From a40c081815fa653cfb6334cbbe4a22167af53cec Mon Sep 17 00:00:00 2001
From: akwizgran <akwizgran@users.sourceforge.net>
Date: Mon, 26 Sep 2011 18:13:48 +0100
Subject: [PATCH] Record when the latest subscription/transport update was
 sent.

---
 components/net/sf/briar/db/Database.java       | 18 ++++++++++++++++++
 .../net/sf/briar/db/DatabaseComponentImpl.java | 18 ++++++++++++------
 .../net/sf/briar/db/DatabaseComponentTest.java |  4 ++++
 3 files changed, 34 insertions(+), 6 deletions(-)

diff --git a/components/net/sf/briar/db/Database.java b/components/net/sf/briar/db/Database.java
index f43a98cde8..648f231d77 100644
--- a/components/net/sf/briar/db/Database.java
+++ b/components/net/sf/briar/db/Database.java
@@ -452,6 +452,15 @@ interface Database<T> {
 	void setSubscriptions(T txn, ContactId c, Map<Group, Long> subs,
 			long timestamp) throws DbException;
 
+	/**
+	 * Records the time at which a subscription update was last sent to the
+	 * given contact.
+	 * <p>
+	 * Locking: contacts read, subscriptions write.
+	 */
+	void setSubscriptionTimestamp(T txn, ContactId c, long timestamp)
+	throws DbException;
+
 	/**
 	 * Sets the configuration for the transport with the given name, replacing
 	 * any existing configuration for that transport.
@@ -481,6 +490,15 @@ interface Database<T> {
 			Map<String, Map<String, String>> transports, long timestamp)
 	throws DbException;
 
+	/**
+	 * Records the time at which a transport update was last sent to the given
+	 * contact.
+	 * <p>
+	 * Locking: contacts read, transports write.
+	 */
+	void setTransportTimestamp(T txn, ContactId c, long timestamp)
+	throws DbException;
+
 	/**
 	 * Makes the given group visible to the given set of contacts and invisible
 	 * to any other contacts.
diff --git a/components/net/sf/briar/db/DatabaseComponentImpl.java b/components/net/sf/briar/db/DatabaseComponentImpl.java
index 042b714f21..bc882aa453 100644
--- a/components/net/sf/briar/db/DatabaseComponentImpl.java
+++ b/components/net/sf/briar/db/DatabaseComponentImpl.java
@@ -596,26 +596,29 @@ DatabaseCleaner.Callback {
 	public void generateSubscriptionUpdate(ContactId c, SubscriptionWriter s)
 	throws DbException, IOException {
 		Map<Group, Long> subs;
+		long timestamp;
 		contactLock.readLock().lock();
 		try {
 			if(!containsContact(c)) throw new NoSuchContactException();
-			subscriptionLock.readLock().lock();
+			subscriptionLock.writeLock().lock();
 			try {
 				T txn = db.startTransaction();
 				try {
 					subs = db.getVisibleSubscriptions(txn, c);
+					timestamp = System.currentTimeMillis();
+					db.setSubscriptionTimestamp(txn, c, timestamp);
 					db.commitTransaction(txn);
 				} catch(DbException e) {
 					db.abortTransaction(txn);
 					throw e;
 				}
 			} finally {
-				subscriptionLock.readLock().unlock();
+				subscriptionLock.writeLock().unlock();
 			}
 		} finally {
 			contactLock.readLock().unlock();
 		}
-		s.writeSubscriptions(subs, System.currentTimeMillis());
+		s.writeSubscriptions(subs, timestamp);
 		if(LOG.isLoggable(Level.FINE))
 			LOG.fine("Added " + subs.size() + " subscriptions to update");
 	}
@@ -623,26 +626,29 @@ DatabaseCleaner.Callback {
 	public void generateTransportUpdate(ContactId c, TransportWriter t)
 	throws DbException, IOException {
 		Map<String, Map<String, String>> transports;
+		long timestamp;
 		contactLock.readLock().lock();
 		try {
 			if(!containsContact(c)) throw new NoSuchContactException();
-			transportLock.readLock().lock();
+			transportLock.writeLock().lock();
 			try {
 				T txn = db.startTransaction();
 				try {
 					transports = db.getTransports(txn);
+					timestamp = System.currentTimeMillis();
+					db.setTransportTimestamp(txn, c, timestamp);
 					db.commitTransaction(txn);
 				} catch(DbException e) {
 					db.abortTransaction(txn);
 					throw e;
 				}
 			} finally {
-				transportLock.readLock().unlock();
+				transportLock.writeLock().unlock();
 			}
 		} finally {
 			contactLock.readLock().unlock();
 		}
-		t.writeTransports(transports, System.currentTimeMillis());
+		t.writeTransports(transports, timestamp);
 		if(LOG.isLoggable(Level.FINE))
 			LOG.fine("Added " + transports.size() + " transports to update");
 	}
diff --git a/test/net/sf/briar/db/DatabaseComponentTest.java b/test/net/sf/briar/db/DatabaseComponentTest.java
index 1e8d39f07e..4f9d1dbbbf 100644
--- a/test/net/sf/briar/db/DatabaseComponentTest.java
+++ b/test/net/sf/briar/db/DatabaseComponentTest.java
@@ -753,6 +753,8 @@ public abstract class DatabaseComponentTest extends TestCase {
 			// Get the visible subscriptions
 			oneOf(database).getVisibleSubscriptions(txn, contactId);
 			will(returnValue(Collections.singletonMap(group, 0L)));
+			oneOf(database).setSubscriptionTimestamp(with(txn), with(contactId),
+					with(any(long.class)));
 			// Add the subscriptions to the writer
 			oneOf(subscriptionWriter).writeSubscriptions(
 					with(Collections.singletonMap(group, 0L)),
@@ -786,6 +788,8 @@ public abstract class DatabaseComponentTest extends TestCase {
 			// Get the local transport properties
 			oneOf(database).getTransports(txn);
 			will(returnValue(transports));
+			oneOf(database).setTransportTimestamp(with(txn), with(contactId),
+					with(any(long.class)));
 			// Add the properties to the writer
 			oneOf(transportWriter).writeTransports(with(transports),
 					with(any(long.class)));
-- 
GitLab