Merge pull request #249 from mikeprimm/master

Tighten up logic for assuring unlock of locked files during exceptions, fix version number display
This commit is contained in:
mikeprimm 2011-06-28 20:39:00 -07:00
commit aa796deeff
9 changed files with 182 additions and 158 deletions

View File

@ -301,8 +301,9 @@ public class DynmapWorld {
im = ImageIO.read(f); im = ImageIO.read(f);
} catch (IOException e) { } catch (IOException e) {
} catch (IndexOutOfBoundsException e) { } catch (IndexOutOfBoundsException e) {
} finally {
FileLockManager.releaseReadLock(f);
} }
FileLockManager.releaseReadLock(f);
if(im != null) { if(im != null) {
im.getRGB(0, 0, width, height, argb, 0, width); /* Read data */ im.getRGB(0, 0, width, height, argb, 0, width); /* Read data */
im.flush(); im.flush();
@ -333,27 +334,30 @@ public class DynmapWorld {
} }
} }
FileLockManager.getWriteLock(zf); FileLockManager.getWriteLock(zf);
TileHashManager hashman = MapManager.mapman.hashman; try {
long crc = hashman.calculateTileHash(kzIm.argb_buf); /* Get hash of tile */ TileHashManager hashman = MapManager.mapman.hashman;
int tilex = ztx/step/2; long crc = hashman.calculateTileHash(kzIm.argb_buf); /* Get hash of tile */
int tiley = ty/step/2; int tilex = ztx/step/2;
String key = world.getName()+".z"+pd.zoomprefix+pd.baseprefix; int tiley = ty/step/2;
if((!zf.exists()) || (crc != MapManager.mapman.hashman.getImageHashCode(key, null, tilex, tiley))) { String key = world.getName()+".z"+pd.zoomprefix+pd.baseprefix;
try { if((!zf.exists()) || (crc != MapManager.mapman.hashman.getImageHashCode(key, null, tilex, tiley))) {
if(!zf.getParentFile().exists()) try {
zf.getParentFile().mkdirs(); if(!zf.getParentFile().exists())
FileLockManager.imageIOWrite(zIm, "png", zf); zf.getParentFile().mkdirs();
Debug.debug("Saved zoom-out tile at " + zf.getPath()); FileLockManager.imageIOWrite(zIm, "png", zf);
} catch (IOException e) { Debug.debug("Saved zoom-out tile at " + zf.getPath());
Debug.error("Failed to save zoom-out tile: " + zf.getName(), e); } catch (IOException e) {
} catch (java.lang.NullPointerException e) { Debug.error("Failed to save zoom-out tile: " + zf.getName(), e);
Debug.error("Failed to save zoom-out tile (NullPointerException): " + zf.getName(), e); } catch (java.lang.NullPointerException e) {
Debug.error("Failed to save zoom-out tile (NullPointerException): " + zf.getName(), e);
}
hashman.updateHashCode(key, null, tilex, tiley, crc);
MapManager.mapman.pushUpdate(this.world, new Client.Tile(zfname));
enqueueZoomOutUpdate(zf, pd.zoomlevel+1);
} }
hashman.updateHashCode(key, null, tilex, tiley, crc); } finally {
MapManager.mapman.pushUpdate(this.world, new Client.Tile(zfname)); FileLockManager.releaseWriteLock(zf);
enqueueZoomOutUpdate(zf, pd.zoomlevel+1); KzedMap.freeBufferedImage(kzIm);
} }
FileLockManager.releaseWriteLock(zf);
KzedMap.freeBufferedImage(kzIm);
} }
} }

View File

