diff --git a/src/net/sf/briar/plugins/modem/Modem.java b/src/net/sf/briar/plugins/modem/Modem.java index 42c3693bf369fcf2a4c90df2752281dffb22ca6c..3d55e3c24c0a42f9466e1ed6ab728fd205558908 100644 --- a/src/net/sf/briar/plugins/modem/Modem.java +++ b/src/net/sf/briar/plugins/modem/Modem.java @@ -6,14 +6,14 @@ import java.io.OutputStream; /** * A modem that can be used for multiple sequential incoming and outgoing - * calls. If the modem or its input or output streams throw any exceptions they - * cannot continue to be used. + * calls. */ interface Modem { /** - * Call this method once after creating the modem and before making any - * calls. + * Call this method after creating the modem and before making any calls. + * If an exception is thrown while using the modem, this method must be + * called again. */ void init() throws IOException; diff --git a/src/net/sf/briar/plugins/modem/ModemImpl.java b/src/net/sf/briar/plugins/modem/ModemImpl.java index da217a881c4c07f8e945ba37bc52db2442cc79d6..eb8542259931badac7ca8d5b35904ad8024ea0f1 100644 --- a/src/net/sf/briar/plugins/modem/ModemImpl.java +++ b/src/net/sf/briar/plugins/modem/ModemImpl.java @@ -41,7 +41,6 @@ class ModemImpl implements Modem, SerialPortEventListener { private int lineLen = 0; - ModemImpl(Executor executor, Callback callback, String portName) { this.executor = executor; this.callback = callback; diff --git a/src/net/sf/briar/plugins/modem/ModemPlugin.java b/src/net/sf/briar/plugins/modem/ModemPlugin.java index e51dd7b03531ccf2f0448fd7620a4c585fba6a14..f2ea8473901cab58ed17e9ecd43701106a44218e 100644 --- a/src/net/sf/briar/plugins/modem/ModemPlugin.java +++ b/src/net/sf/briar/plugins/modem/ModemPlugin.java @@ -80,10 +80,24 @@ class ModemPlugin implements DuplexPlugin, Modem.Callback { return false; } - public void stop() { + // Synchronized to avoid a race condition with resetModem() + public synchronized void stop() { running = false; } + // Synchronized to avoid a race condition with stop() + private synchronized boolean resetModem() { + if(!running) return false; + try { + modem.init(); + return true; + } catch(IOException e) { + if(LOG.isLoggable(WARNING)) LOG.warning(e.toString()); + running = false; + return false; + } + } + public boolean shouldPoll() { return true; } @@ -121,9 +135,7 @@ class ModemPlugin implements DuplexPlugin, Modem.Callback { try { if(!modem.dial(number)) continue; } catch(IOException e) { - // FIXME: Race condition with stop() - running = false; - if(start()) continue; + if(resetModem()) continue; else break; } ModemTransportConnection conn = new ModemTransportConnection(); @@ -149,9 +161,8 @@ class ModemPlugin implements DuplexPlugin, Modem.Callback { try { if(!modem.dial(number)) return null; } catch(IOException e) { - // FIXME: Race condition with stop() - running = false; - start(); + // Reinitialise the modem + resetModem(); return null; } return new ModemTransportConnection(); @@ -199,11 +210,7 @@ class ModemPlugin implements DuplexPlugin, Modem.Callback { if(LOG.isLoggable(WARNING)) LOG.warning(e.toString()); exception = true; } - if(exception) { - // FIXME: Race condition with stop() - running = false; - start(); - } + if(exception) resetModem(); finished.countDown(); }