From 83c20b0bd671f461f13b9294fbbfedc08cbab317 Mon Sep 17 00:00:00 2001 From: lolodomo Date: Fri, 27 Jan 2023 13:23:04 +0100 Subject: [PATCH] [rotel] Fix reader thread handling (#14272) Previous code was not working in Java 17. A thread should not be started after being interrupted. Fix #14264 Signed-off-by: Laurent Garnier --- .../communication/RotelConnector.java | 35 +++++++++++++++---- .../communication/RotelIpConnector.java | 2 +- .../communication/RotelSerialConnector.java | 2 +- .../communication/RotelSimuConnector.java | 2 +- 4 files changed, 31 insertions(+), 10 deletions(-) diff --git a/bundles/org.openhab.binding.rotel/src/main/java/org/openhab/binding/rotel/internal/communication/RotelConnector.java b/bundles/org.openhab.binding.rotel/src/main/java/org/openhab/binding/rotel/internal/communication/RotelConnector.java index 778d11367..4dc0cbc31 100644 --- a/bundles/org.openhab.binding.rotel/src/main/java/org/openhab/binding/rotel/internal/communication/RotelConnector.java +++ b/bundles/org.openhab.binding.rotel/src/main/java/org/openhab/binding/rotel/internal/communication/RotelConnector.java @@ -34,8 +34,11 @@ public abstract class RotelConnector { private final Logger logger = LoggerFactory.getLogger(RotelConnector.class); + private final RotelAbstractProtocolHandler protocolHandler; private final boolean simu; - protected final Thread readerThread; + private final String readerThreadName; + + private @Nullable Thread readerThread; /** The output stream */ protected @Nullable OutputStream dataOut; @@ -54,8 +57,9 @@ public abstract class RotelConnector { * @param readerThreadName the name of thread to be created */ public RotelConnector(RotelAbstractProtocolHandler protocolHandler, boolean simu, String readerThreadName) { + this.protocolHandler = protocolHandler; this.simu = simu; - this.readerThread = new RotelReaderThread(this, protocolHandler, readerThreadName); + this.readerThreadName = readerThreadName; } /** @@ -88,15 +92,32 @@ public abstract class RotelConnector { */ public abstract void close(); + protected void startReaderThread() { + Thread thread = readerThread; + if (thread == null || thread.isInterrupted()) { + thread = new RotelReaderThread(this, protocolHandler, readerThreadName); + readerThread = thread; + thread.start(); + } + } + + protected void stopReaderThread() { + Thread thread = readerThread; + if (thread != null) { + thread.interrupt(); + try { + thread.join(); + } catch (InterruptedException e) { + } + readerThread = null; + } + } + /** * Stop the thread that handles the feedback messages and close the opened input and output streams */ protected void cleanup() { - readerThread.interrupt(); - try { - readerThread.join(); - } catch (InterruptedException e) { - } + stopReaderThread(); OutputStream dataOut = this.dataOut; if (dataOut != null) { try { diff --git a/bundles/org.openhab.binding.rotel/src/main/java/org/openhab/binding/rotel/internal/communication/RotelIpConnector.java b/bundles/org.openhab.binding.rotel/src/main/java/org/openhab/binding/rotel/internal/communication/RotelIpConnector.java index 30b5e58e5..ea971e754 100644 --- a/bundles/org.openhab.binding.rotel/src/main/java/org/openhab/binding/rotel/internal/communication/RotelIpConnector.java +++ b/bundles/org.openhab.binding.rotel/src/main/java/org/openhab/binding/rotel/internal/communication/RotelIpConnector.java @@ -68,7 +68,7 @@ public class RotelIpConnector extends RotelConnector { dataOut = new DataOutputStream(clientSocket.getOutputStream()); dataIn = new DataInputStream(clientSocket.getInputStream()); - readerThread.start(); + startReaderThread(); this.clientSocket = clientSocket; diff --git a/bundles/org.openhab.binding.rotel/src/main/java/org/openhab/binding/rotel/internal/communication/RotelSerialConnector.java b/bundles/org.openhab.binding.rotel/src/main/java/org/openhab/binding/rotel/internal/communication/RotelSerialConnector.java index 47571b0de..1c91803ea 100644 --- a/bundles/org.openhab.binding.rotel/src/main/java/org/openhab/binding/rotel/internal/communication/RotelSerialConnector.java +++ b/bundles/org.openhab.binding.rotel/src/main/java/org/openhab/binding/rotel/internal/communication/RotelSerialConnector.java @@ -94,7 +94,7 @@ public class RotelSerialConnector extends RotelConnector { } } - readerThread.start(); + startReaderThread(); this.serialPort = commPort; this.dataIn = dataIn; diff --git a/bundles/org.openhab.binding.rotel/src/main/java/org/openhab/binding/rotel/internal/communication/RotelSimuConnector.java b/bundles/org.openhab.binding.rotel/src/main/java/org/openhab/binding/rotel/internal/communication/RotelSimuConnector.java index 836cacb08..35c6fabcb 100644 --- a/bundles/org.openhab.binding.rotel/src/main/java/org/openhab/binding/rotel/internal/communication/RotelSimuConnector.java +++ b/bundles/org.openhab.binding.rotel/src/main/java/org/openhab/binding/rotel/internal/communication/RotelSimuConnector.java @@ -132,7 +132,7 @@ public class RotelSimuConnector extends RotelConnector { @Override public synchronized void open() throws RotelException { logger.debug("Opening simulated connection"); - readerThread.start(); + startReaderThread(); setConnected(true); logger.debug("Simulated connection opened"); }