diff --git a/briar-api/src/net/sf/briar/api/db/event/SubscriptionsUpdatedEvent.java b/briar-api/src/net/sf/briar/api/db/event/LocalSubscriptionsUpdatedEvent.java similarity index 51% rename from briar-api/src/net/sf/briar/api/db/event/SubscriptionsUpdatedEvent.java rename to briar-api/src/net/sf/briar/api/db/event/LocalSubscriptionsUpdatedEvent.java index 2f878438b655a0d3adff422a67789671b3edf30d..a0114cee024118ea410c294a84259b1e913177ca 100644 --- a/briar-api/src/net/sf/briar/api/db/event/SubscriptionsUpdatedEvent.java +++ b/briar-api/src/net/sf/briar/api/db/event/LocalSubscriptionsUpdatedEvent.java @@ -9,20 +9,20 @@ import net.sf.briar.api.ContactId; * An event that is broadcast when the set of subscriptions visible to one or * more contacts is updated. */ -public class SubscriptionsUpdatedEvent extends DatabaseEvent { +public class LocalSubscriptionsUpdatedEvent extends DatabaseEvent { - private final Collection<ContactId> affectedContacts; + private final Collection<ContactId> affected; - public SubscriptionsUpdatedEvent() { - affectedContacts = Collections.emptyList(); + public LocalSubscriptionsUpdatedEvent() { + affected = Collections.emptyList(); } - public SubscriptionsUpdatedEvent(Collection<ContactId> affectedContacts) { - this.affectedContacts = affectedContacts; + public LocalSubscriptionsUpdatedEvent(Collection<ContactId> affected) { + this.affected = affected; } /** Returns the contacts affected by the update. */ public Collection<ContactId> getAffectedContacts() { - return affectedContacts; + return affected; } } diff --git a/briar-api/src/net/sf/briar/api/db/event/TransportsUpdatedEvent.java b/briar-api/src/net/sf/briar/api/db/event/LocalTransportsUpdatedEvent.java similarity index 66% rename from briar-api/src/net/sf/briar/api/db/event/TransportsUpdatedEvent.java rename to briar-api/src/net/sf/briar/api/db/event/LocalTransportsUpdatedEvent.java index 782b11cfe7f2cbbadd68cf61dc25a3106e069cf0..c60c23b83b1000df6d6b7d933bbb8f2822abfb2e 100644 --- a/briar-api/src/net/sf/briar/api/db/event/TransportsUpdatedEvent.java +++ b/briar-api/src/net/sf/briar/api/db/event/LocalTransportsUpdatedEvent.java @@ -4,6 +4,6 @@ package net.sf.briar.api.db.event; * An event that is broadcast when the local transport properties are * updated. */ -public class TransportsUpdatedEvent extends DatabaseEvent { +public class LocalTransportsUpdatedEvent extends DatabaseEvent { } diff --git a/briar-api/src/net/sf/briar/api/db/event/RemoteSubscriptionsUpdatedEvent.java b/briar-api/src/net/sf/briar/api/db/event/RemoteSubscriptionsUpdatedEvent.java new file mode 100644 index 0000000000000000000000000000000000000000..54436e52e4d0e15a3daf07b4a78bea4bf6c15a1a --- /dev/null +++ b/briar-api/src/net/sf/briar/api/db/event/RemoteSubscriptionsUpdatedEvent.java @@ -0,0 +1,17 @@ +package net.sf.briar.api.db.event; + +import net.sf.briar.api.ContactId; + +/** An event that is broadcast when a contact's subscriptions are updated. */ +public class RemoteSubscriptionsUpdatedEvent extends DatabaseEvent { + + private final ContactId contactId; + + public RemoteSubscriptionsUpdatedEvent(ContactId contactId) { + this.contactId = contactId; + } + + public ContactId getContactId() { + return contactId; + } +} diff --git a/briar-api/src/net/sf/briar/api/db/event/RemoteTransportsUpdatedEvent.java b/briar-api/src/net/sf/briar/api/db/event/RemoteTransportsUpdatedEvent.java new file mode 100644 index 0000000000000000000000000000000000000000..6458ad54bd869f1763b919eb8e3dc18087455111 --- /dev/null +++ b/briar-api/src/net/sf/briar/api/db/event/RemoteTransportsUpdatedEvent.java @@ -0,0 +1,28 @@ +package net.sf.briar.api.db.event; + +import net.sf.briar.api.ContactId; +import net.sf.briar.api.protocol.TransportId; + +/** + * An event that is broadcast when a contact's remote transport properties + * are updated. + */ +public class RemoteTransportsUpdatedEvent extends DatabaseEvent { + + private final ContactId contactId; + private final TransportId transportId; + + public RemoteTransportsUpdatedEvent(ContactId contactId, + TransportId transportId) { + this.contactId = contactId; + this.transportId = transportId; + } + + public ContactId getContactId() { + return contactId; + } + + public TransportId getTransportId() { + return transportId; + } +} diff --git a/briar-api/src/net/sf/briar/api/db/event/TransportAddedEvent.java b/briar-api/src/net/sf/briar/api/db/event/TransportAddedEvent.java new file mode 100644 index 0000000000000000000000000000000000000000..75156882292478155b0ef2b3c29e30511c5e6f8b --- /dev/null +++ b/briar-api/src/net/sf/briar/api/db/event/TransportAddedEvent.java @@ -0,0 +1,17 @@ +package net.sf.briar.api.db.event; + +import net.sf.briar.api.protocol.TransportId; + +/** An event that is broadcast when a transport is added. */ +public class TransportAddedEvent extends DatabaseEvent { + + private final TransportId transportId; + + public TransportAddedEvent(TransportId transportId) { + this.transportId = transportId; + } + + public TransportId getTransportId() { + return transportId; + } +} diff --git a/briar-api/src/net/sf/briar/api/db/event/TransportRemovedEvent.java b/briar-api/src/net/sf/briar/api/db/event/TransportRemovedEvent.java new file mode 100644 index 0000000000000000000000000000000000000000..2b7dd98a267a578282ed6ff6244cf22ccdc5e490 --- /dev/null +++ b/briar-api/src/net/sf/briar/api/db/event/TransportRemovedEvent.java @@ -0,0 +1,17 @@ +package net.sf.briar.api.db.event; + +import net.sf.briar.api.protocol.TransportId; + +/** An event that is broadcast when a transport is removed. */ +public class TransportRemovedEvent extends DatabaseEvent { + + private final TransportId transportId; + + public TransportRemovedEvent(TransportId transportId) { + this.transportId = transportId; + } + + public TransportId getTransportId() { + return transportId; + } +} diff --git a/briar-core/src/net/sf/briar/db/Database.java b/briar-core/src/net/sf/briar/db/Database.java index 229e912b63d6059df561e6dac5340c504d309e5a..98f4b0adb45d575c7514f1511021072e2c103867 100644 --- a/briar-core/src/net/sf/briar/db/Database.java +++ b/briar-core/src/net/sf/briar/db/Database.java @@ -31,12 +31,10 @@ import net.sf.briar.api.transport.TemporarySecret; * {@link #commitTransaction(T)}, even if an exception is thrown. * <p> * Locking is provided by the DatabaseComponent implementation. To prevent - * deadlock, locks must be acquired in the following order: + * deadlock, locks must be acquired in the following (alphabetical) order: * <ul> * <li> contact * <li> message - * <li> messageFlag - * <li> messageStatus * <li> rating * <li> subscription * <li> transport @@ -83,7 +81,7 @@ interface Database<T> { /** * Adds a contact transport to the database. * <p> - * Locking: contact read, window write. + * Locking: contact read, transport read, window write. */ void addContactTransport(T txn, ContactTransport ct) throws DbException; @@ -98,14 +96,14 @@ interface Database<T> { /** * Records a received message as needing to be acknowledged. * <p> - * Locking: contact read, messageStatus write. + * Locking: contact read, message write. */ void addMessageToAck(T txn, ContactId c, MessageId m) throws DbException; /** * Records a collection of sent messages as needing to be acknowledged. * <p> - * Locking: contact read, message read, messageStatus write. + * Locking: contact read, message write. */ void addOutstandingMessages(T txn, ContactId c, Collection<MessageId> sent) throws DbException; @@ -122,7 +120,7 @@ interface Database<T> { * Stores the given temporary secrets and deletes any secrets that have * been made obsolete. * <p> - * Locking: contact read, window write. + * Locking: contact read, transport read, window write. */ void addSecrets(T txn, Collection<TemporarySecret> secrets) throws DbException; @@ -158,7 +156,7 @@ interface Database<T> { /** * Returns true if the database contains the given contact transport. * <p> - * Locking: contact read, window read. + * Locking: contact read, transport read, window read. */ boolean containsContactTransport(T txn, ContactId c, TransportId t) throws DbException; @@ -203,7 +201,7 @@ interface Database<T> { /** * Returns all contact transports. * <p> - * Locking: contact read, window read. + * Locking: contact read, transport read, window read. */ Collection<ContactTransport> getContactTransports(T txn) throws DbException; @@ -257,7 +255,7 @@ interface Database<T> { /** * Returns the headers of all messages in the given group. * <p> - * Locking: message read, messageFlag read. + * Locking: message read. */ Collection<MessageHeader> getMessageHeaders(T txn, GroupId g) throws DbException; @@ -267,8 +265,7 @@ interface Database<T> { * if the message is not present in the database or is not sendable to the * given contact. * <p> - * Locking: contact read, message read, messageStatus read, - * subscription read. + * Locking: contact read, message read, subscription read. */ byte[] getMessageIfSendable(T txn, ContactId c, MessageId m) throws DbException; @@ -285,7 +282,7 @@ interface Database<T> { * Returns the IDs of some messages received from the given contact that * need to be acknowledged, up to the given number of messages. * <p> - * Locking: contact read, messageStatus read. + * Locking: contact read, message read. */ Collection<MessageId> getMessagesToAck(T txn, ContactId c, int maxMessages) throws DbException; @@ -294,8 +291,7 @@ interface Database<T> { * Returns the IDs of some messages that are eligible to be sent to the * given contact, up to the given number of messages. * <p> - * Locking: contact read, message read, messageStatus read, - * subscription read. + * Locking: contact read, message read, subscription read. */ Collection<MessageId> getMessagesToOffer(T txn, ContactId c, int maxMessages) throws DbException; @@ -327,7 +323,7 @@ interface Database<T> { /** * Returns true if the given message has been read. * <p> - * Locking: message read, messageFlag read. + * Locking: message read. */ boolean getReadFlag(T txn, MessageId m) throws DbException; @@ -342,7 +338,7 @@ interface Database<T> { /** * Returns all temporary secrets. * <p> - * Locking: contact read, window read. + * Locking: contact read, transport read, window read. */ Collection<TemporarySecret> getSecrets(T txn) throws DbException; @@ -358,8 +354,7 @@ interface Database<T> { * given contact, with a total length less than or equal to the given * length. * <p> - * Locking: contact read, message read, messageStatus read, - * subscription read. + * Locking: contact read, message read, subscription read. */ Collection<MessageId> getSendableMessages(T txn, ContactId c, int maxLength) throws DbException; @@ -367,7 +362,7 @@ interface Database<T> { /** * Returns true if the given message has been starred. * <p> - * Locking: message read, messageFlag read. + * Locking: message read. */ boolean getStarredFlag(T txn, MessageId m) throws DbException; @@ -425,7 +420,7 @@ interface Database<T> { /** * Returns the number of unread messages in each subscribed group. * <p> - * Locking: message read, messageFlag read, subscription read. + * Locking: message read, subscription read. */ Map<GroupId, Integer> getUnreadMessageCounts(T txn) throws DbException; @@ -439,7 +434,7 @@ interface Database<T> { /** * Returns true if any messages are sendable to the given contact. * <p> - * Locking: contact read, message read, messageStatus read. + * Locking: contact read, message read. */ boolean hasSendableMessages(T txn, ContactId c) throws DbException; @@ -447,7 +442,7 @@ interface Database<T> { * Increments the outgoing connection counter for the given contact * transport in the given rotation period and returns the old value; * <p> - * Locking: contact read, window write. + * Locking: contact read, transport read, window write. */ long incrementConnectionCounter(T txn, ContactId c, TransportId t, long period) throws DbException; @@ -471,53 +466,51 @@ interface Database<T> { throws DbException; /** - * Removes outstanding messages that have been acknowledged. Any of the - * messages that are still considered outstanding (Status.SENT) with - * respect to the given contact are now considered seen (Status.SEEN). + * Removes a contact (and all associated state) from the database. * <p> - * Locking: contact read, message read, messageStatus write. + * Locking: contact write, message write, subscription write, + * transport write, window write. */ - void removeOutstandingMessages(T txn, ContactId c, - Collection<MessageId> acked) throws DbException; + void removeContact(T txn, ContactId c) throws DbException; /** - * Marks the given messages received from the given contact as having been - * acknowledged. + * Removes a message (and all associated state) from the database. * <p> - * Locking: contact read, messageStatus write. + * Locking: contact read, message write. */ - void removeMessagesToAck(T txn, ContactId c, Collection<MessageId> acked) - throws DbException; + void removeMessage(T txn, MessageId m) throws DbException; /** - * Removes a contact (and all associated state) from the database. + * Marks the given messages received from the given contact as having been + * acknowledged. * <p> - * Locking: contact write, message write, messageFlag write, - * messageStatus write, subscription write, transport write, window write. + * Locking: contact read, message write. */ - void removeContact(T txn, ContactId c) throws DbException; + void removeMessagesToAck(T txn, ContactId c, Collection<MessageId> acked) + throws DbException; /** - * Removes a message (and all associated state) from the database. + * Removes outstanding messages that have been acknowledged. Any of the + * messages that are still considered outstanding (Status.SENT) with + * respect to the given contact are now considered seen (Status.SEEN). * <p> - * Locking: contact read, message write, messageFlag write, - * messageStatus write. + * Locking: contact read, message write. */ - void removeMessage(T txn, MessageId m) throws DbException; + void removeOutstandingMessages(T txn, ContactId c, + Collection<MessageId> acked) throws DbException; /** * Unsubscribes from the given group. Any messages belonging to the group * are deleted from the database. * <p> - * Locking: contact write, message write, messageFlag write, - * messageStatus write, subscription write. + * Locking: contact write, message write, subscription write. */ void removeSubscription(T txn, GroupId g) throws DbException; /** * Removes a transport (and all associated state) from the database. * <p> - * Locking: contact read, transport write. + * Locking: transport write. */ void removeTransport(T txn, TransportId t) throws DbException; @@ -532,7 +525,7 @@ interface Database<T> { * Sets the connection reordering window for the given contact transport in * the given rotation period. * <p> - * Locking: contact read, window write. + * Locking: contact read, transport read, window write. */ void setConnectionWindow(T txn, ContactId c, TransportId t, long period, long centre, byte[] bitmap) throws DbException; @@ -555,7 +548,7 @@ interface Database<T> { * Marks the given message read or unread and returns true if it was * previously read. * <p> - * Locking: message read, messageFlag write. + * Locking: message write. */ boolean setRead(T txn, MessageId m, boolean read) throws DbException; @@ -581,14 +574,14 @@ interface Database<T> { * Marks the given message starred or unstarred and returns true if it was * previously starred. * <p> - * Locking: message read, messageFlag write. + * Locking: message write. */ boolean setStarred(T txn, MessageId m, boolean starred) throws DbException; /** * Sets the status of the given message with respect to the given contact. * <p> - * Locking: contact read, message read, messageStatus write. + * Locking: contact read, message write. */ void setStatus(T txn, ContactId c, MessageId m, Status s) throws DbException; @@ -599,8 +592,7 @@ interface Database<T> { * with respect to the contact to Status.SEEN and returns true; otherwise * returns false. * <p> - * Locking: contact read, message read, messageStatus write, - * subscription read. + * Locking: contact read, message write, subscription read. */ boolean setStatusSeenIfVisible(T txn, ContactId c, MessageId m) throws DbException; diff --git a/briar-core/src/net/sf/briar/db/DatabaseComponentImpl.java b/briar-core/src/net/sf/briar/db/DatabaseComponentImpl.java index d1308b3b1acb7bfd6ab746c8cf50a48c120a76b6..0ab4bfc60cddb3a94ce1dbabb0343b325d8a80aa 100644 --- a/briar-core/src/net/sf/briar/db/DatabaseComponentImpl.java +++ b/briar-core/src/net/sf/briar/db/DatabaseComponentImpl.java @@ -34,11 +34,15 @@ import net.sf.briar.api.db.event.ContactAddedEvent; import net.sf.briar.api.db.event.ContactRemovedEvent; import net.sf.briar.api.db.event.DatabaseEvent; import net.sf.briar.api.db.event.DatabaseListener; +import net.sf.briar.api.db.event.LocalSubscriptionsUpdatedEvent; +import net.sf.briar.api.db.event.LocalTransportsUpdatedEvent; import net.sf.briar.api.db.event.MessageAddedEvent; import net.sf.briar.api.db.event.MessageReceivedEvent; import net.sf.briar.api.db.event.RatingChangedEvent; -import net.sf.briar.api.db.event.SubscriptionsUpdatedEvent; -import net.sf.briar.api.db.event.TransportsUpdatedEvent; +import net.sf.briar.api.db.event.RemoteSubscriptionsUpdatedEvent; +import net.sf.briar.api.db.event.RemoteTransportsUpdatedEvent; +import net.sf.briar.api.db.event.TransportAddedEvent; +import net.sf.briar.api.db.event.TransportRemovedEvent; import net.sf.briar.api.lifecycle.ShutdownManager; import net.sf.briar.api.protocol.Ack; import net.sf.briar.api.protocol.AuthorId; @@ -79,10 +83,6 @@ 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 = new ReentrantReadWriteLock(true); private final ReentrantReadWriteLock subscriptionLock = @@ -194,20 +194,25 @@ DatabaseCleaner.Callback { public void addContactTransport(ContactTransport ct) throws DbException { contactLock.readLock().lock(); try { - windowLock.writeLock().lock(); + transportLock.readLock().lock(); try { - T txn = db.startTransaction(); + windowLock.writeLock().lock(); try { - if(!db.containsContact(txn, ct.getContactId())) - throw new NoSuchContactException(); - db.addContactTransport(txn, ct); - db.commitTransaction(txn); - } catch(DbException e) { - db.abortTransaction(txn); - throw e; + T txn = db.startTransaction(); + try { + if(!db.containsContact(txn, ct.getContactId())) + throw new NoSuchContactException(); + db.addContactTransport(txn, ct); + db.commitTransaction(txn); + } catch(DbException e) { + db.abortTransaction(txn); + throw e; + } + } finally { + windowLock.writeLock().unlock(); } } finally { - windowLock.writeLock().unlock(); + transportLock.readLock().unlock(); } } finally { contactLock.readLock().unlock(); @@ -220,26 +225,21 @@ DatabaseCleaner.Callback { try { messageLock.writeLock().lock(); try { - messageStatusLock.writeLock().lock(); + subscriptionLock.readLock().lock(); try { - subscriptionLock.readLock().lock(); + T txn = db.startTransaction(); try { - T txn = db.startTransaction(); - try { - // Don't store the message if the user has - // unsubscribed from the group - if(db.containsSubscription(txn, m.getGroup())) - added = storeGroupMessage(txn, m, null); - db.commitTransaction(txn); - } catch(DbException e) { - db.abortTransaction(txn); - throw e; - } - } finally { - subscriptionLock.readLock().unlock(); + // Don't store the message if the user has + // unsubscribed from the group + if(db.containsSubscription(txn, m.getGroup())) + added = storeGroupMessage(txn, m, null); + db.commitTransaction(txn); + } catch(DbException e) { + db.abortTransaction(txn); + throw e; } } finally { - messageStatusLock.writeLock().unlock(); + subscriptionLock.readLock().unlock(); } } finally { messageLock.writeLock().unlock(); @@ -257,7 +257,7 @@ DatabaseCleaner.Callback { * sendability of its ancestors if necessary, marks the message as seen by * the sender and unseen by all other contacts, and returns true. * <p> - * Locking: contact read, message write, messageStatus write. + * Locking: contact read, message write. * @param sender may be null for a locally generated message. */ private boolean storeGroupMessage(T txn, Message m, ContactId sender) @@ -344,20 +344,15 @@ DatabaseCleaner.Callback { try { messageLock.writeLock().lock(); try { - messageStatusLock.writeLock().lock(); + T txn = db.startTransaction(); try { - T txn = db.startTransaction(); - try { - if(!db.containsContact(txn, c)) - throw new NoSuchContactException(); - added = storePrivateMessage(txn, m, c, false); - db.commitTransaction(txn); - } catch(DbException e) { - db.abortTransaction(txn); - throw e; - } - } finally { - messageStatusLock.writeLock().unlock(); + if(!db.containsContact(txn, c)) + throw new NoSuchContactException(); + added = storePrivateMessage(txn, m, c, false); + db.commitTransaction(txn); + } catch(DbException e) { + db.abortTransaction(txn); + throw e; } } finally { messageLock.writeLock().unlock(); @@ -373,26 +368,31 @@ DatabaseCleaner.Callback { throws DbException { contactLock.readLock().lock(); try { - windowLock.writeLock().lock(); + transportLock.readLock().lock(); try { - T txn = db.startTransaction(); + windowLock.writeLock().lock(); try { - Collection<TemporarySecret> relevant = - new ArrayList<TemporarySecret>(); - for(TemporarySecret s : secrets) { - ContactId c = s.getContactId(); - TransportId t = s.getTransportId(); - if(db.containsContactTransport(txn, c, t)) - relevant.add(s); + T txn = db.startTransaction(); + try { + Collection<TemporarySecret> relevant = + new ArrayList<TemporarySecret>(); + for(TemporarySecret s : secrets) { + ContactId c = s.getContactId(); + TransportId t = s.getTransportId(); + if(db.containsContactTransport(txn, c, t)) + relevant.add(s); + } + if(!secrets.isEmpty()) db.addSecrets(txn, relevant); + db.commitTransaction(txn); + } catch(DbException e) { + db.abortTransaction(txn); + throw e; } - if(!secrets.isEmpty()) db.addSecrets(txn, relevant); - db.commitTransaction(txn); - } catch(DbException e) { - db.abortTransaction(txn); - throw e; + } finally { + windowLock.writeLock().unlock(); } } finally { - windowLock.writeLock().unlock(); + transportLock.readLock().unlock(); } } finally { contactLock.readLock().unlock(); @@ -413,6 +413,8 @@ DatabaseCleaner.Callback { } finally { transportLock.writeLock().unlock(); } + // Call the listeners outside the lock + callListeners(new TransportAddedEvent(t)); } /** @@ -421,7 +423,7 @@ DatabaseCleaner.Callback { * incoming, respectively; or returns false if the message is already in * the database. * <p> - * Locking: contact read, message write, messageStatus write. + * Locking: contact read, message write. */ private boolean storePrivateMessage(T txn, Message m, ContactId c, boolean incoming) throws DbException { @@ -442,7 +444,7 @@ DatabaseCleaner.Callback { Collection<MessageId> acked; contactLock.readLock().lock(); try { - messageStatusLock.readLock().lock(); + messageLock.readLock().lock(); try { T txn = db.startTransaction(); try { @@ -455,11 +457,11 @@ DatabaseCleaner.Callback { throw e; } } finally { - messageStatusLock.readLock().unlock(); + messageLock.readLock().unlock(); } if(acked.isEmpty()) return null; // Record the contents of the ack - messageStatusLock.writeLock().lock(); + messageLock.writeLock().lock(); try { T txn = db.startTransaction(); try { @@ -470,7 +472,7 @@ DatabaseCleaner.Callback { throw e; } } finally { - messageStatusLock.writeLock().unlock(); + messageLock.writeLock().unlock(); } } finally { contactLock.readLock().unlock(); @@ -487,45 +489,41 @@ DatabaseCleaner.Callback { try { messageLock.readLock().lock(); try { - messageStatusLock.readLock().lock(); - try { - subscriptionLock.readLock().lock(); - try { - T txn = db.startTransaction(); - try { - if(!db.containsContact(txn, c)) - throw new NoSuchContactException(); - ids = db.getSendableMessages(txn, c, maxLength); - for(MessageId m : ids) { - messages.add(db.getMessage(txn, m)); - } - db.commitTransaction(txn); - } catch(DbException e) { - db.abortTransaction(txn); - throw e; - } - } finally { - subscriptionLock.readLock().unlock(); - } - } finally { - messageStatusLock.readLock().unlock(); - } - if(messages.isEmpty()) return null; - messageStatusLock.writeLock().lock(); + subscriptionLock.readLock().lock(); try { T txn = db.startTransaction(); try { - db.addOutstandingMessages(txn, c, ids); + if(!db.containsContact(txn, c)) + throw new NoSuchContactException(); + ids = db.getSendableMessages(txn, c, maxLength); + for(MessageId m : ids) { + messages.add(db.getMessage(txn, m)); + } db.commitTransaction(txn); } catch(DbException e) { db.abortTransaction(txn); throw e; } } finally { - messageStatusLock.writeLock().unlock(); + subscriptionLock.readLock().unlock(); } } finally { - messageLock.readLock().unlock(); + messageLock.readLock().lock(); + } + if(messages.isEmpty()) return null; + // Record the message as sent + messageLock.writeLock().lock(); + try { + T txn = db.startTransaction(); + try { + db.addOutstandingMessages(txn, c, ids); + db.commitTransaction(txn); + } catch(DbException e) { + db.abortTransaction(txn); + throw e; + } + } finally { + messageLock.writeLock().unlock(); } } finally { contactLock.readLock().unlock(); @@ -542,54 +540,50 @@ DatabaseCleaner.Callback { try { messageLock.readLock().lock(); try { - messageStatusLock.readLock().lock(); - try{ - subscriptionLock.readLock().lock(); - try { - T txn = db.startTransaction(); - try { - if(!db.containsContact(txn, c)) - throw new NoSuchContactException(); - Iterator<MessageId> it = requested.iterator(); - while(it.hasNext()) { - MessageId m = it.next(); - byte[] raw = db.getMessageIfSendable(txn, c, m); - if(raw != null) { - if(raw.length > maxLength) break; - messages.add(raw); - ids.add(m); - maxLength -= raw.length; - } - it.remove(); - } - db.commitTransaction(txn); - } catch(DbException e) { - db.abortTransaction(txn); - throw e; - } - } finally { - subscriptionLock.readLock().unlock(); - } - } finally { - messageStatusLock.readLock().unlock(); - } - if(messages.isEmpty()) return null; - messageStatusLock.writeLock().lock(); + subscriptionLock.readLock().lock(); try { T txn = db.startTransaction(); try { - db.addOutstandingMessages(txn, c, ids); + if(!db.containsContact(txn, c)) + throw new NoSuchContactException(); + Iterator<MessageId> it = requested.iterator(); + while(it.hasNext()) { + MessageId m = it.next(); + byte[] raw = db.getMessageIfSendable(txn, c, m); + if(raw != null) { + if(raw.length > maxLength) break; + messages.add(raw); + ids.add(m); + maxLength -= raw.length; + } + it.remove(); + } db.commitTransaction(txn); } catch(DbException e) { db.abortTransaction(txn); throw e; } } finally { - messageStatusLock.writeLock().unlock(); + subscriptionLock.readLock().unlock(); } } finally { messageLock.readLock().unlock(); } + if(messages.isEmpty()) return null; + // Record the messages as sent + messageLock.writeLock().lock(); + try { + T txn = db.startTransaction(); + try { + db.addOutstandingMessages(txn, c, ids); + db.commitTransaction(txn); + } catch(DbException e) { + db.abortTransaction(txn); + throw e; + } + } finally { + messageLock.writeLock().unlock(); + } } finally { contactLock.readLock().unlock(); } @@ -603,20 +597,15 @@ DatabaseCleaner.Callback { try { messageLock.readLock().lock(); try { - messageStatusLock.readLock().lock(); + T txn = db.startTransaction(); try { - T txn = db.startTransaction(); - try { - if(!db.containsContact(txn, c)) - throw new NoSuchContactException(); - offered = db.getMessagesToOffer(txn, c, maxMessages); - db.commitTransaction(txn); - } catch(DbException e) { - db.abortTransaction(txn); - throw e; - } - } finally { - messageStatusLock.readLock().unlock(); + if(!db.containsContact(txn, c)) + throw new NoSuchContactException(); + offered = db.getMessagesToOffer(txn, c, maxMessages); + db.commitTransaction(txn); + } catch(DbException e) { + db.abortTransaction(txn); + throw e; } } finally { messageLock.readLock().unlock(); @@ -780,20 +769,15 @@ DatabaseCleaner.Callback { throws DbException { messageLock.readLock().lock(); try { - messageFlagLock.readLock().lock(); + T txn = db.startTransaction(); try { - T txn = db.startTransaction(); - try { - Collection<MessageHeader> headers = - db.getMessageHeaders(txn, g); - db.commitTransaction(txn); - return headers; - } catch(DbException e) { - db.abortTransaction(txn); - throw e; - } - } finally { - messageFlagLock.readLock().unlock(); + Collection<MessageHeader> headers = + db.getMessageHeaders(txn, g); + db.commitTransaction(txn); + return headers; + } catch(DbException e) { + db.abortTransaction(txn); + throw e; } } finally { messageLock.readLock().unlock(); @@ -844,19 +828,25 @@ DatabaseCleaner.Callback { public Collection<TemporarySecret> getSecrets() throws DbException { contactLock.readLock().lock(); try { - windowLock.readLock().lock(); + transportLock.readLock().lock(); try { - T txn = db.startTransaction(); + windowLock.readLock().lock(); try { - Collection<TemporarySecret> secrets = db.getSecrets(txn); - db.commitTransaction(txn); - return secrets; - } catch(DbException e) { - db.abortTransaction(txn); - throw e; + T txn = db.startTransaction(); + try { + Collection<TemporarySecret> secrets = + db.getSecrets(txn); + db.commitTransaction(txn); + return secrets; + } catch(DbException e) { + db.abortTransaction(txn); + throw e; + } + } finally { + windowLock.readLock().unlock(); } } finally { - windowLock.readLock().unlock(); + transportLock.readLock().unlock(); } } finally { contactLock.readLock().unlock(); @@ -883,25 +873,20 @@ DatabaseCleaner.Callback { public Map<GroupId, Integer> getUnreadMessageCounts() throws DbException { messageLock.readLock().lock(); try { - messageFlagLock.readLock().lock(); + subscriptionLock.readLock().lock(); try { - subscriptionLock.readLock().lock(); + T txn = db.startTransaction(); try { - T txn = db.startTransaction(); - try { - Map<GroupId, Integer> counts = - db.getUnreadMessageCounts(txn); - db.commitTransaction(txn); - return counts; - } catch(DbException e) { - db.abortTransaction(txn); - throw e; - } - } finally { - subscriptionLock.readLock().unlock(); + Map<GroupId, Integer> counts = + db.getUnreadMessageCounts(txn); + db.commitTransaction(txn); + return counts; + } catch(DbException e) { + db.abortTransaction(txn); + throw e; } } finally { - messageFlagLock.readLock().unlock(); + subscriptionLock.readLock().unlock(); } } finally { messageLock.readLock().unlock(); @@ -935,26 +920,21 @@ DatabaseCleaner.Callback { try { messageLock.readLock().lock(); try { - messageStatusLock.readLock().lock(); + subscriptionLock.readLock().lock(); try { - subscriptionLock.readLock().lock(); + T txn = db.startTransaction(); try { - T txn = db.startTransaction(); - try { - if(!db.containsContact(txn, c)) - throw new NoSuchContactException(); - boolean has = db.hasSendableMessages(txn, c); - db.commitTransaction(txn); - return has; - } catch(DbException e) { - db.abortTransaction(txn); - throw e; - } - } finally { - subscriptionLock.readLock().unlock(); + if(!db.containsContact(txn, c)) + throw new NoSuchContactException(); + boolean has = db.hasSendableMessages(txn, c); + db.commitTransaction(txn); + return has; + } catch(DbException e) { + db.abortTransaction(txn); + throw e; } } finally { - messageStatusLock.readLock().unlock(); + subscriptionLock.readLock().unlock(); } } finally { messageLock.readLock().unlock(); @@ -968,21 +948,27 @@ DatabaseCleaner.Callback { long period) throws DbException { contactLock.readLock().lock(); try { - windowLock.writeLock().lock(); + transportLock.readLock().lock(); try { - T txn = db.startTransaction(); + windowLock.writeLock().lock(); try { - if(!db.containsContactTransport(txn, c, t)) - throw new NoSuchContactTransportException(); - long l = db.incrementConnectionCounter(txn, c, t, period); - db.commitTransaction(txn); - return l; - } catch(DbException e) { - db.abortTransaction(txn); - throw e; + T txn = db.startTransaction(); + try { + if(!db.containsContactTransport(txn, c, t)) + throw new NoSuchContactTransportException(); + long counter = db.incrementConnectionCounter(txn, c, t, + period); + db.commitTransaction(txn); + return counter; + } catch(DbException e) { + db.abortTransaction(txn); + throw e; + } + } finally { + windowLock.writeLock().unlock(); } } finally { - windowLock.writeLock().unlock(); + transportLock.readLock().unlock(); } } finally { contactLock.readLock().unlock(); @@ -1026,31 +1012,26 @@ DatabaseCleaner.Callback { transportLock.writeLock().unlock(); } // Call the listeners outside the lock - if(changed) callListeners(new TransportsUpdatedEvent()); + if(changed) callListeners(new LocalTransportsUpdatedEvent()); } public void receiveAck(ContactId c, Ack a) throws DbException { contactLock.readLock().lock(); try { - messageLock.readLock().lock(); + messageLock.writeLock().lock(); try { - messageStatusLock.writeLock().lock(); + T txn = db.startTransaction(); try { - T txn = db.startTransaction(); - try { - if(!db.containsContact(txn, c)) - throw new NoSuchContactException(); - db.removeOutstandingMessages(txn, c, a.getMessageIds()); - db.commitTransaction(txn); - } catch(DbException e) { - db.abortTransaction(txn); - throw e; - } - } finally { - messageStatusLock.writeLock().unlock(); + if(!db.containsContact(txn, c)) + throw new NoSuchContactException(); + db.removeOutstandingMessages(txn, c, a.getMessageIds()); + db.commitTransaction(txn); + } catch(DbException e) { + db.abortTransaction(txn); + throw e; } } finally { - messageLock.readLock().unlock(); + messageLock.writeLock().unlock(); } } finally { contactLock.readLock().unlock(); @@ -1063,26 +1044,21 @@ DatabaseCleaner.Callback { try { messageLock.writeLock().lock(); try { - messageStatusLock.writeLock().lock(); + subscriptionLock.readLock().lock(); try { - subscriptionLock.readLock().lock(); + T txn = db.startTransaction(); try { - T txn = db.startTransaction(); - try { - if(!db.containsContact(txn, c)) - throw new NoSuchContactException(); - added = storeMessage(txn, c, m); - db.addMessageToAck(txn, c, m.getId()); - db.commitTransaction(txn); - } catch(DbException e) { - db.abortTransaction(txn); - throw e; - } - } finally { - subscriptionLock.readLock().unlock(); + if(!db.containsContact(txn, c)) + throw new NoSuchContactException(); + added = storeMessage(txn, c, m); + db.addMessageToAck(txn, c, m.getId()); + db.commitTransaction(txn); + } catch(DbException e) { + db.abortTransaction(txn); + throw e; } } finally { - messageStatusLock.writeLock().unlock(); + subscriptionLock.readLock().unlock(); } } finally { messageLock.writeLock().unlock(); @@ -1099,8 +1075,7 @@ DatabaseCleaner.Callback { * Attempts to store a message received from the given contact, and returns * true if it was stored. * <p> - * Locking: contact read, message write, messageStatus write, - * subscription read. + * Locking: contact read, message write, subscription read. */ private boolean storeMessage(T txn, ContactId c, Message m) throws DbException { @@ -1115,39 +1090,34 @@ DatabaseCleaner.Callback { BitSet request; contactLock.readLock().lock(); try { - messageLock.readLock().lock(); + messageLock.writeLock().lock(); try { - messageStatusLock.writeLock().lock(); + subscriptionLock.readLock().lock(); try { - subscriptionLock.readLock().lock(); + T txn = db.startTransaction(); try { - T txn = db.startTransaction(); - try { - if(!db.containsContact(txn, c)) - throw new NoSuchContactException(); - offered = o.getMessageIds(); - request = new BitSet(offered.size()); - Iterator<MessageId> it = offered.iterator(); - for(int i = 0; it.hasNext(); i++) { - // If the message is not in the database, or if - // it is not visible to the contact, request it - MessageId m = it.next(); - if(!db.setStatusSeenIfVisible(txn, c, m)) - request.set(i); - } - db.commitTransaction(txn); - } catch(DbException e) { - db.abortTransaction(txn); - throw e; + if(!db.containsContact(txn, c)) + throw new NoSuchContactException(); + offered = o.getMessageIds(); + request = new BitSet(offered.size()); + Iterator<MessageId> it = offered.iterator(); + for(int i = 0; it.hasNext(); i++) { + // If the message is not in the database, or not + // visible to the contact, request it + MessageId m = it.next(); + if(!db.setStatusSeenIfVisible(txn, c, m)) + request.set(i); } - } finally { - subscriptionLock.readLock().unlock(); + db.commitTransaction(txn); + } catch(DbException e) { + db.abortTransaction(txn); + throw e; } } finally { - messageStatusLock.writeLock().unlock(); + subscriptionLock.readLock().unlock(); } } finally { - messageLock.readLock().unlock(); + messageLock.writeLock().unlock(); } } finally { contactLock.readLock().unlock(); @@ -1165,8 +1135,7 @@ DatabaseCleaner.Callback { try { if(!db.containsContact(txn, c)) throw new NoSuchContactException(); - long version = a.getVersionNumber(); - db.setSubscriptionUpdateAcked(txn, c, version); + db.setSubscriptionUpdateAcked(txn, c, a.getVersionNumber()); db.commitTransaction(txn); } catch(DbException e) { db.abortTransaction(txn); @@ -1202,6 +1171,8 @@ DatabaseCleaner.Callback { } finally { contactLock.readLock().unlock(); } + // Call the listeners outside the lock + callListeners(new RemoteSubscriptionsUpdatedEvent(c)); } public void receiveTransportAck(ContactId c, TransportAck a) @@ -1215,8 +1186,7 @@ DatabaseCleaner.Callback { if(!db.containsContact(txn, c)) throw new NoSuchContactException(); TransportId t = a.getId(); - long version = a.getVersionNumber(); - db.setTransportUpdateAcked(txn, c, t, version); + db.setTransportUpdateAcked(txn, c, t, a.getVersionNumber()); db.commitTransaction(txn); } catch(DbException e) { db.abortTransaction(txn); @@ -1252,6 +1222,8 @@ DatabaseCleaner.Callback { } finally { contactLock.readLock().unlock(); } + // Call the listeners outside the lock + callListeners(new RemoteTransportsUpdatedEvent(c, t.getId())); } public void removeContact(ContactId c) throws DbException { @@ -1259,40 +1231,30 @@ DatabaseCleaner.Callback { try { messageLock.writeLock().lock(); try { - messageFlagLock.writeLock().lock(); + subscriptionLock.writeLock().lock(); try { - messageStatusLock.writeLock().lock(); + transportLock.writeLock().lock(); try { - subscriptionLock.writeLock().lock(); + windowLock.writeLock().lock(); try { - transportLock.writeLock().lock(); + T txn = db.startTransaction(); try { - windowLock.writeLock().lock(); - 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 { - windowLock.writeLock().unlock(); - } - } finally { - transportLock.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; } } finally { - subscriptionLock.writeLock().unlock(); + windowLock.writeLock().unlock(); } } finally { - messageStatusLock.writeLock().unlock(); + transportLock.writeLock().unlock(); } } finally { - messageFlagLock.writeLock().unlock(); + subscriptionLock.writeLock().unlock(); } } finally { messageLock.writeLock().unlock(); @@ -1304,24 +1266,48 @@ DatabaseCleaner.Callback { callListeners(new ContactRemovedEvent(c)); } + public void removeTransport(TransportId t) throws DbException { + transportLock.writeLock().lock(); + try { + T txn = db.startTransaction(); + try { + db.removeTransport(txn, t); + db.commitTransaction(txn); + } catch(DbException e) { + db.abortTransaction(txn); + throw e; + } + } finally { + transportLock.writeLock().unlock(); + } + // Call the listeners outside the lock + callListeners(new TransportRemovedEvent(t)); + } + public void setConnectionWindow(ContactId c, TransportId t, long period, long centre, byte[] bitmap) throws DbException { contactLock.readLock().lock(); try { - windowLock.writeLock().lock(); + transportLock.readLock().lock(); try { - T txn = db.startTransaction(); + windowLock.writeLock().lock(); try { - if(!db.containsContactTransport(txn, c, t)) - throw new NoSuchContactTransportException(); - db.setConnectionWindow(txn, c, t, period, centre, bitmap); - db.commitTransaction(txn); - } catch(DbException e) { - db.abortTransaction(txn); - throw e; + T txn = db.startTransaction(); + try { + if(!db.containsContactTransport(txn, c, t)) + throw new NoSuchContactTransportException(); + db.setConnectionWindow(txn, c, t, period, centre, + bitmap); + db.commitTransaction(txn); + } catch(DbException e) { + db.abortTransaction(txn); + throw e; + } + } finally { + windowLock.writeLock().unlock(); } } finally { - windowLock.writeLock().unlock(); + transportLock.readLock().unlock(); } } finally { contactLock.readLock().unlock(); @@ -1362,32 +1348,27 @@ DatabaseCleaner.Callback { throws DbException { contactLock.readLock().lock(); try { - messageLock.readLock().lock(); + messageLock.writeLock().lock(); try { - messageStatusLock.writeLock().lock(); + subscriptionLock.readLock().lock(); try { - subscriptionLock.readLock().lock(); + T txn = db.startTransaction(); try { - T txn = db.startTransaction(); - try { - if(!db.containsContact(txn, c)) - throw new NoSuchContactException(); - for(MessageId m : seen) { - db.setStatusSeenIfVisible(txn, c, m); - } - db.commitTransaction(txn); - } catch(DbException e) { - db.abortTransaction(txn); - throw e; + if(!db.containsContact(txn, c)) + throw new NoSuchContactException(); + for(MessageId m : seen) { + db.setStatusSeenIfVisible(txn, c, m); } - } finally { - subscriptionLock.readLock().unlock(); + db.commitTransaction(txn); + } catch(DbException e) { + db.abortTransaction(txn); + throw e; } } finally { - messageStatusLock.writeLock().unlock(); + subscriptionLock.readLock().unlock(); } } finally { - messageLock.readLock().unlock(); + messageLock.writeLock().unlock(); } } finally { contactLock.readLock().unlock(); @@ -1475,31 +1456,21 @@ DatabaseCleaner.Callback { try { messageLock.writeLock().lock(); try { - messageFlagLock.writeLock().lock(); + subscriptionLock.writeLock().lock(); try { - messageStatusLock.writeLock().lock(); + T txn = db.startTransaction(); try { - subscriptionLock.writeLock().lock(); - try { - 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; - } - } finally { - subscriptionLock.writeLock().unlock(); + if(db.containsSubscription(txn, g)) { + affected = db.getVisibility(txn, g); + db.removeSubscription(txn, g); } - } finally { - messageStatusLock.writeLock().unlock(); + db.commitTransaction(txn); + } catch(DbException e) { + db.abortTransaction(txn); + throw e; } } finally { - messageFlagLock.writeLock().unlock(); + subscriptionLock.writeLock().unlock(); } } finally { messageLock.writeLock().unlock(); @@ -1508,8 +1479,7 @@ DatabaseCleaner.Callback { contactLock.writeLock().unlock(); } // Call the listeners outside the lock - if(affected != null && !affected.isEmpty()) - callListeners(new SubscriptionsUpdatedEvent(affected)); + callListeners(new LocalSubscriptionsUpdatedEvent(affected)); } public void checkFreeSpaceAndClean() throws DbException { @@ -1537,24 +1507,14 @@ DatabaseCleaner.Callback { try { messageLock.writeLock().lock(); try { - messageFlagLock.writeLock().lock(); + T txn = db.startTransaction(); try { - messageStatusLock.writeLock().lock(); - try { - 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 { - messageFlagLock.writeLock().unlock(); + old = db.getOldMessages(txn, size); + for(MessageId m : old) removeMessage(txn, m); + db.commitTransaction(txn); + } catch(DbException e) { + db.abortTransaction(txn); + throw e; } } finally { messageLock.writeLock().unlock(); @@ -1568,7 +1528,7 @@ DatabaseCleaner.Callback { /** * Removes the given message (and all associated state) from the database. * <p> - * Locking: contact read, message write, messageStatus write. + * Locking: contact read, message write. */ private void removeMessage(T txn, MessageId m) throws DbException { int sendability = db.getSendability(txn, m); diff --git a/briar-core/src/net/sf/briar/db/JdbcDatabase.java b/briar-core/src/net/sf/briar/db/JdbcDatabase.java index 708595a0b22adef9b0baeec6b61d7807105d7017..a4263a62a012b1a6bd084912b5e015ae5c2f3ce4 100644 --- a/briar-core/src/net/sf/briar/db/JdbcDatabase.java +++ b/briar-core/src/net/sf/briar/db/JdbcDatabase.java @@ -92,7 +92,7 @@ abstract class JdbcDatabase implements Database<Connection> { private static final String INDEX_MESSAGES_BY_SENDABILITY = "CREATE INDEX messagesBySendability ON messages (sendability)"; - // Locking: contact read, messageStatus + // Locking: contact read, message private static final String CREATE_MESSAGES_TO_ACK = "CREATE TABLE messagesToAck" + " (messageId HASH NOT NULL," @@ -102,7 +102,7 @@ abstract class JdbcDatabase implements Database<Connection> { + " REFERENCES contacts (contactId)" + " ON DELETE CASCADE)"; - // Locking: contact read, message read, messageStatus + // Locking: contact read, message private static final String CREATE_STATUSES = "CREATE TABLE statuses" + " (messageId HASH NOT NULL," @@ -122,7 +122,7 @@ abstract class JdbcDatabase implements Database<Connection> { private static final String INDEX_STATUSES_BY_CONTACT = "CREATE INDEX statusesByContact ON statuses (contactId)"; - // Locking: message read, messageFlag + // Locking: message private static final String CREATE_FLAGS = "CREATE TABLE flags" + " (messageId HASH NOT NULL," @@ -252,7 +252,7 @@ abstract class JdbcDatabase implements Database<Connection> { + " REFERENCES contacts (contactId)" + " ON DELETE CASCADE)"; - // Locking: contact read, window + // Locking: contact read, transport read, window private static final String CREATE_CONTACT_TRANSPORTS = "CREATE TABLE contactTransports" + " (contactId INT NOT NULL," @@ -269,7 +269,7 @@ abstract class JdbcDatabase implements Database<Connection> { + " REFERENCES transports (transportId)" + " ON DELETE CASCADE)"; - // Locking: contact read, window + // Locking: contact read, transport read, window private static final String CREATE_SECRETS = "CREATE TABLE secrets" + " (contactId INT NOT NULL," diff --git a/briar-core/src/net/sf/briar/protocol/duplex/DuplexConnection.java b/briar-core/src/net/sf/briar/protocol/duplex/DuplexConnection.java index 221dd002759075080f23e29acd729a78c64624c4..9321750e4c23da193d09c513184f22c368dc2241 100644 --- a/briar-core/src/net/sf/briar/protocol/duplex/DuplexConnection.java +++ b/briar-core/src/net/sf/briar/protocol/duplex/DuplexConnection.java @@ -29,8 +29,8 @@ import net.sf.briar.api.db.event.DatabaseEvent; import net.sf.briar.api.db.event.DatabaseListener; import net.sf.briar.api.db.event.MessageAddedEvent; import net.sf.briar.api.db.event.MessageReceivedEvent; -import net.sf.briar.api.db.event.SubscriptionsUpdatedEvent; -import net.sf.briar.api.db.event.TransportsUpdatedEvent; +import net.sf.briar.api.db.event.LocalSubscriptionsUpdatedEvent; +import net.sf.briar.api.db.event.LocalTransportsUpdatedEvent; import net.sf.briar.api.plugins.duplex.DuplexTransportConnection; import net.sf.briar.api.protocol.Ack; import net.sf.briar.api.protocol.Message; @@ -127,13 +127,13 @@ abstract class DuplexConnection implements DatabaseListener { } else if(e instanceof MessageAddedEvent) { if(canSendOffer.getAndSet(false)) dbExecutor.execute(new GenerateOffer()); - } else if(e instanceof SubscriptionsUpdatedEvent) { + } else if(e instanceof LocalSubscriptionsUpdatedEvent) { Collection<ContactId> affected = - ((SubscriptionsUpdatedEvent) e).getAffectedContacts(); + ((LocalSubscriptionsUpdatedEvent) e).getAffectedContacts(); if(affected.contains(contactId)) { dbExecutor.execute(new GenerateSubscriptionUpdate()); } - } else if(e instanceof TransportsUpdatedEvent) { + } else if(e instanceof LocalTransportsUpdatedEvent) { dbExecutor.execute(new GenerateTransportUpdate()); } } diff --git a/briar-tests/src/net/sf/briar/db/DatabaseComponentTest.java b/briar-tests/src/net/sf/briar/db/DatabaseComponentTest.java index 298503a0c7d2af3659874806ec0ea7dea2152cbc..dfe7f39165bfb7a115e3ff46fe1b9bb6d9fc6697 100644 --- a/briar-tests/src/net/sf/briar/db/DatabaseComponentTest.java +++ b/briar-tests/src/net/sf/briar/db/DatabaseComponentTest.java @@ -19,7 +19,7 @@ import net.sf.briar.api.db.event.ContactRemovedEvent; import net.sf.briar.api.db.event.DatabaseListener; import net.sf.briar.api.db.event.MessageAddedEvent; import net.sf.briar.api.db.event.RatingChangedEvent; -import net.sf.briar.api.db.event.SubscriptionsUpdatedEvent; +import net.sf.briar.api.db.event.LocalSubscriptionsUpdatedEvent; import net.sf.briar.api.lifecycle.ShutdownManager; import net.sf.briar.api.protocol.Ack; import net.sf.briar.api.protocol.AuthorId; @@ -1377,7 +1377,7 @@ public abstract class DatabaseComponentTest extends BriarTestCase { oneOf(database).removeVisibility(txn, contactId1, groupId); oneOf(database).commitTransaction(txn); oneOf(listener).eventOccurred(with(any( - SubscriptionsUpdatedEvent.class))); + LocalSubscriptionsUpdatedEvent.class))); }}); DatabaseComponent db = createDatabaseComponent(database, cleaner, shutdown);