From e29d501011e701ab14e89bd5820f33bfb47bbbf1 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Bal=C3=A1zs=20P=C3=B3ka?=
Date: Thu, 1 Jan 2026 18:41:13 +0100
Subject: [PATCH] fix possible concurrency issues with listener registrations
---
src/main/java/cz/smarteon/loxone/Loxone.java | 4 ++--
src/main/java/cz/smarteon/loxone/LoxoneAuth.java | 4 ++--
src/main/java/cz/smarteon/loxone/LoxoneWebSocket.java | 10 +++++-----
3 files changed, 9 insertions(+), 9 deletions(-)
diff --git a/src/main/java/cz/smarteon/loxone/Loxone.java b/src/main/java/cz/smarteon/loxone/Loxone.java
index b398d88..49407e6 100644
--- a/src/main/java/cz/smarteon/loxone/Loxone.java
+++ b/src/main/java/cz/smarteon/loxone/Loxone.java
@@ -15,9 +15,9 @@
import java.util.ArrayList;
import java.util.HashMap;
-import java.util.LinkedList;
import java.util.List;
import java.util.Map;
+import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import java.util.function.Function;
@@ -48,7 +48,7 @@ public class Loxone {
private final LoxoneWebSocket loxoneWebSocket;
private final LoxoneAuth loxoneAuth;
- private final List loxoneAppListeners = new LinkedList<>();
+ private final List loxoneAppListeners = new CopyOnWriteArrayList<>();
private final LoxoneWebSocketListener webSocketListener = this::start;
private final Map clientMiniserversHttp = new HashMap<>();
diff --git a/src/main/java/cz/smarteon/loxone/LoxoneAuth.java b/src/main/java/cz/smarteon/loxone/LoxoneAuth.java
index 3bd0e15..3cb10de 100644
--- a/src/main/java/cz/smarteon/loxone/LoxoneAuth.java
+++ b/src/main/java/cz/smarteon/loxone/LoxoneAuth.java
@@ -16,10 +16,10 @@
import javax.crypto.SecretKey;
import java.security.PublicKey;
import java.security.SecureRandom;
-import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
@@ -103,7 +103,7 @@ public LoxoneAuth(@NotNull LoxoneHttp loxoneHttp, @NotNull LoxoneProfile profile
this.getKeyCommand = getKey(profile.getUsername());
this.getVisuHashCommand = LoxoneMessageCommand.getVisuHash(profile.getUsername());
- this.authListeners = new LinkedList<>();
+ this.authListeners = new CopyOnWriteArrayList<>();
}
@Deprecated
diff --git a/src/main/java/cz/smarteon/loxone/LoxoneWebSocket.java b/src/main/java/cz/smarteon/loxone/LoxoneWebSocket.java
index 8f57f51..5bc3c10 100644
--- a/src/main/java/cz/smarteon/loxone/LoxoneWebSocket.java
+++ b/src/main/java/cz/smarteon/loxone/LoxoneWebSocket.java
@@ -17,14 +17,14 @@
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.util.Collection;
-import java.util.HashSet;
import java.util.Iterator;
-import java.util.LinkedList;
import java.util.List;
import java.util.NoSuchElementException;
import java.util.Queue;
import java.util.Set;
import java.util.concurrent.ConcurrentLinkedQueue;
+import java.util.concurrent.CopyOnWriteArrayList;
+import java.util.concurrent.CopyOnWriteArraySet;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
@@ -89,9 +89,9 @@ public LoxoneWebSocket(final @NotNull LoxoneEndpoint endpoint, final @NotNull Lo
this.webSocketClientProvider = requireNonNull(webSocketClientProvider,
"webSocketClientProvider shouldn't be null");
- this.webSocketListeners = new HashSet<>();
- this.commandResponseListeners = new LinkedList<>();
- this.eventListeners = new LinkedList<>();
+ this.webSocketListeners = new CopyOnWriteArraySet<>();
+ this.commandResponseListeners = new CopyOnWriteArrayList<>();
+ this.eventListeners = new CopyOnWriteArrayList<>();
this.commands = new ConcurrentLinkedQueue<>();
// link loxoneAuth as command listener