mirror of
https://code.briarproject.org/briar/briar.git
synced 2026-02-15 12:19:54 +01:00
Wait for writes to complete before closing the serial port.
This commit is contained in:
@@ -33,7 +33,7 @@ class ModemImpl implements Modem, WriteHandler, SerialPortEventListener {
|
|||||||
private final Callback callback;
|
private final Callback callback;
|
||||||
private final SerialPort port;
|
private final SerialPort port;
|
||||||
private final AtomicBoolean initialised, connected;
|
private final AtomicBoolean initialised, connected;
|
||||||
private final Semaphore offHook;
|
private final Semaphore offHook, writing;
|
||||||
private final byte[] line;
|
private final byte[] line;
|
||||||
|
|
||||||
private int lineLen = 0;
|
private int lineLen = 0;
|
||||||
@@ -46,6 +46,7 @@ class ModemImpl implements Modem, WriteHandler, SerialPortEventListener {
|
|||||||
port = new SerialPort(portName);
|
port = new SerialPort(portName);
|
||||||
initialised = new AtomicBoolean(false);
|
initialised = new AtomicBoolean(false);
|
||||||
offHook = new Semaphore(1);
|
offHook = new Semaphore(1);
|
||||||
|
writing = new Semaphore(1);
|
||||||
connected = new AtomicBoolean(false);
|
connected = new AtomicBoolean(false);
|
||||||
line = new byte[MAX_LINE_LENGTH];
|
line = new byte[MAX_LINE_LENGTH];
|
||||||
reliabilityLayer = new ReliabilityLayer(this);
|
reliabilityLayer = new ReliabilityLayer(this);
|
||||||
@@ -151,14 +152,28 @@ class ModemImpl implements Modem, WriteHandler, SerialPortEventListener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void handleWrite(byte[] b) throws IOException {
|
public void handleWrite(byte[] b) throws IOException {
|
||||||
|
try {
|
||||||
|
writing.acquire();
|
||||||
|
} catch(InterruptedException e) {
|
||||||
|
tryToClose(port);
|
||||||
|
Thread.currentThread().interrupt();
|
||||||
|
throw new IOException("Interrupted while waiting to write");
|
||||||
|
}
|
||||||
try {
|
try {
|
||||||
port.writeBytes(b);
|
port.writeBytes(b);
|
||||||
} catch(SerialPortException e) {
|
} catch(SerialPortException e) {
|
||||||
tryToClose(port);
|
tryToClose(port);
|
||||||
throw new IOException(e.toString());
|
throw new IOException(e.toString());
|
||||||
|
} finally {
|
||||||
|
writing.release();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void waitForWritesToComplete() throws InterruptedException {
|
||||||
|
writing.acquire();
|
||||||
|
writing.release();
|
||||||
|
}
|
||||||
|
|
||||||
public void serialEvent(SerialPortEvent ev) {
|
public void serialEvent(SerialPortEvent ev) {
|
||||||
try {
|
try {
|
||||||
if(ev.isRXCHAR()) {
|
if(ev.isRXCHAR()) {
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ class ReliabilityLayer implements ReadHandler, WriteHandler {
|
|||||||
private final BlockingQueue<byte[]> writes;
|
private final BlockingQueue<byte[]> writes;
|
||||||
|
|
||||||
private volatile boolean valid = true;
|
private volatile boolean valid = true;
|
||||||
|
private volatile Thread writer = null;
|
||||||
|
|
||||||
ReliabilityLayer(WriteHandler writeHandler) {
|
ReliabilityLayer(WriteHandler writeHandler) {
|
||||||
this.writeHandler = writeHandler;
|
this.writeHandler = writeHandler;
|
||||||
@@ -36,7 +37,7 @@ class ReliabilityLayer implements ReadHandler, WriteHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void init() {
|
void init() {
|
||||||
new Thread("ReliabilityLayer") {
|
writer = new Thread("ReliabilityLayer") {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
try {
|
try {
|
||||||
@@ -58,7 +59,8 @@ class ReliabilityLayer implements ReadHandler, WriteHandler {
|
|||||||
valid = false;
|
valid = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}.start();
|
};
|
||||||
|
writer.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
InputStream getInputStream() {
|
InputStream getInputStream() {
|
||||||
@@ -88,4 +90,9 @@ class ReliabilityLayer implements ReadHandler, WriteHandler {
|
|||||||
if(LOG.isLoggable(INFO)) LOG.info("Queueing " + b.length + " bytes");
|
if(LOG.isLoggable(INFO)) LOG.info("Queueing " + b.length + " bytes");
|
||||||
if(b.length > 0) writes.add(b);
|
if(b.length > 0) writes.add(b);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void waitForWritesToComplete() throws InterruptedException {
|
||||||
|
if(writer != null) writer.join();
|
||||||
|
writeHandler.waitForWritesToComplete();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -204,6 +204,10 @@ class Sender {
|
|||||||
writeHandler.handleWrite(d.getBuffer());
|
writeHandler.handleWrite(d.getBuffer());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void waitForWritesToComplete() throws InterruptedException {
|
||||||
|
writeHandler.waitForWritesToComplete();
|
||||||
|
}
|
||||||
|
|
||||||
private static class Outstanding {
|
private static class Outstanding {
|
||||||
|
|
||||||
private final Data data;
|
private final Data data;
|
||||||
|
|||||||
@@ -23,6 +23,12 @@ class SenderOutputStream extends OutputStream {
|
|||||||
@Override
|
@Override
|
||||||
public void flush() throws IOException {
|
public void flush() throws IOException {
|
||||||
if(offset > Data.HEADER_LENGTH) send(false);
|
if(offset > Data.HEADER_LENGTH) send(false);
|
||||||
|
try {
|
||||||
|
sender.waitForWritesToComplete();
|
||||||
|
} catch(InterruptedException e) {
|
||||||
|
Thread.currentThread().interrupt();
|
||||||
|
throw new IOException("Interrupted while flushing output stream");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -35,4 +35,8 @@ class SlipEncoder implements WriteHandler {
|
|||||||
encoded[encodedLength - 1] = END;
|
encoded[encodedLength - 1] = END;
|
||||||
writeHandler.handleWrite(encoded);
|
writeHandler.handleWrite(encoded);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void waitForWritesToComplete() throws InterruptedException {
|
||||||
|
writeHandler.waitForWritesToComplete();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,4 +5,6 @@ import java.io.IOException;
|
|||||||
interface WriteHandler {
|
interface WriteHandler {
|
||||||
|
|
||||||
void handleWrite(byte[] b) throws IOException;
|
void handleWrite(byte[] b) throws IOException;
|
||||||
|
|
||||||
|
void waitForWritesToComplete() throws InterruptedException;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user