Merge pull request #147 from mikeprimm/master

Fix problem with common buffer in re-entrant FileHandler
This commit is contained in:
mikeprimm 2011-05-16 20:05:49 -07:00
commit 57f4f0030e

View File

@ -12,10 +12,16 @@ import org.dynmap.web.HttpHandler;
import org.dynmap.web.HttpRequest; import org.dynmap.web.HttpRequest;
import org.dynmap.web.HttpResponse; import org.dynmap.web.HttpResponse;
import org.dynmap.web.HttpStatus; import org.dynmap.web.HttpStatus;
import java.util.LinkedList;
public abstract class FileHandler implements HttpHandler { public abstract class FileHandler implements HttpHandler {
protected static final Logger log = Logger.getLogger("Minecraft"); protected static final Logger log = Logger.getLogger("Minecraft");
private byte[] readBuffer = new byte[40960]; //BUG-this breaks re-entrancy of this handler, which is called from multiple threads (one per request)
//private byte[] readBuffer = new byte[40960];
//Replace with pool of buffers
private LinkedList<byte[]> bufferpool = new LinkedList<byte[]>();
private Object lock = new Object();
private static final int MAX_FREE_IN_POOL = 2;
private static Map<String, String> mimes = new HashMap<String, String>(); private static Map<String, String> mimes = new HashMap<String, String>();
static { static {
@ -59,6 +65,24 @@ public abstract class FileHandler implements HttpHandler {
return path + "index.html"; return path + "index.html";
} }
private byte[] allocateReadBuffer() {
byte[] buf;
synchronized(lock) {
buf = bufferpool.poll();
}
if(buf == null) {
buf = new byte[40960];
}
return buf;
}
private void freeReadBuffer(byte[] buf) {
synchronized(lock) {
if(bufferpool.size() < MAX_FREE_IN_POOL)
bufferpool.push(buf);
}
}
@Override @Override
public void handle(String path, HttpRequest request, HttpResponse response) throws Exception { public void handle(String path, HttpRequest request, HttpResponse response) throws Exception {
InputStream fileInput = null; InputStream fileInput = null;
@ -76,6 +100,7 @@ public abstract class FileHandler implements HttpHandler {
response.fields.put(HttpField.ContentType, mimeType); response.fields.put(HttpField.ContentType, mimeType);
response.status = HttpStatus.OK; response.status = HttpStatus.OK;
OutputStream out = response.getBody(); OutputStream out = response.getBody();
byte[] readBuffer = allocateReadBuffer();
try { try {
int readBytes; int readBytes;
while ((readBytes = fileInput.read(readBuffer)) > 0) { while ((readBytes = fileInput.read(readBuffer)) > 0) {
@ -84,6 +109,8 @@ public abstract class FileHandler implements HttpHandler {
} catch (IOException e) { } catch (IOException e) {
fileInput.close(); fileInput.close();
throw e; throw e;
} finally {
freeReadBuffer(readBuffer);
} }
fileInput.close(); fileInput.close();
} catch (Exception e) { } catch (Exception e) {