diff --git a/components/net/sf/briar/db/Database.java b/components/net/sf/briar/db/Database.java index 977df1292..b6a980b67 100644 --- a/components/net/sf/briar/db/Database.java +++ b/components/net/sf/briar/db/Database.java @@ -32,6 +32,7 @@ import net.sf.briar.api.transport.ConnectionWindow; *
+ * Locking: message read, messageFlag read. + */ + boolean getRead(T txn, MessageId m) throws DbException; + /** * Returns all remote properties for the given transport. *
@@ -346,6 +354,13 @@ interface Database
+ * Locking: message read, messageFlag read.
+ */
+ boolean getStarred(T txn, MessageId m) throws DbException;
+
/**
* Returns the groups to which the user subscribes.
*
@@ -433,8 +448,8 @@ interface Database
- * Locking: contact write, message write, messageStatus write,
- * subscription write, transport write.
+ * Locking: contact write, message write, messageFlag write,
+ * messageStatus write, subscription write, transport write.
*/
void removeContact(T txn, ContactId c) throws DbException;
@@ -450,7 +465,8 @@ interface Database
- * Locking: contact read, message write, messageStatus write.
+ * Locking: contact read, message write, messageFlag write,
+ * messageStatus write.
*/
void removeMessage(T txn, MessageId m) throws DbException;
@@ -458,8 +474,8 @@ interface Database
- * Locking: contact read, message write, messageStatus write,
- * subscription write.
+ * Locking: contact read, message write, messageFlag write,
+ * messageStatus write, subscription write.
*/
void removeSubscription(T txn, GroupId g) throws DbException;
@@ -497,6 +513,14 @@ interface Database
+ * Locking: message read, messageFlag write.
+ */
+ boolean setRead(T txn, MessageId m, boolean read) throws DbException;
+
/**
* Sets the sendability score of the given message.
*
@@ -504,6 +528,14 @@ interface Database
+ * Locking: message read, messageFlag write.
+ */
+ boolean setStarred(T txn, MessageId m, boolean starred) throws DbException;
+
/**
* Sets the status of the given message with respect to the given contact.
*
diff --git a/components/net/sf/briar/db/DatabaseComponentImpl.java b/components/net/sf/briar/db/DatabaseComponentImpl.java
index 90523a273..36c88cce8 100644
--- a/components/net/sf/briar/db/DatabaseComponentImpl.java
+++ b/components/net/sf/briar/db/DatabaseComponentImpl.java
@@ -81,6 +81,8 @@ DatabaseCleaner.Callback {
new ReentrantReadWriteLock(true);
private final ReentrantReadWriteLock messageLock =
new ReentrantReadWriteLock(true);
+ private final ReentrantReadWriteLock messageFlagLock =
+ new ReentrantReadWriteLock(true);
private final ReentrantReadWriteLock messageStatusLock =
new ReentrantReadWriteLock(true);
private final ReentrantReadWriteLock ratingLock =
@@ -1137,28 +1139,33 @@ DatabaseCleaner.Callback {
try {
messageLock.writeLock().lock();
try {
- messageStatusLock.writeLock().lock();
+ messageFlagLock.writeLock().lock();
try {
- subscriptionLock.writeLock().lock();
+ messageStatusLock.writeLock().lock();
try {
- transportLock.writeLock().lock();
+ subscriptionLock.writeLock().lock();
try {
- T txn = db.startTransaction();
+ transportLock.writeLock().lock();
try {
- db.removeContact(txn, c);
- db.commitTransaction(txn);
- } catch(DbException e) {
- db.abortTransaction(txn);
- throw e;
+ T txn = db.startTransaction();
+ try {
+ db.removeContact(txn, c);
+ db.commitTransaction(txn);
+ } catch(DbException e) {
+ db.abortTransaction(txn);
+ throw e;
+ }
+ } finally {
+ transportLock.writeLock().unlock();
}
} finally {
- transportLock.writeLock().unlock();
+ subscriptionLock.writeLock().unlock();
}
} finally {
- subscriptionLock.writeLock().unlock();
+ messageStatusLock.writeLock().unlock();
}
} finally {
- messageStatusLock.writeLock().unlock();
+ messageFlagLock.writeLock().unlock();
}
} finally {
messageLock.writeLock().unlock();
@@ -1399,26 +1406,31 @@ DatabaseCleaner.Callback {
try {
messageLock.writeLock().lock();
try {
- messageStatusLock.writeLock().lock();
+ messageFlagLock.writeLock().lock();
try {
- subscriptionLock.writeLock().lock();
+ messageStatusLock.writeLock().lock();
try {
- T txn = db.startTransaction();
+ subscriptionLock.writeLock().lock();
try {
- if(db.containsSubscription(txn, g)) {
- affected = db.getVisibility(txn, g);
- db.removeSubscription(txn, g);
+ T txn = db.startTransaction();
+ try {
+ if(db.containsSubscription(txn, g)) {
+ affected = db.getVisibility(txn, g);
+ db.removeSubscription(txn, g);
+ }
+ db.commitTransaction(txn);
+ } catch(DbException e) {
+ db.abortTransaction(txn);
+ throw e;
}
- db.commitTransaction(txn);
- } catch(DbException e) {
- db.abortTransaction(txn);
- throw e;
+ } finally {
+ subscriptionLock.writeLock().unlock();
}
} finally {
- subscriptionLock.writeLock().unlock();
+ messageStatusLock.writeLock().unlock();
}
} finally {
- messageStatusLock.writeLock().unlock();
+ messageFlagLock.writeLock().unlock();
}
} finally {
messageLock.writeLock().unlock();
@@ -1457,19 +1469,24 @@ DatabaseCleaner.Callback {
try {
messageLock.writeLock().lock();
try {
- messageStatusLock.writeLock().lock();
+ messageFlagLock.writeLock().lock();
try {
- T txn = db.startTransaction();
+ messageStatusLock.writeLock().lock();
try {
- old = db.getOldMessages(txn, size);
- for(MessageId m : old) removeMessage(txn, m);
- db.commitTransaction(txn);
- } catch(DbException e) {
- db.abortTransaction(txn);
- throw e;
+ T txn = db.startTransaction();
+ try {
+ old = db.getOldMessages(txn, size);
+ for(MessageId m : old) removeMessage(txn, m);
+ db.commitTransaction(txn);
+ } catch(DbException e) {
+ db.abortTransaction(txn);
+ throw e;
+ }
+ } finally {
+ messageStatusLock.writeLock().unlock();
}
} finally {
- messageStatusLock.writeLock().unlock();
+ messageFlagLock.writeLock().unlock();
}
} finally {
messageLock.writeLock().unlock();
diff --git a/components/net/sf/briar/db/JdbcDatabase.java b/components/net/sf/briar/db/JdbcDatabase.java
index 16799e6bc..f167aa121 100644
--- a/components/net/sf/briar/db/JdbcDatabase.java
+++ b/components/net/sf/briar/db/JdbcDatabase.java
@@ -225,6 +225,15 @@ abstract class JdbcDatabase implements Database