@ -137,7 +137,7 @@ public class MapManager {
MapTile tile = null; MapTile tile = null;
int rendercnt = 0; int rendercnt = 0;
CommandSender sender; CommandSender sender;
long starttime; long timeaccum;
/* Full world, all maps render */ /* Full world, all maps render */
FullWorldRenderState(DynmapWorld dworld, Location l, CommandSender sender) { FullWorldRenderState(DynmapWorld dworld, Location l, CommandSender sender) {
@ -173,7 +173,7 @@ public class MapManager {
/* If render queue is empty, start next map */ /* If render queue is empty, start next map */
if(renderQueue.isEmpty()) { if(renderQueue.isEmpty()) {
if(map_index >= 0) { /* Finished a map? */ if(map_index >= 0) { /* Finished a map? */
double msecpertile = (double)(tstart - starttime) / (double)((rendercnt>0)?rendercnt:1); double msecpertile = (double)timeaccum / (double)((rendercnt>0)?rendercnt:1);
sender.sendMessage("Full render of map '" + world.maps.get(map_index).getClass().getSimpleName() + "' of world '" + sender.sendMessage("Full render of map '" + world.maps.get(map_index).getClass().getSimpleName() + "' of world '" +
world.world.getName() + "' completed - " + rendercnt + " tiles rendered (" + String.format("%.2f", msecpertile) + " msec/tile)."); world.world.getName() + "' completed - " + rendercnt + " tiles rendered (" + String.format("%.2f", msecpertile) + " msec/tile).");
} }
@ -187,7 +187,6 @@ public class MapManager {
return; return;
} }
map = world.maps.get(map_index); map = world.maps.get(map_index);
starttime = System.currentTimeMillis();
/* Now, prime the render queue */ /* Now, prime the render queue */
for (MapTile mt : map.getTiles(loc)) { for (MapTile mt : map.getTiles(loc)) {
@ -241,8 +240,9 @@ public class MapManager {
found.remove(tile); found.remove(tile);
if(!cache.isEmpty()) { if(!cache.isEmpty()) {
rendercnt++; rendercnt++;
timeaccum += System.currentTimeMillis() - tstart;
if((rendercnt % 100) == 0) { if((rendercnt % 100) == 0) {
double msecpertile = (double)(System.currentTimeMillis() - starttime) / (double)rendercnt; double msecpertile = (double)timeaccum / (double)rendercnt;
sender.sendMessage("Full render of map '" + world.maps.get(map_index).getClass().getSimpleName() + "' on world '" + sender.sendMessage("Full render of map '" + world.maps.get(map_index).getClass().getSimpleName() + "' on world '" +
w.getName() + "' in progress - " + rendercnt + " tiles rendered (" + String.format("%.2f", msecpertile) + " msec/tile)."); w.getName() + "' in progress - " + rendercnt + " tiles rendered (" + String.format("%.2f", msecpertile) + " msec/tile).");
} }

View File

@ -271,61 +271,67 @@ public class FlatMap extends MapType {
} }
} }
/* Test to see if we're unchanged from older tile */ /* Test to see if we're unchanged from older tile */
FileLockManager.getWriteLock(outputFile);
TileHashManager hashman = MapManager.mapman.hashman; TileHashManager hashman = MapManager.mapman.hashman;
long crc = hashman.calculateTileHash(argb_buf); long crc = hashman.calculateTileHash(argb_buf);
boolean tile_update = false; boolean tile_update = false;
if((!outputFile.exists()) || (crc != hashman.getImageHashCode(tile.getKey(), null, t.x, t.y))) { FileLockManager.getWriteLock(outputFile);
/* Wrap buffer as buffered image */ try {
Debug.debug("saving image " + outputFile.getPath()); if((!outputFile.exists()) || (crc != hashman.getImageHashCode(tile.getKey(), null, t.x, t.y))) {
if(!outputFile.getParentFile().exists()) /* Wrap buffer as buffered image */
outputFile.getParentFile().mkdirs(); Debug.debug("saving image " + outputFile.getPath());
try { if(!outputFile.getParentFile().exists())
FileLockManager.imageIOWrite(im.buf_img, "png", outputFile); outputFile.getParentFile().mkdirs();
} catch (IOException e) { try {
Debug.error("Failed to save image: " + outputFile.getPath(), e); FileLockManager.imageIOWrite(im.buf_img, "png", outputFile);
} catch (java.lang.NullPointerException e) { } catch (IOException e) {
Debug.error("Failed to save image (NullPointerException): " + outputFile.getPath(), e); Debug.error("Failed to save image: " + outputFile.getPath(), e);
} catch (java.lang.NullPointerException e) {
Debug.error("Failed to save image (NullPointerException): " + outputFile.getPath(), e);
}
MapManager.mapman.pushUpdate(tile.getWorld(), new Client.Tile(tile.getFilename()));
hashman.updateHashCode(tile.getKey(), null, t.x, t.y, crc);
tile.getDynmapWorld().enqueueZoomOutUpdate(outputFile);
tile_update = true;
} }
MapManager.mapman.pushUpdate(tile.getWorld(), new Client.Tile(tile.getFilename())); else {
hashman.updateHashCode(tile.getKey(), null, t.x, t.y, crc); Debug.debug("skipping image " + outputFile.getPath() + " - hash match");
tile.getDynmapWorld().enqueueZoomOutUpdate(outputFile); }
tile_update = true; } finally {
FileLockManager.releaseWriteLock(outputFile);
KzedMap.freeBufferedImage(im);
} }
else {
Debug.debug("skipping image " + outputFile.getPath() + " - hash match");
}
KzedMap.freeBufferedImage(im);
FileLockManager.releaseWriteLock(outputFile);
MapManager.mapman.updateStatistics(tile, null, true, tile_update, !rendered); MapManager.mapman.updateStatistics(tile, null, true, tile_update, !rendered);
/* If day too, handle it */ /* If day too, handle it */
if(night_and_day) { if(night_and_day) {
File dayfile = new File(tile.getDynmapWorld().worldtilepath, tile.getDayFilename()); File dayfile = new File(tile.getDynmapWorld().worldtilepath, tile.getDayFilename());
FileLockManager.getWriteLock(dayfile);
crc = hashman.calculateTileHash(argb_buf_day); crc = hashman.calculateTileHash(argb_buf_day);
if((!dayfile.exists()) || (crc != hashman.getImageHashCode(tile.getKey(), "day", t.x, t.y))) { FileLockManager.getWriteLock(dayfile);
Debug.debug("saving image " + dayfile.getPath()); try {
if(!dayfile.getParentFile().exists()) if((!dayfile.exists()) || (crc != hashman.getImageHashCode(tile.getKey(), "day", t.x, t.y))) {
dayfile.getParentFile().mkdirs(); Debug.debug("saving image " + dayfile.getPath());
try { if(!dayfile.getParentFile().exists())
FileLockManager.imageIOWrite(im_day.buf_img, "png", dayfile); dayfile.getParentFile().mkdirs();
} catch (IOException e) { try {
Debug.error("Failed to save image: " + dayfile.getPath(), e); FileLockManager.imageIOWrite(im_day.buf_img, "png", dayfile);
} catch (java.lang.NullPointerException e) { } catch (IOException e) {
Debug.error("Failed to save image (NullPointerException): " + dayfile.getPath(), e); Debug.error("Failed to save image: " + dayfile.getPath(), e);
} catch (java.lang.NullPointerException e) {
Debug.error("Failed to save image (NullPointerException): " + dayfile.getPath(), e);
}
MapManager.mapman.pushUpdate(tile.getWorld(), new Client.Tile(tile.getDayFilename()));
hashman.updateHashCode(tile.getKey(), "day", t.x, t.y, crc);
tile.getDynmapWorld().enqueueZoomOutUpdate(dayfile);
tile_update = true;
} }
MapManager.mapman.pushUpdate(tile.getWorld(), new Client.Tile(tile.getDayFilename())); else {
hashman.updateHashCode(tile.getKey(), "day", t.x, t.y, crc); Debug.debug("skipping image " + dayfile.getPath() + " - hash match");
tile.getDynmapWorld().enqueueZoomOutUpdate(dayfile); tile_update = false;
tile_update = true; }
} finally {
FileLockManager.releaseWriteLock(dayfile);
KzedMap.freeBufferedImage(im_day);
} }
else {
Debug.debug("skipping image " + dayfile.getPath() + " - hash match");
tile_update = false;
}
KzedMap.freeBufferedImage(im_day);
FileLockManager.releaseWriteLock(dayfile);
MapManager.mapman.updateStatistics(tile, "day", true, tile_update, !rendered); MapManager.mapman.updateStatistics(tile, "day", true, tile_update, !rendered);
} }

View File

@ -256,29 +256,32 @@ public class DefaultTileRenderer implements MapTileRenderer {
int oy = (mtile.py == zmtile.getTileY())?0:KzedMap.tileHeight/2; int oy = (mtile.py == zmtile.getTileY())?0:KzedMap.tileHeight/2;
/* Test to see if we're unchanged from older tile */ /* Test to see if we're unchanged from older tile */
FileLockManager.getWriteLock(fname);
TileHashManager hashman = MapManager.mapman.hashman; TileHashManager hashman = MapManager.mapman.hashman;
long crc = hashman.calculateTileHash(img.argb_buf); long crc = hashman.calculateTileHash(img.argb_buf);
boolean updated_fname = false; boolean updated_fname = false;
int tx = mtile.px/KzedMap.tileWidth; int tx = mtile.px/KzedMap.tileWidth;
int ty = mtile.py/KzedMap.tileHeight; int ty = mtile.py/KzedMap.tileHeight;
if((!fname.exists()) || (crc != hashman.getImageHashCode(mtile.getKey(), null, tx, ty))) { FileLockManager.getWriteLock(fname);
Debug.debug("saving image " + fname.getPath()); try {
if(!fname.getParentFile().exists()) if((!fname.exists()) || (crc != hashman.getImageHashCode(mtile.getKey(), null, tx, ty))) {
fname.getParentFile().mkdirs(); Debug.debug("saving image " + fname.getPath());
try { if(!fname.getParentFile().exists())
FileLockManager.imageIOWrite(img.buf_img, "png", fname); fname.getParentFile().mkdirs();
} catch (IOException e) { try {
Debug.error("Failed to save image: " + fname.getPath(), e); FileLockManager.imageIOWrite(img.buf_img, "png", fname);
} catch (java.lang.NullPointerException e) { } catch (IOException e) {
Debug.error("Failed to save image (NullPointerException): " + fname.getPath(), e); Debug.error("Failed to save image: " + fname.getPath(), e);
} catch (java.lang.NullPointerException e) {
Debug.error("Failed to save image (NullPointerException): " + fname.getPath(), e);
}
MapManager.mapman.pushUpdate(mtile.getWorld(), new Client.Tile(mtile.getFilename()));
hashman.updateHashCode(mtile.getKey(), null, tx, ty, crc);
updated_fname = true;
} }
MapManager.mapman.pushUpdate(mtile.getWorld(), new Client.Tile(mtile.getFilename())); } finally {
hashman.updateHashCode(mtile.getKey(), null, tx, ty, crc); FileLockManager.releaseWriteLock(fname);
updated_fname = true; KzedMap.freeBufferedImage(img);
} }
KzedMap.freeBufferedImage(img);
FileLockManager.releaseWriteLock(fname);
MapManager.mapman.updateStatistics(mtile, null, true, updated_fname, !rendered); MapManager.mapman.updateStatistics(mtile, null, true, updated_fname, !rendered);
mtile.file = fname; mtile.file = fname;
@ -287,25 +290,28 @@ public class DefaultTileRenderer implements MapTileRenderer {
File dfname = new File(mtile.getDynmapWorld().worldtilepath, mtile.getDayFilename()); File dfname = new File(mtile.getDynmapWorld().worldtilepath, mtile.getDayFilename());
if(img_day != null) { if(img_day != null) {
FileLockManager.getWriteLock(dfname);
crc = hashman.calculateTileHash(img.argb_buf); crc = hashman.calculateTileHash(img.argb_buf);
if((!dfname.exists()) || (crc != hashman.getImageHashCode(mtile.getKey(), "day", tx, ty))) { FileLockManager.getWriteLock(dfname);
Debug.debug("saving image " + dfname.getPath()); try {
if(!dfname.getParentFile().exists()) if((!dfname.exists()) || (crc != hashman.getImageHashCode(mtile.getKey(), "day", tx, ty))) {
dfname.getParentFile().mkdirs(); Debug.debug("saving image " + dfname.getPath());
try { if(!dfname.getParentFile().exists())
FileLockManager.imageIOWrite(img_day.buf_img, "png", dfname); dfname.getParentFile().mkdirs();
} catch (IOException e) { try {
Debug.error("Failed to save image: " + dfname.getPath(), e); FileLockManager.imageIOWrite(img_day.buf_img, "png", dfname);
} catch (java.lang.NullPointerException e) { } catch (IOException e) {
Debug.error("Failed to save image (NullPointerException): " + dfname.getPath(), e); Debug.error("Failed to save image: " + dfname.getPath(), e);
} catch (java.lang.NullPointerException e) {
Debug.error("Failed to save image (NullPointerException): " + dfname.getPath(), e);
}
MapManager.mapman.pushUpdate(mtile.getWorld(), new Client.Tile(mtile.getDayFilename()));
hashman.updateHashCode(mtile.getKey(), "day", tx, ty, crc);
updated_dfname = true;
} }
MapManager.mapman.pushUpdate(mtile.getWorld(), new Client.Tile(mtile.getDayFilename())); } finally {
hashman.updateHashCode(mtile.getKey(), "day", tx, ty, crc); FileLockManager.releaseWriteLock(dfname);
updated_dfname = true; KzedMap.freeBufferedImage(img_day);
} }
KzedMap.freeBufferedImage(img_day);
FileLockManager.releaseWriteLock(dfname);
MapManager.mapman.updateStatistics(mtile, "day", true, updated_dfname, !rendered); MapManager.mapman.updateStatistics(mtile, "day", true, updated_dfname, !rendered);
} }
@ -313,30 +319,36 @@ public class DefaultTileRenderer implements MapTileRenderer {
// make the zoomed tile here // make the zoomed tile here
boolean ztile_updated = false; boolean ztile_updated = false;
FileLockManager.getWriteLock(zoomFile); FileLockManager.getWriteLock(zoomFile);
if(updated_fname || (!zoomFile.exists())) { try {
saveZoomedTile(zmtile, zoomFile, zimg, ox, oy, null); if(updated_fname || (!zoomFile.exists())) {
MapManager.mapman.pushUpdate(zmtile.getWorld(), saveZoomedTile(zmtile, zoomFile, zimg, ox, oy, null);
MapManager.mapman.pushUpdate(zmtile.getWorld(),
new Client.Tile(zmtile.getFilename())); new Client.Tile(zmtile.getFilename()));
zmtile.getDynmapWorld().enqueueZoomOutUpdate(zoomFile); zmtile.getDynmapWorld().enqueueZoomOutUpdate(zoomFile);
ztile_updated = true; ztile_updated = true;
}
} finally {
FileLockManager.releaseWriteLock(zoomFile);
KzedMap.freeBufferedImage(zimg);
} }
KzedMap.freeBufferedImage(zimg);
FileLockManager.releaseWriteLock(zoomFile);
MapManager.mapman.updateStatistics(zmtile, null, true, ztile_updated, !rendered); MapManager.mapman.updateStatistics(zmtile, null, true, ztile_updated, !rendered);
if(zimg_day != null) { if(zimg_day != null) {
File zoomFile_day = new File(zmtile.getDynmapWorld().worldtilepath, zmtile.getDayFilename()); File zoomFile_day = new File(zmtile.getDynmapWorld().worldtilepath, zmtile.getDayFilename());
ztile_updated = false; ztile_updated = false;
FileLockManager.getWriteLock(zoomFile_day); FileLockManager.getWriteLock(zoomFile_day);
if(updated_dfname || (!zoomFile_day.exists())) { try {
saveZoomedTile(zmtile, zoomFile_day, zimg_day, ox, oy, "day"); if(updated_dfname || (!zoomFile_day.exists())) {
MapManager.mapman.pushUpdate(zmtile.getWorld(), saveZoomedTile(zmtile, zoomFile_day, zimg_day, ox, oy, "day");
MapManager.mapman.pushUpdate(zmtile.getWorld(),
new Client.Tile(zmtile.getDayFilename())); new Client.Tile(zmtile.getDayFilename()));
zmtile.getDynmapWorld().enqueueZoomOutUpdate(zoomFile_day); zmtile.getDynmapWorld().enqueueZoomOutUpdate(zoomFile_day);
ztile_updated = true; ztile_updated = true;
}
} finally {
FileLockManager.releaseWriteLock(zoomFile_day);
KzedMap.freeBufferedImage(zimg_day);
} }
KzedMap.freeBufferedImage(zimg_day);
FileLockManager.releaseWriteLock(zoomFile_day);
MapManager.mapman.updateStatistics(zmtile, "day", true, ztile_updated, !rendered); MapManager.mapman.updateStatistics(zmtile, "day", true, ztile_updated, !rendered);
} }
} }

View File

@ -18,7 +18,7 @@ public class FileLockManager {
* Get write lock on file - exclusive lock, no other writers or readers * Get write lock on file - exclusive lock, no other writers or readers
* @throws InterruptedException * @throws InterruptedException
*/ */
public static void getWriteLock(File f) { public static boolean getWriteLock(File f) {
String fn = f.getPath(); String fn = f.getPath();
synchronized(lock) { synchronized(lock) {
boolean got_lock = false; boolean got_lock = false;
@ -29,6 +29,7 @@ public class FileLockManager {
lock.wait(); lock.wait();
} catch (InterruptedException ix) { } catch (InterruptedException ix) {
Log.severe("getWriteLock(" + fn + ") interrupted"); Log.severe("getWriteLock(" + fn + ") interrupted");
return false;
} }
} }
else { else {
@ -38,6 +39,7 @@ public class FileLockManager {
} }
} }
//Log.info("getWriteLock(" + f + ")"); //Log.info("getWriteLock(" + f + ")");
return true;
} }
/** /**
* Release write lock * Release write lock
@ -60,10 +62,17 @@ public class FileLockManager {
/** /**
* Get read lock on file - multiple readers allowed, blocks writers * Get read lock on file - multiple readers allowed, blocks writers
*/ */
public static void getReadLock(File f) { public static boolean getReadLock(File f) {
return getReadLock(f, -1);
}
/**
* Get read lock on file - multiple readers allowed, blocks writers - with timeout (msec)
*/
public static boolean getReadLock(File f, long timeout) {
String fn = f.getPath(); String fn = f.getPath();
synchronized(lock) { synchronized(lock) {
boolean got_lock = false; boolean got_lock = false;
boolean first_wait = true;
while(!got_lock) { while(!got_lock) {
Integer lockcnt = filelocks.get(fn); /* Get lock count */ Integer lockcnt = filelocks.get(fn); /* Get lock count */
if(lockcnt == null) { if(lockcnt == null) {
@ -76,14 +85,23 @@ public class FileLockManager {
} }
else { /* Write lock in place */ else { /* Write lock in place */
try { try {
lock.wait(); if((timeout > 0) && (!first_wait)) { /* We already waited */
return false;
}
if(timeout < 0)
lock.wait();
else
lock.wait(timeout);
first_wait = false;
} catch (InterruptedException ix) { } catch (InterruptedException ix) {
Log.severe("getReadLock(" + fn + ") interrupted"); Log.severe("getReadLock(" + fn + ") interrupted");
return false;
} }
} }
} }
} }
//Log.info("getReadLock(" + f + ")"); //Log.info("getReadLock(" + f + ")");
return true;
} }
/** /**
* Release read lock * Release read lock

View File

@ -131,7 +131,6 @@ public class HttpServerConnection extends Thread {
HttpRequest request = new HttpRequest(); HttpRequest request = new HttpRequest();
request.rmtaddr = rmtaddr; request.rmtaddr = rmtaddr;
if (!readRequestHeader(in, request)) { if (!readRequestHeader(in, request)) {
socket.close();
return; return;
} }
@ -174,7 +173,6 @@ public class HttpServerConnection extends Thread {
} }
if (handler == null) { if (handler == null) {
socket.close();
return; return;
} }
@ -186,10 +184,7 @@ public class HttpServerConnection extends Thread {
throw e; throw e;
} catch (Exception e) { } catch (Exception e) {
Log.severe("HttpHandler '" + handler + "' has thown an exception", e); Log.severe("HttpHandler '" + handler + "' has thown an exception", e);
if (socket != null) { out.flush();
out.flush();
socket.close();
}
return; return;
} }
@ -211,37 +206,28 @@ public class HttpServerConnection extends Thread {
if (responseBody == null) { if (responseBody == null) {
Debug.debug("Response was given without Content-Length by '" + handler + "' for path '" + request.path + "'."); Debug.debug("Response was given without Content-Length by '" + handler + "' for path '" + request.path + "'.");
out.flush(); out.flush();
socket.close();
return; return;
} }
} }
out.flush();
if (!isKeepalive) { if (!isKeepalive) {
out.flush();
socket.close();
return; return;
} }
out.flush();
} }
} catch (IOException e) { } catch (IOException e) {
if (socket != null) {
try {
socket.close();
} catch (IOException ex) {
}
}
return;
} catch (Exception e) { } catch (Exception e) {
if (socket != null) {
try {
socket.close();
} catch (IOException ex) {
}
}
Log.severe("Exception while handling request: ", e); Log.severe("Exception while handling request: ", e);
e.printStackTrace(); e.printStackTrace();
return; } finally {
if (socket != null) {
try {
socket.close();
} catch (IOException ex) {
}
}
} }
} }
} }

View File

@ -111,20 +111,13 @@ public abstract class FileHandler implements HttpHandler {
while ((readBytes = fileInput.read(readBuffer)) > 0) { while ((readBytes = fileInput.read(readBuffer)) > 0) {
out.write(readBuffer, 0, readBytes); out.write(readBuffer, 0, readBytes);
} }
} catch (IOException e) {
throw e;
} finally { } finally {
freeReadBuffer(readBuffer); freeReadBuffer(readBuffer);
if(fileInput != null) {
closeFileInput(path, fileInput);
fileInput = null;
}
} }
} catch (Exception e) { } finally {
if (fileInput != null) { if (fileInput != null) {
try { closeFileInput(path, fileInput); fileInput = null; } catch (IOException ex) { } try { closeFileInput(path, fileInput); fileInput = null; } catch (IOException ex) { }
} }
throw e;
} }
} }
} }

View File

@ -23,14 +23,16 @@ public class FilesystemHandler extends FileHandler {
@Override @Override
protected InputStream getFileInput(String path, HttpRequest request, HttpResponse response) { protected InputStream getFileInput(String path, HttpRequest request, HttpResponse response) {
File file = new File(root, path); File file = new File(root, path);
FileLockManager.getReadLock(file); if(!FileLockManager.getReadLock(file, 5000)) { /* Wait up to 5 seconds for lock */
Log.severe("Timeout waiting for lock on file " + file.getPath());
return null;
}
FileInputStream result = null;
try { try {
if (file.getCanonicalPath().startsWith(root.getAbsolutePath()) && file.isFile()) { if (file.getCanonicalPath().startsWith(root.getAbsolutePath()) && file.isFile()) {
FileInputStream result;
try { try {
result = new FileInputStream(file); result = new FileInputStream(file);
} catch (FileNotFoundException e) { } catch (FileNotFoundException e) {
FileLockManager.releaseReadLock(file);
return null; return null;
} }
response.fields.put(HttpField.ContentLength, Long.toString(file.length())); response.fields.put(HttpField.ContentLength, Long.toString(file.length()));
@ -38,14 +40,17 @@ public class FilesystemHandler extends FileHandler {
} }
} catch(IOException ex) { } catch(IOException ex) {
Log.severe("Unable to get canoical path of requested file.", ex); Log.severe("Unable to get canoical path of requested file.", ex);
} finally {
if(result == null) FileLockManager.releaseReadLock(file);
} }
FileLockManager.releaseReadLock(file);
return null; return null;
} }
protected void closeFileInput(String path, InputStream in) throws IOException { protected void closeFileInput(String path, InputStream in) throws IOException {
super.closeFileInput(path, in); try {
File file = new File(root, path); super.closeFileInput(path, in);
FileLockManager.releaseReadLock(file); } finally {
File file = new File(root, path);
FileLockManager.releaseReadLock(file);
}
} }
} }

View File

@ -1,6 +1,6 @@
name: dynmap name: dynmap
main: org.dynmap.DynmapPlugin main: org.dynmap.DynmapPlugin
version: 0.20 version: "0.20"
authors: [FrozenCow, mikeprimm, zeeZ] authors: [FrozenCow, mikeprimm, zeeZ]
softdepend: [Permissions] softdepend: [Permissions]
commands: commands: