mirror of
https://code.briarproject.org/briar/briar.git
synced 2026-02-15 20:29:52 +01:00
Merge branch 'AbrahamKiggundu/briar-master': better lock encapsulation
This commit is contained in:
@@ -27,6 +27,9 @@ import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.concurrent.locks.Condition;
|
||||
import java.util.concurrent.locks.Lock;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import org.briarproject.api.Author;
|
||||
@@ -313,16 +316,19 @@ abstract class JdbcDatabase implements Database<Connection> {
|
||||
private final Clock clock;
|
||||
|
||||
private final LinkedList<Connection> connections =
|
||||
new LinkedList<Connection>(); // Locking: self
|
||||
new LinkedList<Connection>(); // Locking: connectionsLock
|
||||
|
||||
private final AtomicInteger transactionCount = new AtomicInteger(0);
|
||||
|
||||
private int openConnections = 0; // Locking: connections
|
||||
private boolean closed = false; // Locking: connections
|
||||
private int openConnections = 0; // Locking: connectionsLock
|
||||
private boolean closed = false; // Locking: connectionsLock
|
||||
|
||||
protected abstract Connection createConnection() throws SQLException;
|
||||
protected abstract void flushBuffersToDisk(Statement s) throws SQLException;
|
||||
|
||||
private final Lock connectionsLock = new ReentrantLock();
|
||||
private final Condition connectionsChanged = connectionsLock.newCondition();
|
||||
|
||||
JdbcDatabase(String hashType, String binaryType, String counterType,
|
||||
String secretType, Clock clock) {
|
||||
this.hashType = hashType;
|
||||
@@ -431,9 +437,12 @@ abstract class JdbcDatabase implements Database<Connection> {
|
||||
|
||||
public Connection startTransaction() throws DbException {
|
||||
Connection txn = null;
|
||||
synchronized(connections) {
|
||||
connectionsLock.lock();
|
||||
try {
|
||||
if(closed) throw new DbClosedException();
|
||||
txn = connections.poll();
|
||||
} finally {
|
||||
connectionsLock.unlock();
|
||||
}
|
||||
try {
|
||||
if(txn == null) {
|
||||
@@ -441,8 +450,11 @@ abstract class JdbcDatabase implements Database<Connection> {
|
||||
txn = createConnection();
|
||||
if(txn == null) throw new DbException();
|
||||
txn.setAutoCommit(false);
|
||||
synchronized(connections) {
|
||||
connectionsLock.lock();
|
||||
try {
|
||||
openConnections++;
|
||||
} finally {
|
||||
connectionsLock.unlock();
|
||||
}
|
||||
}
|
||||
} catch(SQLException e) {
|
||||
@@ -455,9 +467,12 @@ abstract class JdbcDatabase implements Database<Connection> {
|
||||
public void abortTransaction(Connection txn) {
|
||||
try {
|
||||
txn.rollback();
|
||||
synchronized(connections) {
|
||||
connectionsLock.lock();
|
||||
try {
|
||||
connections.add(txn);
|
||||
connections.notifyAll();
|
||||
connectionsChanged.signalAll();
|
||||
} finally {
|
||||
connectionsLock.unlock();
|
||||
}
|
||||
} catch(SQLException e) {
|
||||
// Try to close the connection
|
||||
@@ -468,9 +483,12 @@ abstract class JdbcDatabase implements Database<Connection> {
|
||||
if(LOG.isLoggable(WARNING)) LOG.log(WARNING, e1.toString(), e1);
|
||||
}
|
||||
// Whatever happens, allow the database to close
|
||||
synchronized(connections) {
|
||||
connectionsLock.lock();
|
||||
try {
|
||||
openConnections--;
|
||||
connections.notifyAll();
|
||||
connectionsChanged.signalAll();
|
||||
} finally {
|
||||
connectionsLock.unlock();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -486,9 +504,12 @@ abstract class JdbcDatabase implements Database<Connection> {
|
||||
tryToClose(s);
|
||||
throw new DbException(e);
|
||||
}
|
||||
synchronized(connections) {
|
||||
connectionsLock.lock();
|
||||
try {
|
||||
connections.add(txn);
|
||||
connections.notifyAll();
|
||||
connectionsChanged.signalAll();
|
||||
} finally {
|
||||
connectionsLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -502,14 +523,15 @@ abstract class JdbcDatabase implements Database<Connection> {
|
||||
|
||||
protected void closeAllConnections() throws SQLException {
|
||||
boolean interrupted = false;
|
||||
synchronized(connections) {
|
||||
connectionsLock.lock();
|
||||
try {
|
||||
closed = true;
|
||||
for(Connection c : connections) c.close();
|
||||
openConnections -= connections.size();
|
||||
connections.clear();
|
||||
while(openConnections > 0) {
|
||||
try {
|
||||
connections.wait();
|
||||
connectionsChanged.await();
|
||||
} catch(InterruptedException e) {
|
||||
LOG.warning("Interrupted while closing connections");
|
||||
interrupted = true;
|
||||
@@ -518,7 +540,10 @@ abstract class JdbcDatabase implements Database<Connection> {
|
||||
openConnections -= connections.size();
|
||||
connections.clear();
|
||||
}
|
||||
} finally {
|
||||
connectionsLock.unlock();
|
||||
}
|
||||
|
||||
if(interrupted) Thread.currentThread().interrupt();
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user