diff --git a/components/net/sf/briar/db/DatabaseCleanerImpl.java b/components/net/sf/briar/db/DatabaseCleanerImpl.java index 39e6c70b47c85774fb3e80b4596f6ef73516fe4c..71574267edf86ac0820520838905a6dd02deb365 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 9a79bc762cb8532bcf26a5c627dfda84691b00b9..402674954a82dac870f6b1776cb046f0f37df78c 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); } }