This is an automated email from the ASF dual-hosted git repository.
hutcheb pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/plc4x.git
The following commit(s) were added to refs/heads/develop by this push:
new ab6aa8ddba Fix race condition causing RejectedExecutionException on
PlcConnection.close() (#1151)
ab6aa8ddba is described below
commit ab6aa8ddba8417e140e18dba86b4641e9c3afc22
Author: Rajmund Takács <[email protected]>
AuthorDate: Mon Oct 16 19:20:40 2023 +0200
Fix race condition causing RejectedExecutionException on
PlcConnection.close() (#1151)
The remote end might actively close the connection as a response to
disconnect event,
which can cause the Netty channel to be already closed when we want to
explicitly
close it on our side.
Can be easily tested in OPC-UA driver, with a few seconds delay added
before the
original code block:
```java
Thread.sleep(10000); // <-- delay
channel.pipeline().fireUserEventTriggered(new CloseConnectionEvent());
channel.close().awaitUninterruptibly();
```
---
.../java/spi/connection/DefaultNettyPlcConnection.java | 15 +++++++++++++--
1 file changed, 13 insertions(+), 2 deletions(-)
diff --git
a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/connection/DefaultNettyPlcConnection.java
b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/connection/DefaultNettyPlcConnection.java
index 5444609721..0ee4e6cf71 100644
---
a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/connection/DefaultNettyPlcConnection.java
+++
b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/connection/DefaultNettyPlcConnection.java
@@ -19,6 +19,7 @@
package org.apache.plc4x.java.spi.connection;
import io.netty.channel.*;
+import java.util.concurrent.RejectedExecutionException;
import org.apache.plc4x.java.api.EventPlcConnection;
import org.apache.plc4x.java.api.authentication.PlcAuthentication;
import org.apache.plc4x.java.api.exceptions.PlcConnectionException;
@@ -171,8 +172,18 @@ public class DefaultNettyPlcConnection extends
AbstractPlcConnection implements
} catch (Exception e) {
logger.error("Timeout while trying to close connection");
}
- channel.pipeline().fireUserEventTriggered(new CloseConnectionEvent());
- channel.close().awaitUninterruptibly();
+
+ // The channel might have already been closed by the remote end.
+ if (channel.isOpen()) {
+ try {
+ channel.pipeline().fireUserEventTriggered(new
CloseConnectionEvent());
+ channel.close().awaitUninterruptibly();
+ } catch (RejectedExecutionException ex) {
+ if (channel.isOpen()) {
+ throw ex;
+ }
+ }
+ }
if (!sessionDisconnectCompleteFuture.isDone()) {
sessionDisconnectCompleteFuture.complete(null);