Skip to content

Commit 2b0bb8d

Browse files
committed
fixed deadlock in server( TooTallNate#195 ) thanks @DeHecht for isolating the
problem
1 parent e927c29 commit 2b0bb8d

File tree

1 file changed

+27
-7
lines changed

1 file changed

+27
-7
lines changed

src/main/java/org/java_websocket/server/WebSocketServer.java

Lines changed: 27 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -35,10 +35,12 @@
3535
import org.java_websocket.WebSocketImpl;
3636
import org.java_websocket.WrappedByteChannel;
3737
import org.java_websocket.drafts.Draft;
38+
import org.java_websocket.exceptions.InvalidDataException;
3839
import org.java_websocket.framing.CloseFrame;
3940
import org.java_websocket.framing.Framedata;
4041
import org.java_websocket.handshake.ClientHandshake;
4142
import org.java_websocket.handshake.Handshakedata;
43+
import org.java_websocket.handshake.ServerHandshakeBuilder;
4244

4345
/**
4446
* <tt>WebSocketServer</tt> is an abstract class that only takes care of the
@@ -200,15 +202,21 @@ public void start() {
200202
* @throws InterruptedException
201203
*/
202204
public void stop( int timeout ) throws IOException , InterruptedException {
203-
if( !isclosed.compareAndSet( false, true ) ) {
205+
if( !isclosed.compareAndSet( false, true ) ) { // this also makes sure that no further connections will be added to this.connections
204206
return;
205207
}
206208

209+
List<WebSocket> socketsToClose = null;
210+
211+
// copy the connections in a list (prevent callback deadlocks)
207212
synchronized ( connections ) {
208-
for( WebSocket ws : connections ) {
209-
ws.close( CloseFrame.GOING_AWAY );
210-
}
213+
socketsToClose = new ArrayList<WebSocket>( connections );
214+
}
215+
216+
for( WebSocket ws : socketsToClose ) {
217+
ws.close( CloseFrame.GOING_AWAY );
211218
}
219+
212220
synchronized ( this ) {
213221
if( selectorthread != null ) {
214222
if( Thread.currentThread() != selectorthread ) {
@@ -525,13 +533,25 @@ protected boolean removeConnection( WebSocket ws ) {
525533
}
526534
}
527535

536+
@Override
537+
public ServerHandshakeBuilder onWebsocketHandshakeReceivedAsServer( WebSocket conn, Draft draft, ClientHandshake request ) throws InvalidDataException {
538+
return super.onWebsocketHandshakeReceivedAsServer( conn, draft, request );
539+
}
540+
528541
/** @see #removeConnection(WebSocket) */
529542
protected boolean addConnection( WebSocket ws ) {
530-
synchronized ( connections ) {
531-
return this.connections.add( ws );
543+
if( isclosed.get() ) {
544+
synchronized ( connections ) {
545+
boolean succ = this.connections.add( ws );
546+
assert ( succ );
547+
return succ;
548+
}
549+
} else {
550+
// This case will happen when a new connection gets ready while the server is already stopping.
551+
ws.close( CloseFrame.GOING_AWAY );
552+
return true;// for consistency sake we will make sure that both onOpen will be called
532553
}
533554
}
534-
535555
/**
536556
* @param conn
537557
* may be null if the error does not belong to a single connection

0 commit comments

Comments
 (0)