diff --git a/briar-core/src/net/sf/briar/db/Database.java b/briar-core/src/net/sf/briar/db/Database.java index f1031d7a9214628516aa8e1952473a51c212fea8..2c0987ef1ad0327618edc225ffd6f9a2cdba6075 100644 --- a/briar-core/src/net/sf/briar/db/Database.java +++ b/briar-core/src/net/sf/briar/db/Database.java @@ -715,23 +715,23 @@ interface Database<T> { /** * Updates the remote transport properties for the given contact and the - * given transport, replacing any existing properties, unless an update - * with an equal or higher version number has already been received from - * the contact. + * given transport, replacing any existing properties, and returns true, + * unless an update with an equal or higher version number has already been + * received from the contact. * <p> * Locking: transport write. */ - void setRemoteProperties(T txn, ContactId c, TransportId t, + boolean setRemoteProperties(T txn, ContactId c, TransportId t, TransportProperties p, long version) throws DbException; /** - * Sets the retention time of the given contact's database, unless an - * update with an equal or higher version number has already been received - * from the contact. + * Sets the retention time of the given contact's database and returns + * true, unless an update with an equal or higher version number has + * already been received from the contact. * <p> * Locking: retention write. */ - void setRetentionTime(T txn, ContactId c, long retention, long version) + boolean setRetentionTime(T txn, ContactId c, long retention, long version) throws DbException; /** @@ -761,17 +761,17 @@ interface Database<T> { throws DbException; /** - * Updates the groups to which the given contact subscribes, unless an - * update with an equal or higher version number has already been received - * from the contact. + * Updates the groups to which the given contact subscribes and returns + * true, unless an update with an equal or higher version number has + * already been received from the contact. * <p> * Locking: subscription write. */ - void setSubscriptions(T txn, ContactId c, Collection<Group> subs, + boolean setSubscriptions(T txn, ContactId c, Collection<Group> subs, long version) throws DbException; /** - * Records a retention ack from the given contact for the given version + * Records a retention ack from the given contact for the given version, * unless the contact has already acked an equal or higher version. * <p> * Locking: retention write. @@ -780,7 +780,7 @@ interface Database<T> { throws DbException; /** - * Records a subscription ack from the given contact for the given version + * Records a subscription ack from the given contact for the given version, * unless the contact has already acked an equal or higher version. * <p> * Locking: subscription write. @@ -789,7 +789,7 @@ interface Database<T> { throws DbException; /** - * Records a transport ack from the give contact for the given version + * Records a transport ack from the give contact for the given version, * unless the contact has already acked an equal or higher version. * <p> * Locking: transport write. diff --git a/briar-core/src/net/sf/briar/db/DatabaseComponentImpl.java b/briar-core/src/net/sf/briar/db/DatabaseComponentImpl.java index 45568d4d61025c374818f49791a207c7c663b74c..4790da31fbc8ba81febeb858fe4254159d22cd6e 100644 --- a/briar-core/src/net/sf/briar/db/DatabaseComponentImpl.java +++ b/briar-core/src/net/sf/briar/db/DatabaseComponentImpl.java @@ -1613,6 +1613,7 @@ DatabaseCleaner.Callback { public void receiveRetentionUpdate(ContactId c, RetentionUpdate u) throws DbException { + boolean updated; contactLock.readLock().lock(); try { retentionLock.writeLock().lock(); @@ -1621,7 +1622,7 @@ DatabaseCleaner.Callback { try { if(!db.containsContact(txn, c)) throw new NoSuchContactException(); - db.setRetentionTime(txn, c, u.getRetentionTime(), + updated = db.setRetentionTime(txn, c, u.getRetentionTime(), u.getVersion()); db.commitTransaction(txn); } catch(DbException e) { @@ -1634,7 +1635,7 @@ DatabaseCleaner.Callback { } finally { contactLock.readLock().unlock(); } - callListeners(new RemoteRetentionTimeUpdatedEvent(c)); + if(updated) callListeners(new RemoteRetentionTimeUpdatedEvent(c)); } public void receiveSubscriptionAck(ContactId c, SubscriptionAck a) @@ -1663,6 +1664,7 @@ DatabaseCleaner.Callback { public void receiveSubscriptionUpdate(ContactId c, SubscriptionUpdate u) throws DbException { + boolean updated; contactLock.readLock().lock(); try { subscriptionLock.writeLock().lock(); @@ -1671,7 +1673,9 @@ DatabaseCleaner.Callback { try { if(!db.containsContact(txn, c)) throw new NoSuchContactException(); - db.setSubscriptions(txn, c, u.getGroups(), u.getVersion()); + Collection<Group> groups = u.getGroups(); + long version = u.getVersion(); + updated = db.setSubscriptions(txn, c, groups, version); db.commitTransaction(txn); } catch(DbException e) { db.abortTransaction(txn); @@ -1683,7 +1687,7 @@ DatabaseCleaner.Callback { } finally { contactLock.readLock().unlock(); } - callListeners(new RemoteSubscriptionsUpdatedEvent(c)); + if(updated) callListeners(new RemoteSubscriptionsUpdatedEvent(c)); } public void receiveTransportAck(ContactId c, TransportAck a) @@ -1715,6 +1719,7 @@ DatabaseCleaner.Callback { public void receiveTransportUpdate(ContactId c, TransportUpdate u) throws DbException { + boolean updated; contactLock.readLock().lock(); try { transportLock.writeLock().lock(); @@ -1723,8 +1728,10 @@ DatabaseCleaner.Callback { try { if(!db.containsContact(txn, c)) throw new NoSuchContactException(); - db.setRemoteProperties(txn, c, u.getId(), u.getProperties(), - u.getVersion()); + TransportId t = u.getId(); + TransportProperties p = u.getProperties(); + long version = u.getVersion(); + updated = db.setRemoteProperties(txn, c, t, p, version); db.commitTransaction(txn); } catch(DbException e) { db.abortTransaction(txn); @@ -1736,7 +1743,8 @@ DatabaseCleaner.Callback { } finally { contactLock.readLock().unlock(); } - callListeners(new RemoteTransportsUpdatedEvent(c, u.getId())); + if(updated) + callListeners(new RemoteTransportsUpdatedEvent(c, u.getId())); } public void removeContact(ContactId c) throws DbException { diff --git a/briar-tests/src/net/sf/briar/db/H2DatabaseTest.java b/briar-tests/src/net/sf/briar/db/H2DatabaseTest.java index 1fae6c77fb45575705a90d1b040c721508d10733..aa0f778a3ddf9b14f9d982cfb8d4f23105a6eb74 100644 --- a/briar-tests/src/net/sf/briar/db/H2DatabaseTest.java +++ b/briar-tests/src/net/sf/briar/db/H2DatabaseTest.java @@ -839,21 +839,21 @@ public class H2DatabaseTest extends BriarTestCase { // Initialise the transport properties with version 1 TransportProperties p = new TransportProperties( Collections.singletonMap("foo", "bar")); - db.setRemoteProperties(txn, contactId, transportId, p, 1); + assertTrue(db.setRemoteProperties(txn, contactId, transportId, p, 1)); assertEquals(Collections.singletonMap(contactId, p), db.getRemoteProperties(txn, transportId)); // Replace the transport properties with version 2 TransportProperties p1 = new TransportProperties( Collections.singletonMap("baz", "bam")); - db.setRemoteProperties(txn, contactId, transportId, p1, 2); + assertTrue(db.setRemoteProperties(txn, contactId, transportId, p1, 2)); assertEquals(Collections.singletonMap(contactId, p1), db.getRemoteProperties(txn, transportId)); // Try to replace the transport properties with version 1 TransportProperties p2 = new TransportProperties( Collections.singletonMap("quux", "etc")); - db.setRemoteProperties(txn, contactId, transportId, p2, 1); + assertFalse(db.setRemoteProperties(txn, contactId, transportId, p2, 1)); // Version 2 of the properties should still be there assertEquals(Collections.singletonMap(contactId, p1),