Fix race condition on close in GridNioClientConnectionMultiplexer
When `GridNioServer.createSession` is called concurrently with `GridNioServer.stop`, it is possible that `GridNioFuture` returned by `createSession` will never complete. Add RW lock in `GridNioClientConnectionMultiplexer` to fix this.
@@ -23,6 +23,8 @@ import java.nio.ByteOrder;
import java.nio.channels.SocketChannel;
import java.util.HashMap;
import java.util.Map;
+import java.util.concurrent.locks.ReadWriteLock;
+import java.util.concurrent.locks.ReentrantReadWriteLock;
import javax.net.ssl.SSLContext;
import org.apache.ignite.IgniteCheckedException;
@@ -60,6 +62,9 @@ public class GridNioClientConnectionMultiplexer implements ClientConnectionMulti
/** */
private final SSLContext sslCtx;
+ /** */
+ private final ReadWriteLock rwLock = new ReentrantReadWriteLock();
+
/**
* Constructor.
*
@@ -107,19 +112,35 @@ public class GridNioClientConnectionMultiplexer implements ClientConnectionMulti
/** {@inheritDoc} */
@Override public void start() {
+ rwLock.writeLock().lock();
+
+ try {
srv.start();
}
+ finally {
+ rwLock.writeLock().unlock();
+ }
+ }
/** {@inheritDoc} */
- @Override public void stop() {
+ @Override public synchronized void stop() {
+ rwLock.writeLock().lock();
+
+ try {
srv.stop();
}
+ finally {
+ rwLock.writeLock().unlock();
+ }
+ }
/** {@inheritDoc} */
@Override public ClientConnection open(InetSocketAddress addr,
ClientMessageHandler msgHnd,
ClientConnectionStateHandler stateHnd)
throws ClientConnectionException {
+ rwLock.readLock().lock();
+
try {
SocketChannel ch = SocketChannel.open();
ch.socket().connect(new InetSocketAddress(addr.getHostName(), addr.getPort()), Integer.MAX_VALUE);
@@ -143,5 +164,8 @@ public class GridNioClientConnectionMultiplexer implements ClientConnectionMulti
catch (Exception e) {
throw new ClientConnectionException(e.getMessage(), e);
}
+ finally {
+ rwLock.readLock().unlock();
+ }
}
}
