diff --git a/briar-core/src/net/sf/briar/plugins/modem/ReliabilityLayer.java b/briar-core/src/net/sf/briar/plugins/modem/ReliabilityLayer.java index edf67ac576edf81f7afba4c7ff477367c148abfb..d033aa678aeeb8f68d48faa1027c7684784b68e3 100644 --- a/briar-core/src/net/sf/briar/plugins/modem/ReliabilityLayer.java +++ b/briar-core/src/net/sf/briar/plugins/modem/ReliabilityLayer.java @@ -1,5 +1,6 @@ package net.sf.briar.plugins.modem; +import static java.util.concurrent.TimeUnit.MILLISECONDS; import static java.util.logging.Level.WARNING; import java.io.IOException; @@ -11,6 +12,8 @@ import java.util.logging.Logger; class ReliabilityLayer implements ReadHandler, WriteHandler { + private static final int TICK_INTERVAL = 500; // Milliseconds + private static final Logger LOG = Logger.getLogger(ReliabilityLayer.class.getName()); @@ -31,7 +34,7 @@ class ReliabilityLayer implements ReadHandler, WriteHandler { void start() { SlipEncoder encoder = new SlipEncoder(this); - Sender sender = new Sender(encoder); + final Sender sender = new Sender(encoder); receiver = new Receiver(sender); decoder = new SlipDecoder(receiver); inputStream = new ReceiverInputStream(receiver); @@ -39,11 +42,22 @@ class ReliabilityLayer implements ReadHandler, WriteHandler { writer = new Thread("ReliabilityLayer") { @Override public void run() { + long now = System.currentTimeMillis(); + long next = now + TICK_INTERVAL; try { while(running) { - byte[] b = writes.take(); - if(b.length == 0) return; // Poison pill - writeHandler.handleWrite(b); + byte[] b = null; + while(now < next && b == null) { + b = writes.poll(next - now, MILLISECONDS); + now = System.currentTimeMillis(); + } + if(b == null) { + sender.tick(); + while(next <= now) next += TICK_INTERVAL; + } else { + if(b.length == 0) return; // Poison pill + writeHandler.handleWrite(b); + } } } catch(InterruptedException e) { if(LOG.isLoggable(WARNING)) @@ -52,7 +66,7 @@ class ReliabilityLayer implements ReadHandler, WriteHandler { running = false; } catch(IOException e) { if(LOG.isLoggable(WARNING)) - LOG.warning("Interrupted while writing"); + LOG.log(WARNING, e.toString(), e); running = false; } } @@ -70,7 +84,6 @@ class ReliabilityLayer implements ReadHandler, WriteHandler { } void stop() { - if(!running) throw new IllegalStateException(); running = false; receiver.invalidate(); writes.add(new byte[0]); // Poison pill diff --git a/briar-core/src/net/sf/briar/plugins/modem/Sender.java b/briar-core/src/net/sf/briar/plugins/modem/Sender.java index 3bf2c75f5bd8095ef54b34d8598e0c9bc1fa4407..bb2ad8a7bb4b4d676e2a3ea5b7b4a22f40b3bf32 100644 --- a/briar-core/src/net/sf/briar/plugins/modem/Sender.java +++ b/briar-core/src/net/sf/briar/plugins/modem/Sender.java @@ -1,19 +1,13 @@ package net.sf.briar.plugins.modem; -import static java.util.logging.Level.WARNING; - import java.io.IOException; import java.util.ArrayList; import java.util.Iterator; import java.util.LinkedList; import java.util.List; -import java.util.logging.Logger; class Sender { - private static final Logger LOG = - Logger.getLogger(Sender.class.getName()); - // All times are in milliseconds private static final int MIN_TIMEOUT = 1000; private static final int MAX_TIMEOUT = 60 * 1000; @@ -99,7 +93,7 @@ class Sender { writeHandler.handleWrite(fastRetransmit.data.getBuffer()); } - void tick() { + void tick() throws IOException { long now = System.currentTimeMillis(); List<Outstanding> retransmit = null; boolean sendProbe = false; @@ -132,23 +126,17 @@ class Sender { } } } - try { - // Send a window probe if necessary - if(sendProbe) { - byte[] buf = new byte[Data.MIN_LENGTH]; - Data probe = new Data(buf); - probe.setChecksum(probe.calculateChecksum()); - writeHandler.handleWrite(buf); - } - // Retransmit any lost data frames - if(retransmit != null) { - for(Outstanding o : retransmit) - writeHandler.handleWrite(o.data.getBuffer()); - } - } catch(IOException e) { - // FIXME: Do something more meaningful - if(LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e); - return; + // Send a window probe if necessary + if(sendProbe) { + byte[] buf = new byte[Data.MIN_LENGTH]; + Data probe = new Data(buf); + probe.setChecksum(probe.calculateChecksum()); + writeHandler.handleWrite(buf); + } + // Retransmit any lost data frames + if(retransmit != null) { + for(Outstanding o : retransmit) + writeHandler.handleWrite(o.data.getBuffer()); } }