diff options
author | Shawn O. Pearce <spearce@spearce.org> | 2011-05-26 17:19:30 -0700 |
---|---|---|
committer | Shawn O. Pearce <spearce@spearce.org> | 2011-05-31 08:58:45 -0700 |
commit | 042a66fe8c2feef7b831b1999b8cd6e9a0181944 (patch) | |
tree | 51296b4940709e31d5abef74c1c5037fc02dffbb /org.eclipse.jgit.storage.dht | |
parent | 0a39fb2ab65dfdbfbf8022cfdfc3975eba7ac6f2 (diff) | |
download | jgit-042a66fe8c2feef7b831b1999b8cd6e9a0181944.tar.gz jgit-042a66fe8c2feef7b831b1999b8cd6e9a0181944.zip |
DHT: Fix thread-safety issue in AbstractWriteBuffer
There is a data corruption issue with the 'running' list if a
background thread schedules something onto the buffer while the
application thread is also using it.
Change-Id: I5ba78b98b6632965d677a9c8f209f0cf8320cc3d
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
Diffstat (limited to 'org.eclipse.jgit.storage.dht')
-rw-r--r-- | org.eclipse.jgit.storage.dht/src/org/eclipse/jgit/storage/dht/spi/util/AbstractWriteBuffer.java | 25 |
1 files changed, 18 insertions, 7 deletions
diff --git a/org.eclipse.jgit.storage.dht/src/org/eclipse/jgit/storage/dht/spi/util/AbstractWriteBuffer.java b/org.eclipse.jgit.storage.dht/src/org/eclipse/jgit/storage/dht/spi/util/AbstractWriteBuffer.java index d40cbe31ad..ad55206fe7 100644 --- a/org.eclipse.jgit.storage.dht/src/org/eclipse/jgit/storage/dht/spi/util/AbstractWriteBuffer.java +++ b/org.eclipse.jgit.storage.dht/src/org/eclipse/jgit/storage/dht/spi/util/AbstractWriteBuffer.java @@ -82,6 +82,8 @@ public abstract class AbstractWriteBuffer implements WriteBuffer { private final List<Future<?>> running; + private final Object runningLock; + private final Semaphore spaceAvailable; private int queuedCount; @@ -102,6 +104,7 @@ public abstract class AbstractWriteBuffer implements WriteBuffer { this.executor = executor; this.bufferSize = bufferSize; this.running = new LinkedList<Future<?>>(); + this.runningLock = new Object(); this.spaceAvailable = new Semaphore(bufferSize); } @@ -189,14 +192,18 @@ public abstract class AbstractWriteBuffer implements WriteBuffer { } } - checkRunningTasks(true); + synchronized (runningLock) { + checkRunningTasks(true); + } } finally { flushing = false; } } public void abort() throws DhtException { - checkRunningTasks(true); + synchronized (runningLock) { + checkRunningTasks(true); + } } private void acquireSpace(int sz) throws DhtException { @@ -259,9 +266,11 @@ public abstract class AbstractWriteBuffer implements WriteBuffer { return; } - if (!flushing) - checkRunningTasks(false); - running.add(executor.submit(op)); + synchronized (runningLock) { + if (!flushing) + checkRunningTasks(false); + running.add(executor.submit(op)); + } } /** @@ -284,8 +293,10 @@ public abstract class AbstractWriteBuffer implements WriteBuffer { int size) throws DhtException { int permits = permitsForSize(size); WrappedCallback<T> op = new WrappedCallback<T>(callback, permits); - checkRunningTasks(false); - running.add(op); + synchronized (runningLock) { + checkRunningTasks(false); + running.add(op); + } return op; } |