aboutsummaryrefslogtreecommitdiffstats
path: root/org.eclipse.jgit.storage.dht
diff options
context:
space:
mode:
authorShawn O. Pearce <spearce@spearce.org>2011-05-26 17:19:30 -0700
committerShawn O. Pearce <spearce@spearce.org>2011-05-31 08:58:45 -0700
commit042a66fe8c2feef7b831b1999b8cd6e9a0181944 (patch)
tree51296b4940709e31d5abef74c1c5037fc02dffbb /org.eclipse.jgit.storage.dht
parent0a39fb2ab65dfdbfbf8022cfdfc3975eba7ac6f2 (diff)
downloadjgit-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.java25
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;
}