return;
}
try {
while ( !selectorthread.isInterrupted() ) {
SelectionKey key = null;
WebSocketImpl conn = null;
try {
selector.select();
Set<SelectionKey> keys = selector.selectedKeys();
Iterator<SelectionKey> i = keys.iterator();
while ( i.hasNext() ) {
key = i.next();
if( !key.isValid() ) {
// Object o = key.attachment();
continue;
}
if( key.isAcceptable() ) {
if( !onConnect( key ) ) {
key.cancel();
continue;
}
SocketChannel channel = server.accept();
channel.configureBlocking( false );
WebSocketImpl w = wsf.createWebSocket( this, drafts, channel.socket() );
w.key = channel.register( selector, SelectionKey.OP_READ, w );
w.channel = wsf.wrapChannel( channel, w.key );
i.remove();
allocateBuffers( w );
continue;
}
if( key.isReadable() ) {
conn = (WebSocketImpl) key.attachment();
ByteBuffer buf = takeBuffer();
try {
if( SocketChannelIOHelper.read( buf, conn, conn.channel ) ) {
if( buf.hasRemaining() ) {
conn.inQueue.put( buf );
queue( conn );
i.remove();
if( conn.channel instanceof WrappedByteChannel ) {
if( ( (WrappedByteChannel) conn.channel ).isNeedRead() ) {
iqueue.add( conn );
}
}
} else
pushBuffer( buf );
} else {
pushBuffer( buf );
}
} catch ( IOException e ) {
pushBuffer( buf );
throw e;
}
}
if( key.isWritable() ) {
conn = (WebSocketImpl) key.attachment();
if( SocketChannelIOHelper.batch( conn, conn.channel ) ) {
if( key.isValid() )
key.interestOps( SelectionKey.OP_READ );
}
}
}
while ( !iqueue.isEmpty() ) {
conn = iqueue.remove( 0 );
WrappedByteChannel c = ( (WrappedByteChannel) conn.channel );
ByteBuffer buf = takeBuffer();
try {
if( SocketChannelIOHelper.readMore( buf, conn, c ) )
iqueue.add( conn );
if( buf.hasRemaining() ) {
conn.inQueue.put( buf );
queue( conn );
} else {
pushBuffer( buf );
}
} catch ( IOException e ) {
pushBuffer( buf );
throw e;
}
}
} catch ( CancelledKeyException e ) {
// an other thread may cancel the key
} catch ( ClosedByInterruptException e ) {
return; // do the same stuff as when InterruptedException is thrown
} catch ( IOException ex ) {
if( key != null )
key.cancel();
handleIOException( key, conn, ex );
} catch ( InterruptedException e ) {
return;// FIXME controlled shutdown (e.g. take care of buffermanagement)
}
}
} catch ( RuntimeException e ) {
// should hopefully never occur
handleFatal( null, e );
} finally {
if( decoders != null ) {
for( WebSocketWorker w : decoders ) {
w.interrupt();
}
}
if( server != null ) {
try {
server.close();