Wait for writes to complete before closing the serial port.

This commit is contained in:
akwizgran
2012-12-06 16:36:51 +00:00
parent bfbcdfa5a7
commit 0b7ecde4c8
6 changed files with 41 additions and 3 deletions

View File

@@ -33,7 +33,7 @@ class ModemImpl implements Modem, WriteHandler, SerialPortEventListener {
private final Callback callback;
private final SerialPort port;
private final AtomicBoolean initialised, connected;
private final Semaphore offHook;
private final Semaphore offHook, writing;
private final byte[] line;
private int lineLen = 0;
@@ -46,6 +46,7 @@ class ModemImpl implements Modem, WriteHandler, SerialPortEventListener {
port = new SerialPort(portName);
initialised = new AtomicBoolean(false);
offHook = new Semaphore(1);
writing = new Semaphore(1);
connected = new AtomicBoolean(false);
line = new byte[MAX_LINE_LENGTH];
reliabilityLayer = new ReliabilityLayer(this);
@@ -151,14 +152,28 @@ class ModemImpl implements Modem, WriteHandler, SerialPortEventListener {
}
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 {
port.writeBytes(b);
} catch(SerialPortException e) {
tryToClose(port);
throw new IOException(e.toString());
} finally {
writing.release();
}
}
public void waitForWritesToComplete() throws InterruptedException {
writing.acquire();
writing.release();
}
public void serialEvent(SerialPortEvent ev) {
try {
if(ev.isRXCHAR()) {

View File

@@ -23,6 +23,7 @@ class ReliabilityLayer implements ReadHandler, WriteHandler {
private final BlockingQueue<byte[]> writes;
private volatile boolean valid = true;
private volatile Thread writer = null;
ReliabilityLayer(WriteHandler writeHandler) {
this.writeHandler = writeHandler;
@@ -36,7 +37,7 @@ class ReliabilityLayer implements ReadHandler, WriteHandler {
}
void init() {
new Thread("ReliabilityLayer") {
writer = new Thread("ReliabilityLayer") {
@Override
public void run() {
try {
@@ -58,7 +59,8 @@ class ReliabilityLayer implements ReadHandler, WriteHandler {
valid = false;
}
}
}.start();
};
writer.start();
}
InputStream getInputStream() {
@@ -88,4 +90,9 @@ class ReliabilityLayer implements ReadHandler, WriteHandler {
if(LOG.isLoggable(INFO)) LOG.info("Queueing " + b.length + " bytes");
if(b.length > 0) writes.add(b);
}
public void waitForWritesToComplete() throws InterruptedException {
if(writer != null) writer.join();
writeHandler.waitForWritesToComplete();
}
}

View File

@@ -204,6 +204,10 @@ class Sender {
writeHandler.handleWrite(d.getBuffer());
}
void waitForWritesToComplete() throws InterruptedException {
writeHandler.waitForWritesToComplete();
}
private static class Outstanding {
private final Data data;

View File

@@ -23,6 +23,12 @@ class SenderOutputStream extends OutputStream {
@Override
public void flush() throws IOException {
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

View File

@@ -35,4 +35,8 @@ class SlipEncoder implements WriteHandler {
encoded[encodedLength - 1] = END;
writeHandler.handleWrite(encoded);
}
public void waitForWritesToComplete() throws InterruptedException {
writeHandler.waitForWritesToComplete();
}
}

View File

@@ -5,4 +5,6 @@ import java.io.IOException;
interface WriteHandler {
void handleWrite(byte[] b) throws IOException;
void waitForWritesToComplete() throws InterruptedException;
}