diff --git a/briar-core/src/org/briarproject/db/Database.java b/briar-core/src/org/briarproject/db/Database.java
index 934156308..30c824038 100644
--- a/briar-core/src/org/briarproject/db/Database.java
+++ b/briar-core/src/org/briarproject/db/Database.java
@@ -30,27 +30,23 @@ import java.util.Map;
* obtained by calling {@link #startTransaction()}. Every transaction must be
* terminated by calling either {@link #abortTransaction(T)} or
* {@link #commitTransaction(T)}, even if an exception is thrown.
- *
- * Read-write locking is provided by the DatabaseComponent implementation.
*/
interface Database {
/**
* Opens the database and returns true if the database already existed.
- *
- * Locking: write.
*/
boolean open() throws DbException;
/**
* Prevents new transactions from starting, waits for all current
* transactions to finish, and closes the database.
- *
- * Locking: write.
*/
void close() throws DbException, IOException;
- /** Starts a new transaction and returns an object representing it. */
+ /**
+ * Starts a new transaction and returns an object representing it.
+ */
T startTransaction() throws DbException;
/**
@@ -65,59 +61,39 @@ interface Database {
*/
void commitTransaction(T txn) throws DbException;
- /**
- * Returns the number of transactions started since the transaction count
- * was last reset.
- */
- int getTransactionCount();
-
- /** Resets the transaction count. */
- void resetTransactionCount();
-
/**
* Stores a contact associated with the given local and remote pseudonyms,
* and returns an ID for the contact.
- *
- * Locking: write.
*/
ContactId addContact(T txn, Author remote, AuthorId local)
throws DbException;
/**
* Stores a group.
- *
- * Locking: write.
*/
void addGroup(T txn, Group g) throws DbException;
/**
* Stores a local pseudonym.
- *
- * Locking: write.
*/
void addLocalAuthor(T txn, LocalAuthor a) throws DbException;
/**
* Stores a message.
- *
- * Locking: write.
*/
void addMessage(T txn, Message m, Validity validity, boolean shared)
throws DbException;
/**
* Records that a message has been offered by the given contact.
- *
- * Locking: write.
*/
void addOfferedMessage(T txn, ContactId c, MessageId m) throws DbException;
/**
* Initialises the status of the given message with respect to the given
* contact.
- *
- * Locking: write.
- * @param ack whether the message needs to be acknowledged.
+ *
+ * @param ack whether the message needs to be acknowledged.
* @param seen whether the contact has seen the message.
*/
void addStatus(T txn, ContactId c, MessageId m, boolean ack, boolean seen)
@@ -125,76 +101,56 @@ interface Database {
/**
* Stores a transport.
- *
- * Locking: write.
*/
void addTransport(T txn, TransportId t, int maxLatency)
throws DbException;
/**
* Stores transport keys for a newly added contact.
- *
- * Locking: write.
*/
void addTransportKeys(T txn, ContactId c, TransportKeys k)
throws DbException;
/**
* Makes a group visible to the given contact.
- *
- * Locking: write.
*/
void addVisibility(T txn, ContactId c, GroupId g) throws DbException;
/**
* Returns true if the database contains the given contact for the given
* local pseudonym.
- *
- * Locking: read.
*/
boolean containsContact(T txn, AuthorId remote, AuthorId local)
throws DbException;
/**
* Returns true if the database contains the given contact.
- *
- * Locking: read.
*/
boolean containsContact(T txn, ContactId c) throws DbException;
/**
* Returns true if the database contains the given group.
- *
- * Locking: read.
*/
boolean containsGroup(T txn, GroupId g) throws DbException;
/**
* Returns true if the database contains the given local pseudonym.
- *
- * Locking: read.
*/
boolean containsLocalAuthor(T txn, AuthorId a) throws DbException;
/**
* Returns true if the database contains the given message.
- *
- * Locking: read.
*/
boolean containsMessage(T txn, MessageId m) throws DbException;
/**
* Returns true if the database contains the given transport.
- *
- * Locking: read.
*/
boolean containsTransport(T txn, TransportId t) throws DbException;
/**
* Returns true if the database contains the given group and the group is
* visible to the given contact.
- *
- * Locking: read.
*/
boolean containsVisibleGroup(T txn, ContactId c, GroupId g)
throws DbException;
@@ -202,16 +158,12 @@ interface Database {
/**
* Returns true if the database contains the given message and the message
* is visible to the given contact.
- *
- * Locking: read.
*/
boolean containsVisibleMessage(T txn, ContactId c, MessageId m)
throws DbException;
/**
* Returns the number of messages offered by the given contact.
- *
- * Locking: read.
*/
int countOfferedMessages(T txn, ContactId c) throws DbException;
@@ -234,36 +186,26 @@ interface Database {
/**
* Returns the contact with the given ID.
- *
- * Locking: read.
*/
Contact getContact(T txn, ContactId c) throws DbException;
/**
* Returns the IDs of all contacts.
- *
- * Locking: read.
*/
Collection getContactIds(T txn) throws DbException;
/**
* Returns all contacts.
- *
- * Locking: read.
*/
Collection getContacts(T txn) throws DbException;
/**
* Returns all contacts associated with the given local pseudonym.
- *
- * Locking: read.
*/
Collection getContacts(T txn, AuthorId a) throws DbException;
/**
* Returns the unique ID for this device.
- *
- * Locking: read.
*/
DeviceId getDeviceId(T txn) throws DbException;
@@ -276,59 +218,43 @@ interface Database {
/**
* Returns the group with the given ID.
- *
- * Locking: read.
*/
Group getGroup(T txn, GroupId g) throws DbException;
/**
* Returns the metadata for the given group.
- *
- * Locking: read.
*/
Metadata getGroupMetadata(T txn, GroupId g) throws DbException;
/**
* Returns all groups belonging to the given client.
- *
- * Locking: read.
*/
Collection getGroups(T txn, ClientId c) throws DbException;
/**
* Returns the local pseudonym with the given ID.
- *
- * Locking: read.
*/
LocalAuthor getLocalAuthor(T txn, AuthorId a) throws DbException;
/**
* Returns all local pseudonyms.
- *
- * Locking: read.
*/
Collection getLocalAuthors(T txn) throws DbException;
/**
* Returns the metadata for all messages in the given group.
- *
- * Locking: read.
*/
Map getMessageMetadata(T txn, GroupId g)
throws DbException;
/**
* Returns the metadata for the given message.
- *
- * Locking: read.
*/
Metadata getMessageMetadata(T txn, MessageId m) throws DbException;
/**
* Returns the status of all messages in the given group with respect
* to the given contact.
- *
- * Locking: read
*/
Collection getMessageStatus(T txn, ContactId c, GroupId g)
throws DbException;
@@ -336,8 +262,6 @@ interface Database {
/**
* Returns the status of the given message with respect to the given
* contact.
- *
- * Locking: read
*/
MessageStatus getMessageStatus(T txn, ContactId c, MessageId m)
throws DbException;
@@ -345,8 +269,6 @@ interface Database {
/**
* Returns the IDs of some messages received from the given contact that
* need to be acknowledged, up to the given number of messages.
- *
- * Locking: read.
*/
Collection getMessagesToAck(T txn, ContactId c, int maxMessages)
throws DbException;
@@ -354,8 +276,6 @@ interface Database {
/**
* Returns the IDs of some messages that are eligible to be offered to the
* given contact, up to the given number of messages.
- *
- * Locking: read.
*/
Collection getMessagesToOffer(T txn, ContactId c,
int maxMessages) throws DbException;
@@ -363,8 +283,6 @@ interface Database {
/**
* Returns the IDs of some messages that are eligible to be sent to the
* given contact, up to the given total length.
- *
- * Locking: read.
*/
Collection getMessagesToSend(T txn, ContactId c, int maxLength)
throws DbException;
@@ -372,8 +290,6 @@ interface Database {
/**
* Returns the IDs of some messages that are eligible to be requested from
* the given contact, up to the given number of messages.
- *
- * Locking: read.
*/
Collection getMessagesToRequest(T txn, ContactId c,
int maxMessages) throws DbException;
@@ -381,16 +297,12 @@ interface Database {
/**
* Returns the IDs of any messages that need to be validated by the given
* client.
- *
- * Locking: read.
*/
Collection getMessagesToValidate(T txn, ClientId c)
throws DbException;
/**
* Returns the message with the given ID, in serialised form.
- *
- * Locking: read.
*/
byte[] getRawMessage(T txn, MessageId m) throws DbException;
@@ -398,46 +310,34 @@ interface Database {
* Returns the IDs of some messages that are eligible to be sent to the
* given contact and have been requested by the contact, up to the given
* total length.
- *
- * Locking: read.
*/
Collection getRequestedMessagesToSend(T txn, ContactId c,
int maxLength) throws DbException;
/**
* Returns all settings in the given namespace.
- *
- * Locking: read.
*/
Settings getSettings(T txn, String namespace) throws DbException;
/**
* Returns all transport keys for the given transport.
- *
- * Locking: read.
*/
Map getTransportKeys(T txn, TransportId t)
throws DbException;
/**
* Returns the maximum latencies in milliseconds of all transports.
- *
- * Locking: read.
*/
Map getTransportLatencies(T txn) throws DbException;
/**
* Returns the IDs of all contacts to which the given group is visible.
- *
- * Locking: read.
*/
Collection getVisibility(T txn, GroupId g) throws DbException;
/**
* Increments the outgoing stream counter for the given contact and
* transport in the given rotation period.
- *
- * Locking: write.
*/
void incrementStreamCounter(T txn, ContactId c, TransportId t,
long rotationPeriod) throws DbException;
@@ -445,8 +345,6 @@ interface Database {
/**
* Marks the given messages as not needing to be acknowledged to the
* given contact.
- *
- * Locking: write.
*/
void lowerAckFlag(T txn, ContactId c, Collection acked)
throws DbException;
@@ -454,8 +352,6 @@ interface Database {
/**
* Marks the given messages as not having been requested by the given
* contact.
- *
- * Locking: write.
*/
void lowerRequestedFlag(T txn, ContactId c, Collection requested)
throws DbException;
@@ -463,8 +359,6 @@ interface Database {
/*
* Merges the given metadata with the existing metadata for the given
* group.
- *
- * Locking: write.
*/
void mergeGroupMetadata(T txn, GroupId g, Metadata meta)
throws DbException;
@@ -472,8 +366,6 @@ interface Database {
/*
* Merges the given metadata with the existing metadata for the given
* message.
- *
- * Locking: write.
*/
void mergeMessageMetadata(T txn, MessageId m, Metadata meta)
throws DbException;
@@ -481,65 +373,47 @@ interface Database {
/**
* Merges the given settings with the existing settings in the given
* namespace.
- *
- * Locking: write.
*/
void mergeSettings(T txn, Settings s, String namespace) throws DbException;
/**
* Marks a message as needing to be acknowledged to the given contact.
- *
- * Locking: write.
*/
void raiseAckFlag(T txn, ContactId c, MessageId m) throws DbException;
/**
* Marks a message as having been requested by the given contact.
- *
- * Locking: write.
*/
void raiseRequestedFlag(T txn, ContactId c, MessageId m) throws DbException;
/**
* Marks a message as having been seen by the given contact.
- *
- * Locking: write.
*/
void raiseSeenFlag(T txn, ContactId c, MessageId m) throws DbException;
/**
* Removes a contact from the database.
- *
- * Locking: write.
*/
void removeContact(T txn, ContactId c) throws DbException;
/**
* Removes a group (and all associated state) from the database.
- *
- * Locking: write.
*/
void removeGroup(T txn, GroupId g) throws DbException;
/**
* Removes a local pseudonym (and all associated state) from the database.
- *
- * Locking: write.
*/
void removeLocalAuthor(T txn, AuthorId a) throws DbException;
/**
* Removes a message (and all associated state) from the database.
- *
- * Locking: write.
*/
void removeMessage(T txn, MessageId m) throws DbException;
/**
* Removes an offered message that was offered by the given contact, or
* returns false if there is no such message.
- *
- * Locking: write.
*/
boolean removeOfferedMessage(T txn, ContactId c, MessageId m)
throws DbException;
@@ -547,70 +421,52 @@ interface Database {
/**
* Removes the given offered messages that were offered by the given
* contact.
- *
- * Locking: write.
*/
void removeOfferedMessages(T txn, ContactId c,
Collection requested) throws DbException;
/**
* Removes a transport (and all associated state) from the database.
- *
- * Locking: write.
*/
void removeTransport(T txn, TransportId t) throws DbException;
/**
* Makes a group invisible to the given contact.
- *
- * Locking: write.
*/
void removeVisibility(T txn, ContactId c, GroupId g) throws DbException;
/**
* Resets the transmission count and expiry time of the given message with
* respect to the given contact.
- *
- * Locking: write.
*/
void resetExpiryTime(T txn, ContactId c, MessageId m) throws DbException;
/**
* Sets the status of the given contact.
- *
- * Locking: write.
*/
void setContactStatus(T txn, ContactId c, StorageStatus s)
throws DbException;
/**
* Sets the status of the given local pseudonym.
- *
- * Locking: write.
*/
void setLocalAuthorStatus(T txn, AuthorId a, StorageStatus s)
throws DbException;
/**
* Marks the given message as shared or unshared.
- *
- * Locking: write.
*/
void setMessageShared(T txn, MessageId m, boolean shared)
throws DbException;
/**
* Marks the given message as valid or invalid.
- *
- * Locking: write.
*/
void setMessageValid(T txn, MessageId m, boolean valid) throws DbException;
/**
* Sets the reordering window for the given contact and transport in the
* given rotation period.
- *
- * Locking: write.
*/
void setReorderingWindow(T txn, ContactId c, TransportId t,
long rotationPeriod, long base, byte[] bitmap) throws DbException;
@@ -619,16 +475,12 @@ interface Database {
* Updates the transmission count and expiry time of the given message
* with respect to the given contact, using the latency of the transport
* over which it was sent.
- *
- * Locking: write.
*/
void updateExpiryTime(T txn, ContactId c, MessageId m, int maxLatency)
throws DbException;
/**
* Stores the given transport keys, deleting any keys they have replaced.
- *
- * Locking: write.
*/
void updateTransportKeys(T txn, Map keys)
throws DbException;
diff --git a/briar-core/src/org/briarproject/db/DatabaseComponentImpl.java b/briar-core/src/org/briarproject/db/DatabaseComponentImpl.java
index 0a974ed8e..dcf88660a 100644
--- a/briar-core/src/org/briarproject/db/DatabaseComponentImpl.java
+++ b/briar-core/src/org/briarproject/db/DatabaseComponentImpl.java
@@ -55,7 +55,7 @@ import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
-import java.util.concurrent.locks.ReentrantReadWriteLock;
+import java.util.concurrent.atomic.AtomicBoolean;
import java.util.logging.Logger;
import javax.inject.Inject;
@@ -79,12 +79,9 @@ class DatabaseComponentImpl implements DatabaseComponent {
private final Database db;
private final EventBus eventBus;
private final ShutdownManager shutdown;
+ private final AtomicBoolean closed = new AtomicBoolean(false);
- private final ReentrantReadWriteLock lock =
- new ReentrantReadWriteLock(true);
-
- private boolean open = false; // Locking: lock.writeLock
- private int shutdownHandle = -1; // Locking: lock.writeLock
+ private volatile int shutdownHandle = -1;
@Inject
DatabaseComponentImpl(Database db, EventBus eventBus,
@@ -97,9 +94,7 @@ class DatabaseComponentImpl implements DatabaseComponent {
public boolean open() throws DbException {
Runnable shutdownHook = new Runnable() {
public void run() {
- lock.writeLock().lock();
try {
- shutdownHandle = -1;
close();
} catch (DbException e) {
if (LOG.isLoggable(WARNING))
@@ -107,118 +102,81 @@ class DatabaseComponentImpl implements DatabaseComponent {
} catch (IOException e) {
if (LOG.isLoggable(WARNING))
LOG.log(WARNING, e.toString(), e);
- } finally {
- lock.writeLock().unlock();
}
}
};
- lock.writeLock().lock();
- try {
- if (open) throw new IllegalStateException();
- open = true;
- boolean reopened = db.open();
- shutdownHandle = shutdown.addShutdownHook(shutdownHook);
- return reopened;
- } finally {
- lock.writeLock().unlock();
- }
+ boolean reopened = db.open();
+ shutdownHandle = shutdown.addShutdownHook(shutdownHook);
+ return reopened;
}
public void close() throws DbException, IOException {
- lock.writeLock().lock();
- try {
- if (!open) return;
- open = false;
- if (shutdownHandle != -1)
- shutdown.removeShutdownHook(shutdownHandle);
- db.close();
- } finally {
- lock.writeLock().unlock();
- }
+ if (closed.getAndSet(true)) return;
+ shutdown.removeShutdownHook(shutdownHandle);
+ db.close();
}
public ContactId addContact(Author remote, AuthorId local)
throws DbException {
- lock.writeLock().lock();
+ T txn = db.startTransaction();
try {
- T txn = db.startTransaction();
- try {
- if (!db.containsLocalAuthor(txn, local))
- throw new NoSuchLocalAuthorException();
- if (db.containsContact(txn, remote.getId(), local))
- throw new ContactExistsException();
- ContactId c = db.addContact(txn, remote, local);
- db.commitTransaction(txn);
- return c;
- } catch (DbException e) {
- db.abortTransaction(txn);
- throw e;
- }
- } finally {
- lock.writeLock().unlock();
+ if (!db.containsLocalAuthor(txn, local))
+ throw new NoSuchLocalAuthorException();
+ if (db.containsContact(txn, remote.getId(), local))
+ throw new ContactExistsException();
+ ContactId c = db.addContact(txn, remote, local);
+ db.commitTransaction(txn);
+ return c;
+ } catch (DbException e) {
+ db.abortTransaction(txn);
+ throw e;
}
}
public void addGroup(Group g) throws DbException {
boolean added = false;
- lock.writeLock().lock();
+ T txn = db.startTransaction();
try {
- T txn = db.startTransaction();
- try {
- if (!db.containsGroup(txn, g.getId())) {
- db.addGroup(txn, g);
- added = true;
- }
- db.commitTransaction(txn);
- } catch (DbException e) {
- db.abortTransaction(txn);
- throw e;
+ if (!db.containsGroup(txn, g.getId())) {
+ db.addGroup(txn, g);
+ added = true;
}
- } finally {
- lock.writeLock().unlock();
+ db.commitTransaction(txn);
+ } catch (DbException e) {
+ db.abortTransaction(txn);
+ throw e;
}
if (added) eventBus.broadcast(new GroupAddedEvent(g));
}
public void addLocalAuthor(LocalAuthor a) throws DbException {
- lock.writeLock().lock();
+ T txn = db.startTransaction();
try {
- T txn = db.startTransaction();
- try {
- if (!db.containsLocalAuthor(txn, a.getId())) {
- db.addLocalAuthor(txn, a);
- }
- db.commitTransaction(txn);
- } catch (DbException e) {
- db.abortTransaction(txn);
- throw e;
- }
- } finally {
- lock.writeLock().unlock();
+ if (!db.containsLocalAuthor(txn, a.getId()))
+ db.addLocalAuthor(txn, a);
+ db.commitTransaction(txn);
+ } catch (DbException e) {
+ db.abortTransaction(txn);
+ throw e;
}
}
public void addLocalMessage(Message m, ClientId c, Metadata meta,
boolean shared) throws DbException {
boolean added = false;
- lock.writeLock().lock();
+ T txn = db.startTransaction();
try {
- T txn = db.startTransaction();
- try {
- if (!db.containsGroup(txn, m.getGroupId()))
- throw new NoSuchGroupException();
- if (!db.containsMessage(txn, m.getId())) {
- addMessage(txn, m, VALID, shared, null);
- added = true;
- }
- db.mergeMessageMetadata(txn, m.getId(), meta);
- db.commitTransaction(txn);
- } catch (DbException e) {
- db.abortTransaction(txn);
- throw e;
+ if (!db.containsGroup(txn, m.getGroupId()))
+ throw new NoSuchGroupException();
+ if (!db.containsMessage(txn, m.getId())) {
+ addMessage(txn, m, VALID, shared, null);
+ added = true;
}
- } finally {
- lock.writeLock().unlock();
+ db.mergeMessageMetadata(txn, m.getId(), meta);
+ db.commitTransaction(txn);
+ } catch (DbException e) {
+ db.abortTransaction(txn);
+ throw e;
}
if (added) {
eventBus.broadcast(new MessageAddedEvent(m, null));
@@ -229,8 +187,7 @@ class DatabaseComponentImpl implements DatabaseComponent {
/**
* Stores a message and initialises its status with respect to each contact.
- *
- * Locking: write.
+ *
* @param sender null for a locally generated message.
*/
private void addMessage(T txn, Message m, Validity validity, boolean shared,
@@ -253,43 +210,33 @@ class DatabaseComponentImpl implements DatabaseComponent {
public void addTransport(TransportId t, int maxLatency) throws DbException {
boolean added = false;
- lock.writeLock().lock();
+ T txn = db.startTransaction();
try {
- T txn = db.startTransaction();
- try {
- if (!db.containsTransport(txn, t)) {
- db.addTransport(txn, t, maxLatency);
- added = true;
- }
- db.commitTransaction(txn);
- } catch (DbException e) {
- db.abortTransaction(txn);
- throw e;
+ if (!db.containsTransport(txn, t)) {
+ db.addTransport(txn, t, maxLatency);
+ added = true;
}
- } finally {
- lock.writeLock().unlock();
+ db.commitTransaction(txn);
+ } catch (DbException e) {
+ db.abortTransaction(txn);
+ throw e;
}
if (added) eventBus.broadcast(new TransportAddedEvent(t, maxLatency));
}
public void addTransportKeys(ContactId c, TransportKeys k)
throws DbException {
- lock.writeLock().lock();
+ T txn = db.startTransaction();
try {
- T txn = db.startTransaction();
- try {
- if (!db.containsContact(txn, c))
- throw new NoSuchContactException();
- if (!db.containsTransport(txn, k.getTransportId()))
- throw new NoSuchTransportException();
- db.addTransportKeys(txn, c, k);
- db.commitTransaction(txn);
- } catch (DbException e) {
- db.abortTransaction(txn);
- throw e;
- }
- } finally {
- lock.writeLock().unlock();
+ if (!db.containsContact(txn, c))
+ throw new NoSuchContactException();
+ if (!db.containsTransport(txn, k.getTransportId()))
+ throw new NoSuchTransportException();
+ db.addTransportKeys(txn, c, k);
+ db.commitTransaction(txn);
+ } catch (DbException e) {
+ db.abortTransaction(txn);
+ throw e;
}
}
@@ -329,21 +276,16 @@ class DatabaseComponentImpl implements DatabaseComponent {
public Ack generateAck(ContactId c, int maxMessages) throws DbException {
Collection ids;
- lock.writeLock().lock();
+ T txn = db.startTransaction();
try {
- T txn = db.startTransaction();
- try {
- if (!db.containsContact(txn, c))
- throw new NoSuchContactException();
- ids = db.getMessagesToAck(txn, c, maxMessages);
- if (!ids.isEmpty()) db.lowerAckFlag(txn, c, ids);
- db.commitTransaction(txn);
- } catch (DbException e) {
- db.abortTransaction(txn);
- throw e;
- }
- } finally {
- lock.writeLock().unlock();
+ if (!db.containsContact(txn, c))
+ throw new NoSuchContactException();
+ ids = db.getMessagesToAck(txn, c, maxMessages);
+ if (!ids.isEmpty()) db.lowerAckFlag(txn, c, ids);
+ db.commitTransaction(txn);
+ } catch (DbException e) {
+ db.abortTransaction(txn);
+ throw e;
}
if (ids.isEmpty()) return null;
return new Ack(ids);
@@ -353,25 +295,20 @@ class DatabaseComponentImpl implements DatabaseComponent {
int maxLatency) throws DbException {
Collection ids;
List messages = new ArrayList();
- lock.writeLock().lock();
+ T txn = db.startTransaction();
try {
- T txn = db.startTransaction();
- try {
- if (!db.containsContact(txn, c))
- throw new NoSuchContactException();
- ids = db.getMessagesToSend(txn, c, maxLength);
- for (MessageId m : ids) {
- messages.add(db.getRawMessage(txn, m));
- db.updateExpiryTime(txn, c, m, maxLatency);
- }
- if (!ids.isEmpty()) db.lowerRequestedFlag(txn, c, ids);
- db.commitTransaction(txn);
- } catch (DbException e) {
- db.abortTransaction(txn);
- throw e;
+ if (!db.containsContact(txn, c))
+ throw new NoSuchContactException();
+ ids = db.getMessagesToSend(txn, c, maxLength);
+ for (MessageId m : ids) {
+ messages.add(db.getRawMessage(txn, m));
+ db.updateExpiryTime(txn, c, m, maxLatency);
}
- } finally {
- lock.writeLock().unlock();
+ if (!ids.isEmpty()) db.lowerRequestedFlag(txn, c, ids);
+ db.commitTransaction(txn);
+ } catch (DbException e) {
+ db.abortTransaction(txn);
+ throw e;
}
if (messages.isEmpty()) return null;
if (!ids.isEmpty()) eventBus.broadcast(new MessagesSentEvent(c, ids));
@@ -381,22 +318,16 @@ class DatabaseComponentImpl implements DatabaseComponent {
public Offer generateOffer(ContactId c, int maxMessages, int maxLatency)
throws DbException {
Collection ids;
- lock.writeLock().lock();
+ T txn = db.startTransaction();
try {
- T txn = db.startTransaction();
- try {
- if (!db.containsContact(txn, c))
- throw new NoSuchContactException();
- ids = db.getMessagesToOffer(txn, c, maxMessages);
- for (MessageId m : ids)
- db.updateExpiryTime(txn, c, m, maxLatency);
- db.commitTransaction(txn);
- } catch (DbException e) {
- db.abortTransaction(txn);
- throw e;
- }
- } finally {
- lock.writeLock().unlock();
+ if (!db.containsContact(txn, c))
+ throw new NoSuchContactException();
+ ids = db.getMessagesToOffer(txn, c, maxMessages);
+ for (MessageId m : ids) db.updateExpiryTime(txn, c, m, maxLatency);
+ db.commitTransaction(txn);
+ } catch (DbException e) {
+ db.abortTransaction(txn);
+ throw e;
}
if (ids.isEmpty()) return null;
return new Offer(ids);
@@ -405,21 +336,16 @@ class DatabaseComponentImpl implements DatabaseComponent {
public Request generateRequest(ContactId c, int maxMessages)
throws DbException {
Collection ids;
- lock.writeLock().lock();
+ T txn = db.startTransaction();
try {
- T txn = db.startTransaction();
- try {
- if (!db.containsContact(txn, c))
- throw new NoSuchContactException();
- ids = db.getMessagesToRequest(txn, c, maxMessages);
- if (!ids.isEmpty()) db.removeOfferedMessages(txn, c, ids);
- db.commitTransaction(txn);
- } catch (DbException e) {
- db.abortTransaction(txn);
- throw e;
- }
- } finally {
- lock.writeLock().unlock();
+ if (!db.containsContact(txn, c))
+ throw new NoSuchContactException();
+ ids = db.getMessagesToRequest(txn, c, maxMessages);
+ if (!ids.isEmpty()) db.removeOfferedMessages(txn, c, ids);
+ db.commitTransaction(txn);
+ } catch (DbException e) {
+ db.abortTransaction(txn);
+ throw e;
}
if (ids.isEmpty()) return null;
return new Request(ids);
@@ -429,25 +355,20 @@ class DatabaseComponentImpl implements DatabaseComponent {
int maxLatency) throws DbException {
Collection ids;
List messages = new ArrayList();
- lock.writeLock().lock();
+ T txn = db.startTransaction();
try {
- T txn = db.startTransaction();
- try {
- if (!db.containsContact(txn, c))
- throw new NoSuchContactException();
- ids = db.getRequestedMessagesToSend(txn, c, maxLength);
- for (MessageId m : ids) {
- messages.add(db.getRawMessage(txn, m));
- db.updateExpiryTime(txn, c, m, maxLatency);
- }
- if (!ids.isEmpty()) db.lowerRequestedFlag(txn, c, ids);
- db.commitTransaction(txn);
- } catch (DbException e) {
- db.abortTransaction(txn);
- throw e;
+ if (!db.containsContact(txn, c))
+ throw new NoSuchContactException();
+ ids = db.getRequestedMessagesToSend(txn, c, maxLength);
+ for (MessageId m : ids) {
+ messages.add(db.getRawMessage(txn, m));
+ db.updateExpiryTime(txn, c, m, maxLatency);
}
- } finally {
- lock.writeLock().unlock();
+ if (!ids.isEmpty()) db.lowerRequestedFlag(txn, c, ids);
+ db.commitTransaction(txn);
+ } catch (DbException e) {
+ db.abortTransaction(txn);
+ throw e;
}
if (messages.isEmpty()) return null;
if (!ids.isEmpty()) eventBus.broadcast(new MessagesSentEvent(c, ids));
@@ -455,518 +376,384 @@ class DatabaseComponentImpl implements DatabaseComponent {
}
public Contact getContact(ContactId c) throws DbException {
- lock.readLock().lock();
+ T txn = db.startTransaction();
try {
- T txn = db.startTransaction();
- try {
- if (!db.containsContact(txn, c))
- throw new NoSuchContactException();
- Contact contact = db.getContact(txn, c);
- db.commitTransaction(txn);
- return contact;
- } catch (DbException e) {
- db.abortTransaction(txn);
- throw e;
- }
- } finally {
- lock.readLock().unlock();
+ if (!db.containsContact(txn, c))
+ throw new NoSuchContactException();
+ Contact contact = db.getContact(txn, c);
+ db.commitTransaction(txn);
+ return contact;
+ } catch (DbException e) {
+ db.abortTransaction(txn);
+ throw e;
}
}
public Collection getContacts() throws DbException {
- lock.readLock().lock();
+ T txn = db.startTransaction();
try {
- T txn = db.startTransaction();
- try {
- Collection contacts = db.getContacts(txn);
- db.commitTransaction(txn);
- return contacts;
- } catch (DbException e) {
- db.abortTransaction(txn);
- throw e;
- }
- } finally {
- lock.readLock().unlock();
+ Collection contacts = db.getContacts(txn);
+ db.commitTransaction(txn);
+ return contacts;
+ } catch (DbException e) {
+ db.abortTransaction(txn);
+ throw e;
}
}
public Collection getContacts(AuthorId a) throws DbException {
- lock.readLock().lock();
+ T txn = db.startTransaction();
try {
- T txn = db.startTransaction();
- try {
- if (!db.containsLocalAuthor(txn, a))
- throw new NoSuchLocalAuthorException();
- Collection contacts = db.getContacts(txn, a);
- db.commitTransaction(txn);
- return contacts;
- } catch (DbException e) {
- db.abortTransaction(txn);
- throw e;
- }
- } finally {
- lock.readLock().unlock();
+ if (!db.containsLocalAuthor(txn, a))
+ throw new NoSuchLocalAuthorException();
+ Collection contacts = db.getContacts(txn, a);
+ db.commitTransaction(txn);
+ return contacts;
+ } catch (DbException e) {
+ db.abortTransaction(txn);
+ throw e;
}
}
public DeviceId getDeviceId() throws DbException {
- lock.readLock().lock();
+ T txn = db.startTransaction();
try {
- T txn = db.startTransaction();
- try {
- DeviceId id = db.getDeviceId(txn);
- db.commitTransaction(txn);
- return id;
- } catch (DbException e) {
- db.abortTransaction(txn);
- throw e;
- }
- } finally {
- lock.readLock().unlock();
+ DeviceId id = db.getDeviceId(txn);
+ db.commitTransaction(txn);
+ return id;
+ } catch (DbException e) {
+ db.abortTransaction(txn);
+ throw e;
}
}
public Group getGroup(GroupId g) throws DbException {
- lock.readLock().lock();
+ T txn = db.startTransaction();
try {
- T txn = db.startTransaction();
- try {
- if (!db.containsGroup(txn, g))
- throw new NoSuchGroupException();
- Group group = db.getGroup(txn, g);
- db.commitTransaction(txn);
- return group;
- } catch (DbException e) {
- db.abortTransaction(txn);
- throw e;
- }
- } finally {
- lock.readLock().unlock();
+ if (!db.containsGroup(txn, g))
+ throw new NoSuchGroupException();
+ Group group = db.getGroup(txn, g);
+ db.commitTransaction(txn);
+ return group;
+ } catch (DbException e) {
+ db.abortTransaction(txn);
+ throw e;
}
}
public Metadata getGroupMetadata(GroupId g) throws DbException {
- lock.readLock().lock();
+ T txn = db.startTransaction();
try {
- T txn = db.startTransaction();
- try {
- if (!db.containsGroup(txn, g))
- throw new NoSuchGroupException();
- Metadata metadata = db.getGroupMetadata(txn, g);
- db.commitTransaction(txn);
- return metadata;
- } catch (DbException e) {
- db.abortTransaction(txn);
- throw e;
- }
- } finally {
- lock.readLock().unlock();
+ if (!db.containsGroup(txn, g))
+ throw new NoSuchGroupException();
+ Metadata metadata = db.getGroupMetadata(txn, g);
+ db.commitTransaction(txn);
+ return metadata;
+ } catch (DbException e) {
+ db.abortTransaction(txn);
+ throw e;
}
}
public Collection getGroups(ClientId c) throws DbException {
- lock.readLock().lock();
+ T txn = db.startTransaction();
try {
- T txn = db.startTransaction();
- try {
- Collection groups = db.getGroups(txn, c);
- db.commitTransaction(txn);
- return groups;
- } catch (DbException e) {
- db.abortTransaction(txn);
- throw e;
- }
- } finally {
- lock.readLock().unlock();
+ Collection groups = db.getGroups(txn, c);
+ db.commitTransaction(txn);
+ return groups;
+ } catch (DbException e) {
+ db.abortTransaction(txn);
+ throw e;
}
}
public LocalAuthor getLocalAuthor(AuthorId a) throws DbException {
- lock.readLock().lock();
+ T txn = db.startTransaction();
try {
- T txn = db.startTransaction();
- try {
- if (!db.containsLocalAuthor(txn, a))
- throw new NoSuchLocalAuthorException();
- LocalAuthor localAuthor = db.getLocalAuthor(txn, a);
- db.commitTransaction(txn);
- return localAuthor;
- } catch (DbException e) {
- db.abortTransaction(txn);
- throw e;
- }
- } finally {
- lock.readLock().unlock();
+ if (!db.containsLocalAuthor(txn, a))
+ throw new NoSuchLocalAuthorException();
+ LocalAuthor localAuthor = db.getLocalAuthor(txn, a);
+ db.commitTransaction(txn);
+ return localAuthor;
+ } catch (DbException e) {
+ db.abortTransaction(txn);
+ throw e;
}
}
public Collection getLocalAuthors() throws DbException {
- lock.readLock().lock();
+ T txn = db.startTransaction();
try {
- T txn = db.startTransaction();
- try {
- Collection authors = db.getLocalAuthors(txn);
- db.commitTransaction(txn);
- return authors;
- } catch (DbException e) {
- db.abortTransaction(txn);
- throw e;
- }
- } finally {
- lock.readLock().unlock();
+ Collection authors = db.getLocalAuthors(txn);
+ db.commitTransaction(txn);
+ return authors;
+ } catch (DbException e) {
+ db.abortTransaction(txn);
+ throw e;
}
}
public Collection getMessagesToValidate(ClientId c)
throws DbException {
- lock.readLock().lock();
+ T txn = db.startTransaction();
try {
- T txn = db.startTransaction();
- try {
- Collection ids = db.getMessagesToValidate(txn, c);
- db.commitTransaction(txn);
- return ids;
- } catch (DbException e) {
- db.abortTransaction(txn);
- throw e;
- }
- } finally {
- lock.readLock().unlock();
+ Collection ids = db.getMessagesToValidate(txn, c);
+ db.commitTransaction(txn);
+ return ids;
+ } catch (DbException e) {
+ db.abortTransaction(txn);
+ throw e;
}
}
public byte[] getRawMessage(MessageId m) throws DbException {
- lock.readLock().lock();
+ T txn = db.startTransaction();
try {
- T txn = db.startTransaction();
- try {
- if (!db.containsMessage(txn, m))
- throw new NoSuchMessageException();
- byte[] raw = db.getRawMessage(txn, m);
- db.commitTransaction(txn);
- return raw;
- } catch (DbException e) {
- db.abortTransaction(txn);
- throw e;
- }
- } finally {
- lock.readLock().unlock();
+ if (!db.containsMessage(txn, m))
+ throw new NoSuchMessageException();
+ byte[] raw = db.getRawMessage(txn, m);
+ db.commitTransaction(txn);
+ return raw;
+ } catch (DbException e) {
+ db.abortTransaction(txn);
+ throw e;
}
}
public Map getMessageMetadata(GroupId g)
throws DbException {
- lock.readLock().lock();
+ T txn = db.startTransaction();
try {
- T txn = db.startTransaction();
- try {
- if (!db.containsGroup(txn, g))
- throw new NoSuchGroupException();
- Map metadata =
- db.getMessageMetadata(txn, g);
- db.commitTransaction(txn);
- return metadata;
- } catch (DbException e) {
- db.abortTransaction(txn);
- throw e;
- }
- } finally {
- lock.readLock().unlock();
+ if (!db.containsGroup(txn, g))
+ throw new NoSuchGroupException();
+ Map metadata = db.getMessageMetadata(txn, g);
+ db.commitTransaction(txn);
+ return metadata;
+ } catch (DbException e) {
+ db.abortTransaction(txn);
+ throw e;
}
}
public Metadata getMessageMetadata(MessageId m) throws DbException {
- lock.readLock().lock();
+ T txn = db.startTransaction();
try {
- T txn = db.startTransaction();
- try {
- if (!db.containsMessage(txn, m))
- throw new NoSuchMessageException();
- Metadata metadata = db.getMessageMetadata(txn, m);
- db.commitTransaction(txn);
- return metadata;
- } catch (DbException e) {
- db.abortTransaction(txn);
- throw e;
- }
- } finally {
- lock.readLock().unlock();
+ if (!db.containsMessage(txn, m))
+ throw new NoSuchMessageException();
+ Metadata metadata = db.getMessageMetadata(txn, m);
+ db.commitTransaction(txn);
+ return metadata;
+ } catch (DbException e) {
+ db.abortTransaction(txn);
+ throw e;
}
}
public Collection getMessageStatus(ContactId c, GroupId g)
throws DbException {
- lock.readLock().lock();
+ T txn = db.startTransaction();
try {
- T txn = db.startTransaction();
- try {
- if (!db.containsContact(txn, c))
- throw new NoSuchContactException();
- if (!db.containsGroup(txn, g))
- throw new NoSuchGroupException();
- Collection statuses =
- db.getMessageStatus(txn, c, g);
- db.commitTransaction(txn);
- return statuses;
- } catch (DbException e) {
- db.abortTransaction(txn);
- throw e;
- }
- } finally {
- lock.readLock().unlock();
+ if (!db.containsContact(txn, c))
+ throw new NoSuchContactException();
+ if (!db.containsGroup(txn, g))
+ throw new NoSuchGroupException();
+ Collection statuses = db.getMessageStatus(txn, c, g);
+ db.commitTransaction(txn);
+ return statuses;
+ } catch (DbException e) {
+ db.abortTransaction(txn);
+ throw e;
}
}
public MessageStatus getMessageStatus(ContactId c, MessageId m)
throws DbException {
- lock.readLock().lock();
+ T txn = db.startTransaction();
try {
- T txn = db.startTransaction();
- try {
- if (!db.containsContact(txn, c))
- throw new NoSuchContactException();
- if (!db.containsMessage(txn, m))
- throw new NoSuchMessageException();
- MessageStatus status = db.getMessageStatus(txn, c, m);
- db.commitTransaction(txn);
- return status;
- } catch (DbException e) {
- db.abortTransaction(txn);
- throw e;
- }
- } finally {
- lock.readLock().unlock();
+ if (!db.containsContact(txn, c))
+ throw new NoSuchContactException();
+ if (!db.containsMessage(txn, m))
+ throw new NoSuchMessageException();
+ MessageStatus status = db.getMessageStatus(txn, c, m);
+ db.commitTransaction(txn);
+ return status;
+ } catch (DbException e) {
+ db.abortTransaction(txn);
+ throw e;
}
}
public Settings getSettings(String namespace) throws DbException {
- lock.readLock().lock();
+ T txn = db.startTransaction();
try {
- T txn = db.startTransaction();
- try {
- Settings s = db.getSettings(txn, namespace);
- db.commitTransaction(txn);
- return s;
- } catch (DbException e) {
- db.abortTransaction(txn);
- throw e;
- }
- } finally {
- lock.readLock().unlock();
+ Settings s = db.getSettings(txn, namespace);
+ db.commitTransaction(txn);
+ return s;
+ } catch (DbException e) {
+ db.abortTransaction(txn);
+ throw e;
}
}
public Map getTransportKeys(TransportId t)
throws DbException {
- lock.readLock().lock();
+ T txn = db.startTransaction();
try {
- T txn = db.startTransaction();
- try {
- if (!db.containsTransport(txn, t))
- throw new NoSuchTransportException();
- Map keys =
- db.getTransportKeys(txn, t);
- db.commitTransaction(txn);
- return keys;
- } catch (DbException e) {
- db.abortTransaction(txn);
- throw e;
- }
- } finally {
- lock.readLock().unlock();
+ if (!db.containsTransport(txn, t))
+ throw new NoSuchTransportException();
+ Map keys = db.getTransportKeys(txn, t);
+ db.commitTransaction(txn);
+ return keys;
+ } catch (DbException e) {
+ db.abortTransaction(txn);
+ throw e;
}
}
public Map getTransportLatencies()
throws DbException {
- lock.readLock().lock();
+ T txn = db.startTransaction();
try {
- T txn = db.startTransaction();
- try {
- Map latencies =
- db.getTransportLatencies(txn);
- db.commitTransaction(txn);
- return latencies;
- } catch (DbException e) {
- db.abortTransaction(txn);
- throw e;
- }
- } finally {
- lock.readLock().unlock();
+ Map latencies = db.getTransportLatencies(txn);
+ db.commitTransaction(txn);
+ return latencies;
+ } catch (DbException e) {
+ db.abortTransaction(txn);
+ throw e;
}
}
public Collection getVisibility(GroupId g) throws DbException {
- lock.readLock().lock();
+ T txn = db.startTransaction();
try {
- T txn = db.startTransaction();
- try {
- if (!db.containsGroup(txn, g))
- throw new NoSuchGroupException();
- Collection visible = db.getVisibility(txn, g);
- db.commitTransaction(txn);
- return visible;
- } catch (DbException e) {
- db.abortTransaction(txn);
- throw e;
- }
- } finally {
- lock.readLock().unlock();
+ if (!db.containsGroup(txn, g))
+ throw new NoSuchGroupException();
+ Collection visible = db.getVisibility(txn, g);
+ db.commitTransaction(txn);
+ return visible;
+ } catch (DbException e) {
+ db.abortTransaction(txn);
+ throw e;
}
}
public void incrementStreamCounter(ContactId c, TransportId t,
long rotationPeriod) throws DbException {
- lock.writeLock().lock();
+ T txn = db.startTransaction();
try {
- T txn = db.startTransaction();
- try {
- if (!db.containsContact(txn, c))
- throw new NoSuchContactException();
- if (!db.containsTransport(txn, t))
- throw new NoSuchTransportException();
- db.incrementStreamCounter(txn, c, t, rotationPeriod);
- db.commitTransaction(txn);
- } catch (DbException e) {
- db.abortTransaction(txn);
- throw e;
- }
- } finally {
- lock.writeLock().unlock();
+ if (!db.containsContact(txn, c))
+ throw new NoSuchContactException();
+ if (!db.containsTransport(txn, t))
+ throw new NoSuchTransportException();
+ db.incrementStreamCounter(txn, c, t, rotationPeriod);
+ db.commitTransaction(txn);
+ } catch (DbException e) {
+ db.abortTransaction(txn);
+ throw e;
}
}
public boolean isVisibleToContact(ContactId c, GroupId g)
throws DbException {
- lock.readLock().lock();
+ T txn = db.startTransaction();
try {
- T txn = db.startTransaction();
- try {
- if (!db.containsContact(txn, c))
- throw new NoSuchContactException();
- if (!db.containsGroup(txn, g))
- throw new NoSuchGroupException();
- boolean visible = db.containsVisibleGroup(txn, c, g);
- db.commitTransaction(txn);
- return visible;
- } catch (DbException e) {
- db.abortTransaction(txn);
- throw e;
- }
- } finally {
- lock.readLock().unlock();
+ if (!db.containsContact(txn, c))
+ throw new NoSuchContactException();
+ if (!db.containsGroup(txn, g))
+ throw new NoSuchGroupException();
+ boolean visible = db.containsVisibleGroup(txn, c, g);
+ db.commitTransaction(txn);
+ return visible;
+ } catch (DbException e) {
+ db.abortTransaction(txn);
+ throw e;
}
}
public void mergeGroupMetadata(GroupId g, Metadata meta)
throws DbException {
- lock.writeLock().lock();
+ T txn = db.startTransaction();
try {
- T txn = db.startTransaction();
- try {
- if (!db.containsGroup(txn, g))
- throw new NoSuchGroupException();
- db.mergeGroupMetadata(txn, g, meta);
- db.commitTransaction(txn);
- } catch (DbException e) {
- db.abortTransaction(txn);
- throw e;
- }
- } finally {
- lock.writeLock().unlock();
+ if (!db.containsGroup(txn, g))
+ throw new NoSuchGroupException();
+ db.mergeGroupMetadata(txn, g, meta);
+ db.commitTransaction(txn);
+ } catch (DbException e) {
+ db.abortTransaction(txn);
+ throw e;
}
}
public void mergeMessageMetadata(MessageId m, Metadata meta)
throws DbException {
- lock.writeLock().lock();
+ T txn = db.startTransaction();
try {
- T txn = db.startTransaction();
- try {
- if (!db.containsMessage(txn, m))
- throw new NoSuchMessageException();
- db.mergeMessageMetadata(txn, m, meta);
- db.commitTransaction(txn);
- } catch (DbException e) {
- db.abortTransaction(txn);
- throw e;
- }
- } finally {
- lock.writeLock().unlock();
+ if (!db.containsMessage(txn, m))
+ throw new NoSuchMessageException();
+ db.mergeMessageMetadata(txn, m, meta);
+ db.commitTransaction(txn);
+ } catch (DbException e) {
+ db.abortTransaction(txn);
+ throw e;
}
}
public void mergeSettings(Settings s, String namespace) throws DbException {
boolean changed = false;
- lock.writeLock().lock();
+ T txn = db.startTransaction();
try {
- T txn = db.startTransaction();
- try {
- Settings old = db.getSettings(txn, namespace);
- Settings merged = new Settings();
- merged.putAll(old);
- merged.putAll(s);
- if (!merged.equals(old)) {
- db.mergeSettings(txn, s, namespace);
- changed = true;
- }
- db.commitTransaction(txn);
- } catch (DbException e) {
- db.abortTransaction(txn);
- throw e;
+ Settings old = db.getSettings(txn, namespace);
+ Settings merged = new Settings();
+ merged.putAll(old);
+ merged.putAll(s);
+ if (!merged.equals(old)) {
+ db.mergeSettings(txn, s, namespace);
+ changed = true;
}
- } finally {
- lock.writeLock().unlock();
+ db.commitTransaction(txn);
+ } catch (DbException e) {
+ db.abortTransaction(txn);
+ throw e;
}
if (changed) eventBus.broadcast(new SettingsUpdatedEvent(namespace));
}
public void receiveAck(ContactId c, Ack a) throws DbException {
Collection acked = new ArrayList();
- lock.writeLock().lock();
+ T txn = db.startTransaction();
try {
- T txn = db.startTransaction();
- try {
- if (!db.containsContact(txn, c))
- throw new NoSuchContactException();
- for (MessageId m : a.getMessageIds()) {
- if (db.containsVisibleMessage(txn, c, m)) {
- db.raiseSeenFlag(txn, c, m);
- acked.add(m);
- }
+ if (!db.containsContact(txn, c))
+ throw new NoSuchContactException();
+ for (MessageId m : a.getMessageIds()) {
+ if (db.containsVisibleMessage(txn, c, m)) {
+ db.raiseSeenFlag(txn, c, m);
+ acked.add(m);
}
- db.commitTransaction(txn);
- } catch (DbException e) {
- db.abortTransaction(txn);
- throw e;
}
- } finally {
- lock.writeLock().unlock();
+ db.commitTransaction(txn);
+ } catch (DbException e) {
+ db.abortTransaction(txn);
+ throw e;
}
eventBus.broadcast(new MessagesAckedEvent(c, acked));
}
public void receiveMessage(ContactId c, Message m) throws DbException {
boolean duplicate, visible;
- lock.writeLock().lock();
+ T txn = db.startTransaction();
try {
- T txn = db.startTransaction();
- try {
- if (!db.containsContact(txn, c))
- throw new NoSuchContactException();
- duplicate = db.containsMessage(txn, m.getId());
- visible = db.containsVisibleGroup(txn, c, m.getGroupId());
- if (visible) {
- if (!duplicate) addMessage(txn, m, UNKNOWN, false, c);
- db.raiseAckFlag(txn, c, m.getId());
- }
- db.commitTransaction(txn);
- } catch (DbException e) {
- db.abortTransaction(txn);
- throw e;
+ if (!db.containsContact(txn, c))
+ throw new NoSuchContactException();
+ duplicate = db.containsMessage(txn, m.getId());
+ visible = db.containsVisibleGroup(txn, c, m.getGroupId());
+ if (visible) {
+ if (!duplicate) addMessage(txn, m, UNKNOWN, false, c);
+ db.raiseAckFlag(txn, c, m.getId());
}
- } finally {
- lock.writeLock().unlock();
+ db.commitTransaction(txn);
+ } catch (DbException e) {
+ db.abortTransaction(txn);
+ throw e;
}
if (visible) {
if (!duplicate) eventBus.broadcast(new MessageAddedEvent(m, c));
@@ -976,31 +763,26 @@ class DatabaseComponentImpl implements DatabaseComponent {
public void receiveOffer(ContactId c, Offer o) throws DbException {
boolean ack = false, request = false;
- lock.writeLock().lock();
+ T txn = db.startTransaction();
try {
- T txn = db.startTransaction();
- try {
- if (!db.containsContact(txn, c))
- throw new NoSuchContactException();
- int count = db.countOfferedMessages(txn, c);
- for (MessageId m : o.getMessageIds()) {
- if (db.containsVisibleMessage(txn, c, m)) {
- db.raiseSeenFlag(txn, c, m);
- db.raiseAckFlag(txn, c, m);
- ack = true;
- } else if (count < MAX_OFFERED_MESSAGES) {
- db.addOfferedMessage(txn, c, m);
- request = true;
- count++;
- }
+ if (!db.containsContact(txn, c))
+ throw new NoSuchContactException();
+ int count = db.countOfferedMessages(txn, c);
+ for (MessageId m : o.getMessageIds()) {
+ if (db.containsVisibleMessage(txn, c, m)) {
+ db.raiseSeenFlag(txn, c, m);
+ db.raiseAckFlag(txn, c, m);
+ ack = true;
+ } else if (count < MAX_OFFERED_MESSAGES) {
+ db.addOfferedMessage(txn, c, m);
+ request = true;
+ count++;
}
- db.commitTransaction(txn);
- } catch (DbException e) {
- db.abortTransaction(txn);
- throw e;
}
- } finally {
- lock.writeLock().unlock();
+ db.commitTransaction(txn);
+ } catch (DbException e) {
+ db.abortTransaction(txn);
+ throw e;
}
if (ack) eventBus.broadcast(new MessageToAckEvent(c));
if (request) eventBus.broadcast(new MessageToRequestEvent(c));
@@ -1008,239 +790,184 @@ class DatabaseComponentImpl implements DatabaseComponent {
public void receiveRequest(ContactId c, Request r) throws DbException {
boolean requested = false;
- lock.writeLock().lock();
+ T txn = db.startTransaction();
try {
- T txn = db.startTransaction();
- try {
- if (!db.containsContact(txn, c))
- throw new NoSuchContactException();
- for (MessageId m : r.getMessageIds()) {
- if (db.containsVisibleMessage(txn, c, m)) {
- db.raiseRequestedFlag(txn, c, m);
- db.resetExpiryTime(txn, c, m);
- requested = true;
- }
+ if (!db.containsContact(txn, c))
+ throw new NoSuchContactException();
+ for (MessageId m : r.getMessageIds()) {
+ if (db.containsVisibleMessage(txn, c, m)) {
+ db.raiseRequestedFlag(txn, c, m);
+ db.resetExpiryTime(txn, c, m);
+ requested = true;
}
- db.commitTransaction(txn);
- } catch (DbException e) {
- db.abortTransaction(txn);
- throw e;
}
- } finally {
- lock.writeLock().unlock();
+ db.commitTransaction(txn);
+ } catch (DbException e) {
+ db.abortTransaction(txn);
+ throw e;
}
if (requested) eventBus.broadcast(new MessageRequestedEvent(c));
}
public void removeContact(ContactId c) throws DbException {
- lock.writeLock().lock();
+ T txn = db.startTransaction();
try {
- T txn = db.startTransaction();
- try {
- if (!db.containsContact(txn, c))
- throw new NoSuchContactException();
- db.removeContact(txn, c);
- db.commitTransaction(txn);
- } catch (DbException e) {
- db.abortTransaction(txn);
- throw e;
- }
- } finally {
- lock.writeLock().unlock();
+ if (!db.containsContact(txn, c))
+ throw new NoSuchContactException();
+ db.removeContact(txn, c);
+ db.commitTransaction(txn);
+ } catch (DbException e) {
+ db.abortTransaction(txn);
+ throw e;
}
}
public void removeGroup(Group g) throws DbException {
Collection affected;
- lock.writeLock().lock();
+ T txn = db.startTransaction();
try {
- T txn = db.startTransaction();
- try {
- GroupId id = g.getId();
- if (!db.containsGroup(txn, id))
- throw new NoSuchGroupException();
- affected = db.getVisibility(txn, id);
- db.removeGroup(txn, id);
- db.commitTransaction(txn);
- } catch (DbException e) {
- db.abortTransaction(txn);
- throw e;
- }
- } finally {
- lock.writeLock().unlock();
+ GroupId id = g.getId();
+ if (!db.containsGroup(txn, id))
+ throw new NoSuchGroupException();
+ affected = db.getVisibility(txn, id);
+ db.removeGroup(txn, id);
+ db.commitTransaction(txn);
+ } catch (DbException e) {
+ db.abortTransaction(txn);
+ throw e;
}
eventBus.broadcast(new GroupRemovedEvent(g));
eventBus.broadcast(new GroupVisibilityUpdatedEvent(affected));
}
public void removeLocalAuthor(AuthorId a) throws DbException {
- lock.writeLock().lock();
+ T txn = db.startTransaction();
try {
- T txn = db.startTransaction();
- try {
- if (!db.containsLocalAuthor(txn, a))
- throw new NoSuchLocalAuthorException();
- db.removeLocalAuthor(txn, a);
- db.commitTransaction(txn);
- } catch (DbException e) {
- db.abortTransaction(txn);
- throw e;
- }
- } finally {
- lock.writeLock().unlock();
+ if (!db.containsLocalAuthor(txn, a))
+ throw new NoSuchLocalAuthorException();
+ db.removeLocalAuthor(txn, a);
+ db.commitTransaction(txn);
+ } catch (DbException e) {
+ db.abortTransaction(txn);
+ throw e;
}
}
public void removeTransport(TransportId t) throws DbException {
- lock.writeLock().lock();
+ T txn = db.startTransaction();
try {
- T txn = db.startTransaction();
- try {
- if (!db.containsTransport(txn, t))
- throw new NoSuchTransportException();
- db.removeTransport(txn, t);
- db.commitTransaction(txn);
- } catch (DbException e) {
- db.abortTransaction(txn);
- throw e;
- }
- } finally {
- lock.writeLock().unlock();
+ if (!db.containsTransport(txn, t))
+ throw new NoSuchTransportException();
+ db.removeTransport(txn, t);
+ db.commitTransaction(txn);
+ } catch (DbException e) {
+ db.abortTransaction(txn);
+ throw e;
}
eventBus.broadcast(new TransportRemovedEvent(t));
}
public void setContactStatus(ContactId c, StorageStatus s)
throws DbException {
- lock.writeLock().lock();
+ T txn = db.startTransaction();
try {
- T txn = db.startTransaction();
- try {
- if (!db.containsContact(txn, c))
- throw new NoSuchContactException();
- db.setContactStatus(txn, c, s);
- db.commitTransaction(txn);
- } catch (DbException e) {
- db.abortTransaction(txn);
- throw e;
- }
- } finally {
- lock.writeLock().unlock();
+ if (!db.containsContact(txn, c))
+ throw new NoSuchContactException();
+ db.setContactStatus(txn, c, s);
+ db.commitTransaction(txn);
+ } catch (DbException e) {
+ db.abortTransaction(txn);
+ throw e;
}
}
public void setLocalAuthorStatus(AuthorId a, StorageStatus s)
throws DbException {
- lock.writeLock().lock();
+ T txn = db.startTransaction();
try {
- T txn = db.startTransaction();
- try {
- if (!db.containsLocalAuthor(txn, a))
- throw new NoSuchLocalAuthorException();
- db.setLocalAuthorStatus(txn, a, s);
- db.commitTransaction(txn);
- } catch (DbException e) {
- db.abortTransaction(txn);
- throw e;
- }
- } finally {
- lock.writeLock().unlock();
+ if (!db.containsLocalAuthor(txn, a))
+ throw new NoSuchLocalAuthorException();
+ db.setLocalAuthorStatus(txn, a, s);
+ db.commitTransaction(txn);
+ } catch (DbException e) {
+ db.abortTransaction(txn);
+ throw e;
}
}
public void setMessageShared(Message m, boolean shared)
throws DbException {
- lock.writeLock().lock();
+ T txn = db.startTransaction();
try {
- T txn = db.startTransaction();
- try {
- if (!db.containsMessage(txn, m.getId()))
- throw new NoSuchMessageException();
- db.setMessageShared(txn, m.getId(), shared);
- db.commitTransaction(txn);
- } catch (DbException e) {
- db.abortTransaction(txn);
- throw e;
- }
- } finally {
- lock.writeLock().unlock();
+ if (!db.containsMessage(txn, m.getId()))
+ throw new NoSuchMessageException();
+ db.setMessageShared(txn, m.getId(), shared);
+ db.commitTransaction(txn);
+ } catch (DbException e) {
+ db.abortTransaction(txn);
+ throw e;
}
if (shared) eventBus.broadcast(new MessageSharedEvent(m));
}
public void setMessageValid(Message m, ClientId c, boolean valid)
throws DbException {
- lock.writeLock().lock();
+ T txn = db.startTransaction();
try {
- T txn = db.startTransaction();
- try {
- if (!db.containsMessage(txn, m.getId()))
- throw new NoSuchMessageException();
- db.setMessageValid(txn, m.getId(), valid);
- db.commitTransaction(txn);
- } catch (DbException e) {
- db.abortTransaction(txn);
- throw e;
- }
- } finally {
- lock.writeLock().unlock();
+ if (!db.containsMessage(txn, m.getId()))
+ throw new NoSuchMessageException();
+ db.setMessageValid(txn, m.getId(), valid);
+ db.commitTransaction(txn);
+ } catch (DbException e) {
+ db.abortTransaction(txn);
+ throw e;
}
eventBus.broadcast(new MessageValidatedEvent(m, c, false, valid));
}
public void setReorderingWindow(ContactId c, TransportId t,
long rotationPeriod, long base, byte[] bitmap) throws DbException {
- lock.writeLock().lock();
+ T txn = db.startTransaction();
try {
- T txn = db.startTransaction();
- try {
- if (!db.containsContact(txn, c))
- throw new NoSuchContactException();
- if (!db.containsTransport(txn, t))
- throw new NoSuchTransportException();
- db.setReorderingWindow(txn, c, t, rotationPeriod, base, bitmap);
- db.commitTransaction(txn);
- } catch (DbException e) {
- db.abortTransaction(txn);
- throw e;
- }
- } finally {
- lock.writeLock().unlock();
+ if (!db.containsContact(txn, c))
+ throw new NoSuchContactException();
+ if (!db.containsTransport(txn, t))
+ throw new NoSuchTransportException();
+ db.setReorderingWindow(txn, c, t, rotationPeriod, base, bitmap);
+ db.commitTransaction(txn);
+ } catch (DbException e) {
+ db.abortTransaction(txn);
+ throw e;
}
}
public void setVisibility(GroupId g, Collection visible)
throws DbException {
Collection affected = new ArrayList();
- lock.writeLock().lock();
+ T txn = db.startTransaction();
try {
- T txn = db.startTransaction();
- try {
- if (!db.containsGroup(txn, g))
- throw new NoSuchGroupException();
- // Use HashSets for O(1) lookups, O(n) overall running time
- Collection now = new HashSet(visible);
- Collection before = db.getVisibility(txn, g);
- before = new HashSet(before);
- // Set the group's visibility for each current contact
- for (ContactId c : db.getContactIds(txn)) {
- boolean wasBefore = before.contains(c);
- boolean isNow = now.contains(c);
- if (!wasBefore && isNow) {
- db.addVisibility(txn, c, g);
- affected.add(c);
- } else if (wasBefore && !isNow) {
- db.removeVisibility(txn, c, g);
- affected.add(c);
- }
+ if (!db.containsGroup(txn, g))
+ throw new NoSuchGroupException();
+ // Use HashSets for O(1) lookups, O(n) overall running time
+ Collection now = new HashSet(visible);
+ Collection before = db.getVisibility(txn, g);
+ before = new HashSet(before);
+ // Set the group's visibility for each current contact
+ for (ContactId c : db.getContactIds(txn)) {
+ boolean wasBefore = before.contains(c);
+ boolean isNow = now.contains(c);
+ if (!wasBefore && isNow) {
+ db.addVisibility(txn, c, g);
+ affected.add(c);
+ } else if (wasBefore && !isNow) {
+ db.removeVisibility(txn, c, g);
+ affected.add(c);
}
- db.commitTransaction(txn);
- } catch (DbException e) {
- db.abortTransaction(txn);
- throw e;
}
- } finally {
- lock.writeLock().unlock();
+ db.commitTransaction(txn);
+ } catch (DbException e) {
+ db.abortTransaction(txn);
+ throw e;
}
if (!affected.isEmpty())
eventBus.broadcast(new GroupVisibilityUpdatedEvent(affected));
@@ -1249,24 +976,19 @@ class DatabaseComponentImpl implements DatabaseComponent {
public void setVisibleToContact(ContactId c, GroupId g, boolean visible)
throws DbException {
boolean wasVisible = false;
- lock.writeLock().lock();
+ T txn = db.startTransaction();
try {
- T txn = db.startTransaction();
- try {
- if (!db.containsContact(txn, c))
- throw new NoSuchContactException();
- if (!db.containsGroup(txn, g))
- throw new NoSuchGroupException();
- wasVisible = db.containsVisibleGroup(txn, c, g);
- if (visible && !wasVisible) db.addVisibility(txn, c, g);
- else if (!visible && wasVisible) db.removeVisibility(txn, c, g);
- db.commitTransaction(txn);
- } catch (DbException e) {
- db.abortTransaction(txn);
- throw e;
- }
- } finally {
- lock.writeLock().unlock();
+ if (!db.containsContact(txn, c))
+ throw new NoSuchContactException();
+ if (!db.containsGroup(txn, g))
+ throw new NoSuchGroupException();
+ wasVisible = db.containsVisibleGroup(txn, c, g);
+ if (visible && !wasVisible) db.addVisibility(txn, c, g);
+ else if (!visible && wasVisible) db.removeVisibility(txn, c, g);
+ db.commitTransaction(txn);
+ } catch (DbException e) {
+ db.abortTransaction(txn);
+ throw e;
}
if (visible != wasVisible) {
eventBus.broadcast(new GroupVisibilityUpdatedEvent(
@@ -1276,28 +998,23 @@ class DatabaseComponentImpl implements DatabaseComponent {
public void updateTransportKeys(Map keys)
throws DbException {
- lock.writeLock().lock();
+ T txn = db.startTransaction();
try {
- T txn = db.startTransaction();
- try {
- Map filtered =
- new HashMap();
- for (Entry e : keys.entrySet()) {
- ContactId c = e.getKey();
- TransportKeys k = e.getValue();
- if (db.containsContact(txn, c)
- && db.containsTransport(txn, k.getTransportId())) {
- filtered.put(c, k);
- }
+ Map filtered =
+ new HashMap();
+ for (Entry e : keys.entrySet()) {
+ ContactId c = e.getKey();
+ TransportKeys k = e.getValue();
+ if (db.containsContact(txn, c)
+ && db.containsTransport(txn, k.getTransportId())) {
+ filtered.put(c, k);
}
- db.updateTransportKeys(txn, filtered);
- db.commitTransaction(txn);
- } catch (DbException e) {
- db.abortTransaction(txn);
- throw e;
}
- } finally {
- lock.writeLock().unlock();
+ db.updateTransportKeys(txn, filtered);
+ db.commitTransaction(txn);
+ } catch (DbException e) {
+ db.abortTransaction(txn);
+ throw e;
}
}
}
diff --git a/briar-core/src/org/briarproject/db/JdbcDatabase.java b/briar-core/src/org/briarproject/db/JdbcDatabase.java
index ac583594b..b1b536d7f 100644
--- a/briar-core/src/org/briarproject/db/JdbcDatabase.java
+++ b/briar-core/src/org/briarproject/db/JdbcDatabase.java
@@ -41,7 +41,6 @@ import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
-import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
@@ -228,8 +227,6 @@ abstract class JdbcDatabase implements Database {
private final LinkedList connections =
new LinkedList(); // Locking: connectionsLock
- private final AtomicInteger transactionCount = new AtomicInteger(0);
-
private int openConnections = 0; // Locking: connectionsLock
private boolean closed = false; // Locking: connectionsLock
@@ -369,7 +366,6 @@ abstract class JdbcDatabase implements Database {
} catch (SQLException e) {
throw new DbException(e);
}
- transactionCount.incrementAndGet();
return txn;
}
@@ -418,14 +414,6 @@ abstract class JdbcDatabase implements Database {
}
}
- public int getTransactionCount() {
- return transactionCount.get();
- }
-
- public void resetTransactionCount() {
- transactionCount.set(0);
- }
-
protected void closeAllConnections() throws SQLException {
boolean interrupted = false;
connectionsLock.lock();