From f8183a4ce3d49d82146bc5e42613c06718e095f8 Mon Sep 17 00:00:00 2001
From: akwizgran <michael@briarproject.org>
Date: Fri, 7 Sep 2012 16:36:48 +0100
Subject: [PATCH] Refactored DatabaseCleanerImpl to use Timer and TimerTask.

---
 .../net/sf/briar/db/DatabaseCleanerImpl.java  | 59 ++++++++-----------
 .../sf/briar/db/DatabaseCleanerImplTest.java  | 34 +++++++++--
 2 files changed, 52 insertions(+), 41 deletions(-)

diff --git a/components/net/sf/briar/db/DatabaseCleanerImpl.java b/components/net/sf/briar/db/DatabaseCleanerImpl.java
index 39e6c70b47..71574267ed 100644
--- a/components/net/sf/briar/db/DatabaseCleanerImpl.java
+++ b/components/net/sf/briar/db/DatabaseCleanerImpl.java
@@ -1,56 +1,45 @@
 package net.sf.briar.db;
 
+import java.util.Timer;
+import java.util.TimerTask;
 import java.util.logging.Level;
 import java.util.logging.Logger;
 
 import net.sf.briar.api.db.DbException;
 
-class DatabaseCleanerImpl implements DatabaseCleaner, Runnable {
+class DatabaseCleanerImpl extends TimerTask implements DatabaseCleaner {
 
 	private static final Logger LOG =
-		Logger.getLogger(DatabaseCleanerImpl.class.getName());
+			Logger.getLogger(DatabaseCleanerImpl.class.getName());
 
-	private Callback callback = null;
-	private long msBetweenSweeps = 0L;
-	private boolean stopped = false;
+	private volatile Callback callback = null;
+	private volatile Timer timer = null;
 
-	public synchronized void startCleaning(Callback callback,
-			long msBetweenSweeps) {
+	public void startCleaning(Callback callback, long msBetweenSweeps) {
 		this.callback = callback;
-		this.msBetweenSweeps = msBetweenSweeps;
-		new Thread(this).start();
+		timer = new Timer();
+		timer.scheduleAtFixedRate(this, 0L, msBetweenSweeps);
 	}
 
-	public synchronized void stopCleaning() {
-		stopped = true;
-		notifyAll();
+	public void stopCleaning() {
+		if(timer == null) throw new IllegalStateException();
+		timer.cancel();
 	}
 
 	public void run() {
-		while(true) {
-			synchronized(this) {
-				if(stopped) return;
-				try {
-					if(callback.shouldCheckFreeSpace()) {
-						callback.checkFreeSpaceAndClean();
-					} else {
-						try {
-							wait(msBetweenSweeps);
-						} catch(InterruptedException e) {
-							if(LOG.isLoggable(Level.INFO))
-								LOG.info("Interrupted while waiting to clean");
-							Thread.currentThread().interrupt();
-							return;
-						}
-					}
-				} catch(DbException e) {
-					if(LOG.isLoggable(Level.WARNING))
-						LOG.warning(e.toString());
-				} catch(RuntimeException e) {
-					if(LOG.isLoggable(Level.WARNING))
-						LOG.warning(e.toString());
-				}
+		if(callback == null) throw new IllegalStateException();
+		try {
+			if(callback.shouldCheckFreeSpace()) {
+				callback.checkFreeSpaceAndClean();
 			}
+		} catch(DbException e) {
+			if(LOG.isLoggable(Level.WARNING))
+				LOG.warning(e.toString());
+			throw new Error(e); // Kill the application
+		} catch(RuntimeException e) {
+			if(LOG.isLoggable(Level.WARNING))
+				LOG.warning(e.toString());
+			throw new Error(e); // Kill the application
 		}
 	}
 }
diff --git a/test/net/sf/briar/db/DatabaseCleanerImplTest.java b/test/net/sf/briar/db/DatabaseCleanerImplTest.java
index 9a79bc762c..402674954a 100644
--- a/test/net/sf/briar/db/DatabaseCleanerImplTest.java
+++ b/test/net/sf/briar/db/DatabaseCleanerImplTest.java
@@ -11,29 +11,51 @@ import org.junit.Test;
 
 public class DatabaseCleanerImplTest extends BriarTestCase {
 
+	@Test
+	public void testCleanerRunsPeriodically() throws Exception {
+		final CountDownLatch latch = new CountDownLatch(5);
+		Callback callback = new Callback() {
+
+			public void checkFreeSpaceAndClean() throws DbException {
+				latch.countDown();
+			}
+
+			public boolean shouldCheckFreeSpace() {
+				return true;
+			}
+		};
+		DatabaseCleanerImpl cleaner = new DatabaseCleanerImpl();
+		// Start the cleaner
+		cleaner.startCleaning(callback, 10L);
+		// The database should be cleaned five times (allow 5s for system load)
+		assertTrue(latch.await(5, TimeUnit.SECONDS));
+		// Stop the cleaner
+		cleaner.stopCleaning();
+	}
+
 	@Test
 	public void testStoppingCleanerWakesItUp() throws Exception {
 		final CountDownLatch latch = new CountDownLatch(1);
 		Callback callback = new Callback() {
 
 			public void checkFreeSpaceAndClean() throws DbException {
-				throw new IllegalStateException();
+				latch.countDown();
 			}
 
 			public boolean shouldCheckFreeSpace() {
-				latch.countDown();
-				return false;
+				return true;
 			}
 		};
 		DatabaseCleanerImpl cleaner = new DatabaseCleanerImpl();
 		long start = System.currentTimeMillis();
-		// Start the cleaner and check that shouldCheckFreeSpace() is called
-		cleaner.startCleaning(callback, 30L * 1000L);
+		// Start the cleaner
+		cleaner.startCleaning(callback, 10L * 1000L);
+		// The database should be cleaned once at startup
 		assertTrue(latch.await(5, TimeUnit.SECONDS));
 		// Stop the cleaner (it should be waiting between sweeps)
 		cleaner.stopCleaning();
 		long end = System.currentTimeMillis();
-		// Check that much less than 30 seconds expired
+		// Check that much less than 10 seconds expired
 		assertTrue(end - start < 10L * 1000L);
 	}
 }
-- 
GitLab