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:
Abraham Kiggundu
2014-12-23 23:55:56 +03:00
parent 276dcb1038
commit b074978472
19 changed files with 1001 additions and 478 deletions

View File

@@ -10,6 +10,8 @@ import java.util.Map;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import java.util.logging.Logger;
import org.briarproject.api.Author;
@@ -60,6 +62,8 @@ class ConnectorGroup extends Thread implements InvitationTask {
private final Collection<InvitationListener> listeners;
private final AtomicBoolean connected;
private final CountDownLatch localConfirmationLatch;
private final Lock synchLock = new ReentrantLock();
/*
* All of the following require locking: this. We don't want to call the
@@ -104,12 +108,18 @@ class ConnectorGroup extends Thread implements InvitationTask {
localConfirmationLatch = new CountDownLatch(1);
}
public synchronized InvitationState addListener(InvitationListener l) {
listeners.add(l);
return new InvitationState(localInvitationCode, remoteInvitationCode,
localConfirmationCode, remoteConfirmationCode, connected.get(),
connectionFailed, localCompared, remoteCompared, localMatched,
remoteMatched, remoteName);
public InvitationState addListener(InvitationListener l) {
synchLock.lock();
try{
listeners.add(l);
return new InvitationState(localInvitationCode, remoteInvitationCode,
localConfirmationCode, remoteConfirmationCode, connected.get(),
connectionFailed, localCompared, remoteCompared, localMatched,
remoteMatched, remoteName);
}
finally{
synchLock.unlock();
}
}
public void removeListener(InvitationListener l) {
@@ -130,9 +140,13 @@ class ConnectorGroup extends Thread implements InvitationTask {
localProps = db.getLocalProperties();
} catch(DbException e) {
if(LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
synchronized(this) {
synchLock.lock();
try {
connectionFailed = true;
}
finally{
synchLock.unlock();
}
for(InvitationListener l : listeners) l.connectionFailed();
return;
}
@@ -163,9 +177,13 @@ class ConnectorGroup extends Thread implements InvitationTask {
}
// If none of the threads connected, inform the listeners
if(!connected.get()) {
synchronized(this) {
synchLock.lock();
try {
connectionFailed = true;
}
finally{
synchLock.unlock();
}
for(InvitationListener l : listeners) l.connectionFailed();
}
}
@@ -193,18 +211,26 @@ class ConnectorGroup extends Thread implements InvitationTask {
}
public void localConfirmationSucceeded() {
synchronized(this) {
synchLock.lock();
try {
localCompared = true;
localMatched = true;
}
finally{
synchLock.unlock();
}
localConfirmationLatch.countDown();
}
public void localConfirmationFailed() {
synchronized(this) {
synchLock.lock();
try {
localCompared = true;
localMatched = false;
}
finally{
synchLock.unlock();
}
localConfirmationLatch.countDown();
}
@@ -216,10 +242,14 @@ class ConnectorGroup extends Thread implements InvitationTask {
}
void keyAgreementSucceeded(int localCode, int remoteCode) {
synchronized(this) {
synchLock.lock();
try {
localConfirmationCode = localCode;
remoteConfirmationCode = remoteCode;
}
finally{
synchLock.unlock();
}
for(InvitationListener l : listeners)
l.keyAgreementSucceeded(localCode, remoteCode);
}
@@ -230,32 +260,48 @@ class ConnectorGroup extends Thread implements InvitationTask {
boolean waitForLocalConfirmationResult() throws InterruptedException {
localConfirmationLatch.await(CONFIRMATION_TIMEOUT, MILLISECONDS);
synchronized(this) {
synchLock.lock();
try {
return localMatched;
}
finally{
synchLock.unlock();
}
}
void remoteConfirmationSucceeded() {
synchronized(this) {
synchLock.lock();
try {
remoteCompared = true;
remoteMatched = true;
}
finally{
synchLock.unlock();
}
for(InvitationListener l : listeners) l.remoteConfirmationSucceeded();
}
void remoteConfirmationFailed() {
synchronized(this) {
synchLock.lock();
try {
remoteCompared = true;
remoteMatched = false;
}
finally{
synchLock.unlock();
}
for(InvitationListener l : listeners) l.remoteConfirmationFailed();
}
void pseudonymExchangeSucceeded(Author remoteAuthor) {
String name = remoteAuthor.getName();
synchronized(this) {
synchLock.lock();
try {
remoteName = name;
}
finally{
synchLock.unlock();
}
for(InvitationListener l : listeners)
l.pseudonymExchangeSucceeded(name);
}