Skip to content

Commit

Permalink
Fix potential race during TcpTransport close
Browse files Browse the repository at this point in the history
Further improve the locking around bind and stop to ensure that once
transport stops and closes serverChannels, no new channels can be added.

Relates to CI failure issue: elastic#37543
  • Loading branch information
henningandersen committed Feb 18, 2019
1 parent f61ee79 commit e1b5047
Showing 1 changed file with 25 additions and 18 deletions.
43 changes: 25 additions & 18 deletions server/src/main/java/org/elasticsearch/transport/TcpTransport.java
Original file line number Diff line number Diff line change
Expand Up @@ -388,28 +388,35 @@ private InetSocketAddress bindToPort(final String name, final InetAddress hostAd
PortsRange portsRange = new PortsRange(port);
final AtomicReference<Exception> lastException = new AtomicReference<>();
final AtomicReference<InetSocketAddress> boundSocket = new AtomicReference<>();
boolean success = portsRange.iterate(portNumber -> {
try {
TcpServerChannel channel = bind(name, new InetSocketAddress(hostAddress, portNumber));
synchronized (serverChannels) {
List<TcpServerChannel> list = serverChannels.get(name);
if (list == null) {
list = new ArrayList<>();
serverChannels.put(name, list);
closeLock.readLock().lock();
try {
if (lifecycle.initialized() == false && lifecycle.started() == false) {
throw new IllegalStateException("transport has been stopped");
}
boolean success = portsRange.iterate(portNumber -> {
try {
TcpServerChannel channel = bind(name, new InetSocketAddress(hostAddress, portNumber));
synchronized (serverChannels) {
List<TcpServerChannel> list = serverChannels.get(name);
if (list == null) {
list = new ArrayList<>();
serverChannels.put(name, list);
}
list.add(channel);
boundSocket.set(channel.getLocalAddress());
}
list.add(channel);
boundSocket.set(channel.getLocalAddress());
} catch (Exception e) {
lastException.set(e);
return false;
}
} catch (Exception e) {
lastException.set(e);
return false;
return true;
});
if (!success) {
throw new BindTransportException("Failed to bind to [" + port + "]", lastException.get());
}
return true;
});
if (!success) {
throw new BindTransportException("Failed to bind to [" + port + "]", lastException.get());
} finally {
closeLock.readLock().unlock();
}

if (logger.isDebugEnabled()) {
logger.debug("Bound profile [{}] to address {{}}", name, NetworkAddress.format(boundSocket.get()));
}
Expand Down

0 comments on commit e1b5047

Please sign in to comment.