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
importorg.java_websocket.WebSocketImpl;
3636
importorg.java_websocket.WrappedByteChannel;
3737
importorg.java_websocket.drafts.Draft;
38+
importorg.java_websocket.exceptions.InvalidDataException;
3839
importorg.java_websocket.framing.CloseFrame;
3940
importorg.java_websocket.framing.Framedata;
4041
importorg.java_websocket.handshake.ClientHandshake;
4142
importorg.java_websocket.handshake.Handshakedata;
43+
importorg.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
publicvoidstop( inttimeout ) throwsIOException , 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( WebSocketws : connections ){
209-
ws.close( CloseFrame.GOING_AWAY );
210-
}
213+
socketsToClose = newArrayList<WebSocket>( connections );
214+
}
215+
216+
for( WebSocketws : 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+
publicServerHandshakeBuilderonWebsocketHandshakeReceivedAsServer( WebSocketconn, Draftdraft, ClientHandshakerequest ) throwsInvalidDataException{
538+
returnsuper.onWebsocketHandshakeReceivedAsServer( conn, draft, request );
539+
}
540+
528541
/** @see #removeConnection(WebSocket) */
529542
protectedbooleanaddConnection( WebSocketws ){
530-
synchronized ( connections ){
531-
returnthis.connections.add( ws );
543+
if( isclosed.get() ){
544+
synchronized ( connections ){
545+
booleansucc = this.connections.add( ws );
546+
assert ( succ );
547+
returnsucc;
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+
returntrue;// 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)