From 30753d70b8a54a5c90e64cb0767f234e7039a83b Mon Sep 17 00:00:00 2001 From: Marcus Better Date: Mon, 11 Oct 2021 15:44:44 -0400 Subject: [PATCH] [upb] Fix race condition (#11366) There was a harmless race condition between a message being written and the PIM being initalized to message mode by the binding. This adds a latch to ensure writes happen after initalization. Signed-off-by: Marcus Better --- .../upb/internal/handler/SerialIoThread.java | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/bundles/org.openhab.binding.upb/src/main/java/org/openhab/binding/upb/internal/handler/SerialIoThread.java b/bundles/org.openhab.binding.upb/src/main/java/org/openhab/binding/upb/internal/handler/SerialIoThread.java index 813f95aa5..24248fdd5 100644 --- a/bundles/org.openhab.binding.upb/src/main/java/org/openhab/binding/upb/internal/handler/SerialIoThread.java +++ b/bundles/org.openhab.binding.upb/src/main/java/org/openhab/binding/upb/internal/handler/SerialIoThread.java @@ -60,7 +60,19 @@ public class SerialIoThread extends Thread { private final MessageListener listener; // Single-threaded executor for writes that serves to serialize writes. private final ExecutorService writeExecutor = new ThreadPoolExecutor(1, 1, 30, TimeUnit.SECONDS, - new LinkedBlockingQueue<>(WRITE_QUEUE_LENGTH), new NamedThreadFactory("upb-serial-writer", true)); + new LinkedBlockingQueue<>(WRITE_QUEUE_LENGTH), new NamedThreadFactory("upb-serial-writer", true)) { + @Override + protected void beforeExecute(final @Nullable Thread t, final @Nullable Runnable r) { + // ensure we have prepared the PIM before allowing any writes + super.beforeExecute(t, r); + try { + initialized.await(); + } catch (final InterruptedException e) { + t.interrupt(); + } + } + }; + private final CountDownLatch initialized = new CountDownLatch(1); private final SerialPort serialPort; private volatile @Nullable WriteRunnable currentWrite; @@ -202,6 +214,9 @@ public class SerialIoThread extends Thread { out.flush(); } catch (final IOException e) { logger.warn("error setting message mode", e); + } finally { + // signal that writes can proceed + initialized.countDown(); } }