[enocean] Fix concurrency exception on startup (#11408)

* made listeners a ConcurrentHashMap
* synchronized access to listeners and eventListeners collections of EnOceanTransceiver
* reverted ConcurrentHashMap change as NULL-Key is required

Fixes #11393

Also-by: Daniel Weber <uni@fruggy.de>
Signed-off-by: Thomas Lauterbach <lauterbachthomas@gmail.com>
This commit is contained in:
Thomas Lauterbach 2021-10-21 00:08:18 +02:00 committed by GitHub
parent d7df7a698d
commit 9cc3f441fd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 13 additions and 8 deletions

View File

@ -220,6 +220,7 @@ public abstract class EnOceanTransceiver implements SerialPortEventListener {
readingTask = null; readingTask = null;
timeOut = null; timeOut = null;
listeners.clear(); listeners.clear();
eventListeners.clear();
teachInListener = null; teachInListener = null;
errorListener = null; errorListener = null;
@ -302,9 +303,11 @@ public abstract class EnOceanTransceiver implements SerialPortEventListener {
} }
long s = Long.parseLong(HexUtils.bytesToHex(senderId), 16); long s = Long.parseLong(HexUtils.bytesToHex(senderId), 16);
HashSet<PacketListener> pl = listeners.get(s); synchronized (this) {
if (pl != null) { HashSet<PacketListener> pl = listeners.get(s);
pl.forEach(l -> l.packetReceived(msg)); if (pl != null) {
pl.forEach(l -> l.packetReceived(msg));
}
} }
} }
} else { } else {
@ -331,7 +334,9 @@ public abstract class EnOceanTransceiver implements SerialPortEventListener {
} }
} }
eventListeners.forEach(l -> l.eventReceived(event)); synchronized (this) {
eventListeners.forEach(l -> l.eventReceived(event));
}
} }
} catch (Exception e) { } catch (Exception e) {
logger.error("Exception in informListeners", e); logger.error("Exception in informListeners", e);
@ -374,13 +379,13 @@ public abstract class EnOceanTransceiver implements SerialPortEventListener {
protected abstract byte[] serializePacket(BasePacket packet) throws EnOceanException; protected abstract byte[] serializePacket(BasePacket packet) throws EnOceanException;
public void addPacketListener(PacketListener listener, long senderIdToListenTo) { public synchronized void addPacketListener(PacketListener listener, long senderIdToListenTo) {
if (listeners.computeIfAbsent(senderIdToListenTo, k -> new HashSet<>()).add(listener)) { if (listeners.computeIfAbsent(senderIdToListenTo, k -> new HashSet<>()).add(listener)) {
logger.debug("Listener added: {}", senderIdToListenTo); logger.debug("Listener added: {}", senderIdToListenTo);
} }
} }
public void removePacketListener(PacketListener listener, long senderIdToListenTo) { public synchronized void removePacketListener(PacketListener listener, long senderIdToListenTo) {
HashSet<PacketListener> pl = listeners.get(senderIdToListenTo); HashSet<PacketListener> pl = listeners.get(senderIdToListenTo);
if (pl != null) { if (pl != null) {
pl.remove(listener); pl.remove(listener);
@ -390,11 +395,11 @@ public abstract class EnOceanTransceiver implements SerialPortEventListener {
} }
} }
public void addEventMessageListener(EventListener listener) { public synchronized void addEventMessageListener(EventListener listener) {
eventListeners.add(listener); eventListeners.add(listener);
} }
public void removeEventMessageListener(EventListener listener) { public synchronized void removeEventMessageListener(EventListener listener) {
eventListeners.remove(listener); eventListeners.remove(listener);
} }