[enocean] Fix disposal of running tasks (#15329)

* Fix disposal of running tasks

Fixes #15328

---------

Signed-off-by: Jacob Laursen <jacob-github@vindvejr.dk>
This commit is contained in:
Jacob Laursen 2023-07-31 17:10:17 +02:00 committed by GitHub
parent 92238bcb8b
commit a9d6d805f4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 48 additions and 52 deletions

View File

@ -296,10 +296,10 @@ public class EnOceanBaseActuatorHandler extends EnOceanBaseSensorHandler {
@Override
public void dispose() {
ScheduledFuture<?> localRefreshJob = refreshJob;
if (localRefreshJob != null && !localRefreshJob.isCancelled()) {
localRefreshJob.cancel(true);
refreshJob = null;
ScheduledFuture<?> refreshJob = this.refreshJob;
if (refreshJob != null) {
refreshJob.cancel(true);
this.refreshJob = null;
}
}
}

View File

@ -202,9 +202,9 @@ public class EnOceanBaseSensorHandler extends EnOceanBaseThingHandler implements
// fire trigger for receive
triggerChannel(prepareAnswer, "requestAnswer");
// Send response after 100ms
ScheduledFuture<?> localResponseFuture = responseFuture;
if (localResponseFuture == null || localResponseFuture.isDone()) {
localResponseFuture = scheduler.schedule(this::sendRequestResponse, 100, TimeUnit.MILLISECONDS);
ScheduledFuture<?> responseFuture = this.responseFuture;
if (responseFuture == null || responseFuture.isDone()) {
this.responseFuture = scheduler.schedule(this::sendRequestResponse, 100, TimeUnit.MILLISECONDS);
}
}
}

View File

@ -165,17 +165,14 @@ public class EnOceanBridgeHandler extends ConfigStatusBridgeHandler implements T
public void initialize() {
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_PENDING, "trying to connect to gateway...");
ScheduledFuture<?> localConnectorTask = connectorTask;
if (localConnectorTask == null || localConnectorTask.isDone()) {
localConnectorTask = scheduler.scheduleWithFixedDelay(new Runnable() {
@Override
public void run() {
if (thing.getStatus() != ThingStatus.ONLINE) {
initTransceiver();
}
connectorTask = scheduler.scheduleWithFixedDelay(new Runnable() {
@Override
public void run() {
if (thing.getStatus() != ThingStatus.ONLINE) {
initTransceiver();
}
}, 0, 60, TimeUnit.SECONDS);
}
}
}, 0, 60, TimeUnit.SECONDS);
}
private synchronized void initTransceiver() {
@ -303,16 +300,16 @@ public class EnOceanBridgeHandler extends ConfigStatusBridgeHandler implements T
@Override
public synchronized void dispose() {
EnOceanTransceiver localTransceiver = transceiver;
if (localTransceiver != null) {
localTransceiver.shutDown();
transceiver = null;
EnOceanTransceiver transceiver = this.transceiver;
if (transceiver != null) {
transceiver.shutDown();
this.transceiver = null;
}
ScheduledFuture<?> localConnectorTask = connectorTask;
if (localConnectorTask != null && !localConnectorTask.isDone()) {
localConnectorTask.cancel(true);
connectorTask = null;
ScheduledFuture<?> connectorTask = this.connectorTask;
if (connectorTask != null) {
connectorTask.cancel(true);
this.connectorTask = null;
}
super.dispose();

View File

@ -276,13 +276,12 @@ public class EnOceanClassicDeviceHandler extends EnOceanBaseActuatorHandler {
@Override
public void handleRemoval() {
ScheduledFuture<?> future = releaseFuture;
if (future != null && !future.isDone()) {
future.cancel(true);
future = null;
ScheduledFuture<?> releaseFuture = this.releaseFuture;
if (releaseFuture != null) {
releaseFuture.cancel(true);
this.releaseFuture = null;
}
releaseFuture = null;
super.handleRemoval();
}
}

View File

@ -59,7 +59,7 @@ public abstract class EnOceanTransceiver implements SerialPortEventListener {
// Thread management
protected @Nullable Future<?> readingTask = null;
private @Nullable Future<?> timeOut = null;
private @Nullable Future<?> timeOutTask = null;
protected Logger logger = LoggerFactory.getLogger(EnOceanTransceiver.class);
@ -121,14 +121,14 @@ public abstract class EnOceanTransceiver implements SerialPortEventListener {
localOutPutStream.write(b);
localOutPutStream.flush();
}
Future<?> localTimeOut = timeOut;
if (localTimeOut != null) {
localTimeOut.cancel(true);
Future<?> localTimeOutTask = timeOutTask;
if (localTimeOutTask != null) {
localTimeOutTask.cancel(true);
}
// slowdown sending of message to avoid hickups at receivers
// Todo tweak sending intervall (250 ist just a first try)
timeOut = scheduler.schedule(() -> {
timeOutTask = scheduler.schedule(() -> {
try {
sendNext();
} catch (IOException e) {
@ -222,9 +222,9 @@ public abstract class EnOceanTransceiver implements SerialPortEventListener {
public void startReceiving(ScheduledExecutorService scheduler) {
@Nullable
Future<?> localReadingTask = readingTask;
if (localReadingTask == null || localReadingTask.isCancelled()) {
readingTask = scheduler.submit(new Runnable() {
Future<?> readingTask = this.readingTask;
if (readingTask == null || readingTask.isCancelled()) {
this.readingTask = scheduler.submit(new Runnable() {
@Override
public void run() {
receivePackets();
@ -238,14 +238,15 @@ public abstract class EnOceanTransceiver implements SerialPortEventListener {
logger.debug("shutting down transceiver");
logger.debug("Interrupt rx Thread");
Future<?> localTimeOut = timeOut;
if (localTimeOut != null) {
localTimeOut.cancel(true);
Future<?> timeOutTask = this.timeOutTask;
if (timeOutTask != null) {
timeOutTask.cancel(true);
this.timeOutTask = null;
}
Future<?> localReadingTask = readingTask;
if (localReadingTask != null) {
localReadingTask.cancel(true);
Future<?> readingTask = this.readingTask;
if (readingTask != null) {
readingTask.cancel(true);
InputStream localInputStream = inputStream;
if (localInputStream != null) {
@ -255,10 +256,9 @@ public abstract class EnOceanTransceiver implements SerialPortEventListener {
logger.debug("IOException occured while closing the stream", e);
}
}
this.readingTask = null;
}
readingTask = null;
timeOut = null;
listeners.clear();
eventListeners.clear();
teachInListener = null;
@ -298,8 +298,8 @@ public abstract class EnOceanTransceiver implements SerialPortEventListener {
private void receivePackets() {
byte[] buffer = new byte[1];
Future<?> localReadingTask = readingTask;
while (localReadingTask != null && !localReadingTask.isCancelled()) {
Future<?> readingTask = this.readingTask;
while (readingTask != null && !readingTask.isCancelled()) {
int bytesRead = read(buffer, 1);
if (bytesRead > 0) {
processMessage(buffer[0]);
@ -320,10 +320,10 @@ public abstract class EnOceanTransceiver implements SerialPortEventListener {
}
} else {
logger.warn("Cannot read from null stream");
Future<?> localReadingTask = readingTask;
if (localReadingTask != null) {
localReadingTask.cancel(true);
readingTask = null;
Future<?> readingTask = this.readingTask;
if (readingTask != null) {
readingTask.cancel(true);
this.readingTask = null;
}
TransceiverErrorListener localListener = errorListener;
if (localListener != null) {