From 2863dd0acc86655ab52ee28f9687fbdb0144d92e Mon Sep 17 00:00:00 2001 From: Mike Primm Date: Tue, 28 Jun 2011 22:33:11 -0500 Subject: [PATCH] Put timeout on read lock used by web server - make sure it can't be indefinite --- .../java/org/dynmap/utils/FileLockManager.java | 16 +++++++++++++++- .../dynmap/web/handlers/FilesystemHandler.java | 5 ++++- 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/dynmap/utils/FileLockManager.java b/src/main/java/org/dynmap/utils/FileLockManager.java index 8994b32c..71048616 100644 --- a/src/main/java/org/dynmap/utils/FileLockManager.java +++ b/src/main/java/org/dynmap/utils/FileLockManager.java @@ -63,9 +63,16 @@ public class FileLockManager { * Get read lock on file - multiple readers allowed, blocks writers */ 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(); synchronized(lock) { boolean got_lock = false; + boolean first_wait = true; while(!got_lock) { Integer lockcnt = filelocks.get(fn); /* Get lock count */ if(lockcnt == null) { @@ -78,7 +85,14 @@ public class FileLockManager { } else { /* Write lock in place */ 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) { Log.severe("getReadLock(" + fn + ") interrupted"); return false; diff --git a/src/main/java/org/dynmap/web/handlers/FilesystemHandler.java b/src/main/java/org/dynmap/web/handlers/FilesystemHandler.java index 510f0e85..07bc089a 100644 --- a/src/main/java/org/dynmap/web/handlers/FilesystemHandler.java +++ b/src/main/java/org/dynmap/web/handlers/FilesystemHandler.java @@ -23,7 +23,10 @@ public class FilesystemHandler extends FileHandler { @Override protected InputStream getFileInput(String path, HttpRequest request, HttpResponse response) { 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 { if (file.getCanonicalPath().startsWith(root.getAbsolutePath()) && file.isFile()) {