mirror of
https://code.briarproject.org/briar/briar.git
synced 2026-02-16 12:49:55 +01:00
Improved encapsulation of thread synchronisation as follows
- replaced use of Object instance mutex with a private final Lock object - replaced Object signaling with specific condition signalling
This commit is contained in:
@@ -4,6 +4,10 @@ import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.Collection;
|
||||
import java.util.concurrent.Executor;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.locks.Condition;
|
||||
import java.util.concurrent.locks.Lock;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
class PollingRemovableDriveMonitor implements RemovableDriveMonitor, Runnable {
|
||||
@@ -14,11 +18,14 @@ class PollingRemovableDriveMonitor implements RemovableDriveMonitor, Runnable {
|
||||
private final Executor ioExecutor;
|
||||
private final RemovableDriveFinder finder;
|
||||
private final long pollingInterval;
|
||||
private final Object pollingLock = new Object();
|
||||
|
||||
private volatile boolean running = false;
|
||||
private volatile Callback callback = null;
|
||||
|
||||
private final Lock synchLock = new ReentrantLock();
|
||||
private final Condition stopPolling = synchLock.newCondition();
|
||||
|
||||
|
||||
public PollingRemovableDriveMonitor(Executor ioExecutor,
|
||||
RemovableDriveFinder finder, long pollingInterval) {
|
||||
this.ioExecutor = ioExecutor;
|
||||
@@ -34,8 +41,12 @@ class PollingRemovableDriveMonitor implements RemovableDriveMonitor, Runnable {
|
||||
|
||||
public void stop() throws IOException {
|
||||
running = false;
|
||||
synchronized(pollingLock) {
|
||||
pollingLock.notifyAll();
|
||||
synchLock.lock();
|
||||
try {
|
||||
stopPolling.signalAll();
|
||||
}
|
||||
finally {
|
||||
synchLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -43,8 +54,12 @@ class PollingRemovableDriveMonitor implements RemovableDriveMonitor, Runnable {
|
||||
try {
|
||||
Collection<File> drives = finder.findRemovableDrives();
|
||||
while(running) {
|
||||
synchronized(pollingLock) {
|
||||
pollingLock.wait(pollingInterval);
|
||||
synchLock.lock();
|
||||
try {
|
||||
stopPolling.await(pollingInterval, TimeUnit.MILLISECONDS);
|
||||
}
|
||||
finally{
|
||||
synchLock.unlock();
|
||||
}
|
||||
if(!running) return;
|
||||
Collection<File> newDrives = finder.findRemovableDrives();
|
||||
|
||||
@@ -4,6 +4,9 @@ import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.locks.Condition;
|
||||
import java.util.concurrent.locks.Lock;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
|
||||
import net.contentobjects.jnotify.JNotify;
|
||||
import net.contentobjects.jnotify.JNotifyListener;
|
||||
@@ -21,7 +24,11 @@ JNotifyListener {
|
||||
private Callback callback = null; // Locking: this
|
||||
|
||||
protected abstract String[] getPathsToWatch();
|
||||
|
||||
|
||||
//TODO: rationalise this in a further refactor
|
||||
private final Lock synchLock = new ReentrantLock();
|
||||
private static final Lock staticSynchLock = new ReentrantLock();
|
||||
|
||||
private static Throwable tryLoad() {
|
||||
try {
|
||||
Class.forName("net.contentobjects.jnotify.JNotify");
|
||||
@@ -33,12 +40,18 @@ JNotifyListener {
|
||||
}
|
||||
}
|
||||
|
||||
public static synchronized void checkEnabled() throws IOException {
|
||||
if(!triedLoad) {
|
||||
loadError = tryLoad();
|
||||
triedLoad = true;
|
||||
public static void checkEnabled() throws IOException {
|
||||
staticSynchLock.lock();
|
||||
try {
|
||||
if(!triedLoad) {
|
||||
loadError = tryLoad();
|
||||
triedLoad = true;
|
||||
}
|
||||
if(loadError != null) throw new IOException(loadError.toString());
|
||||
}
|
||||
finally{
|
||||
staticSynchLock.unlock();
|
||||
}
|
||||
if(loadError != null) throw new IOException(loadError.toString());
|
||||
}
|
||||
|
||||
public void start(Callback callback) throws IOException {
|
||||
@@ -49,34 +62,46 @@ JNotifyListener {
|
||||
if(new File(path).exists())
|
||||
watches.add(JNotify.addWatch(path, mask, false, this));
|
||||
}
|
||||
synchronized(this) {
|
||||
assert !started;
|
||||
assert this.callback == null;
|
||||
started = true;
|
||||
this.callback = callback;
|
||||
this.watches.addAll(watches);
|
||||
}
|
||||
synchLock.lock();
|
||||
try {
|
||||
assert !started;
|
||||
assert this.callback == null;
|
||||
started = true;
|
||||
this.callback = callback;
|
||||
this.watches.addAll(watches);
|
||||
}
|
||||
finally{
|
||||
synchLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
public void stop() throws IOException {
|
||||
checkEnabled();
|
||||
List<Integer> watches;
|
||||
synchronized(this) {
|
||||
assert started;
|
||||
assert callback != null;
|
||||
started = false;
|
||||
callback = null;
|
||||
watches = new ArrayList<Integer>(this.watches);
|
||||
this.watches.clear();
|
||||
}
|
||||
synchLock.lock();
|
||||
try {
|
||||
assert started;
|
||||
assert callback != null;
|
||||
started = false;
|
||||
callback = null;
|
||||
watches = new ArrayList<Integer>(this.watches);
|
||||
this.watches.clear();
|
||||
}
|
||||
finally{
|
||||
synchLock.unlock();
|
||||
}
|
||||
for(Integer w : watches) JNotify.removeWatch(w);
|
||||
}
|
||||
|
||||
public void fileCreated(int wd, String rootPath, String name) {
|
||||
Callback callback;
|
||||
synchronized(this) {
|
||||
callback = this.callback;
|
||||
}
|
||||
synchLock.lock();
|
||||
try {
|
||||
callback = this.callback;
|
||||
}
|
||||
finally{
|
||||
synchLock.unlock();
|
||||
}
|
||||
if(callback != null)
|
||||
callback.driveInserted(new File(rootPath + "/" + name));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user