@@ -384,49 +384,53 @@ private Object waitSelect(final int operations, final boolean blocking, final bo
384
384
final SelectionKey key = channel .register (selector , operations );
385
385
386
386
try {
387
- io .addBlockingThread (thread );
388
-
389
387
final int [] result = new int [1 ];
390
388
391
- thread .executeBlockingTask (new RubyThread .BlockingTask () {
392
- public void run () throws InterruptedException {
393
- try {
394
- if ( ! blocking ) {
395
- result [0 ] = selector .selectNow ();
396
-
397
- if ( result [0 ] == 0 ) {
398
- if ((operations & SelectionKey .OP_READ ) != 0 && (operations & SelectionKey .OP_WRITE ) != 0 ) {
399
- if ( key .isReadable () ) {
400
- writeWouldBlock (runtime , exception , result ); return ;
401
- }
402
- //else if ( key.isWritable() ) {
403
- // readWouldBlock(runtime, exception, result);
404
- //}
405
- else { //neither, pick one
406
- readWouldBlock (runtime , exception , result ); return ;
407
- }
408
- }
409
- else if ((operations & SelectionKey .OP_READ ) != 0 ) {
410
- readWouldBlock (runtime , exception , result ); return ;
411
- }
412
- else if ((operations & SelectionKey .OP_WRITE ) != 0 ) {
413
- writeWouldBlock (runtime , exception , result ); return ;
414
- }
389
+ if ( ! blocking ) {
390
+ try {
391
+ result [0 ] = selector .selectNow ();
392
+
393
+ if ( result [0 ] == 0 ) {
394
+ if ((operations & SelectionKey .OP_READ ) != 0 && (operations & SelectionKey .OP_WRITE ) != 0 ) {
395
+ if ( key .isReadable () ) {
396
+ writeWouldBlock (runtime , exception , result );
415
397
}
398
+ //else if ( key.isWritable() ) {
399
+ // readWouldBlock(runtime, exception, result);
400
+ //}
401
+ else { //neither, pick one
402
+ readWouldBlock (runtime , exception , result );
403
+ }
404
+ }
405
+ else if ((operations & SelectionKey .OP_READ ) != 0 ) {
406
+ readWouldBlock (runtime , exception , result );
416
407
}
417
- else {
408
+ else if ((operations & SelectionKey .OP_WRITE ) != 0 ) {
409
+ writeWouldBlock (runtime , exception , result );
410
+ }
411
+ }
412
+ }
413
+ catch (IOException ioe ) {
414
+ throw runtime .newRuntimeError ("Error with selector: " + ioe .getMessage ());
415
+ }
416
+ } else {
417
+ io .addBlockingThread (thread );
418
+ thread .executeBlockingTask (new RubyThread .BlockingTask () {
419
+ public void run () throws InterruptedException {
420
+ try {
418
421
result [0 ] = selector .select ();
419
422
}
423
+ catch (IOException ioe ) {
424
+ throw runtime .newRuntimeError ("Error with selector: " + ioe .getMessage ());
425
+ }
420
426
}
421
- catch (IOException ioe ) {
422
- throw runtime .newRuntimeError ("Error with selector: " + ioe .getMessage ());
427
+
428
+ public void wakeup () {
429
+ selector .wakeup ();
423
430
}
424
- }
431
+ });
432
+ }
425
433
426
- public void wakeup () {
427
- selector .wakeup ();
428
- }
429
- });
430
434
431
435
switch ( result [0 ] ) {
432
436
case READ_WOULD_BLOCK_RESULT :
@@ -435,11 +439,9 @@ public void wakeup() {
435
439
return runtime .newSymbol ("wait_writable" ); // exception: false
436
440
case 0 : return Boolean .FALSE ;
437
441
default :
438
- if ( result [0 ] >= 1 ) {
439
- Set <SelectionKey > keySet = selector .selectedKeys ();
440
- if ( keySet .iterator ().next () == key ) return Boolean .TRUE ;
441
- }
442
- return Boolean .FALSE ;
442
+ //key should always be contained in selectedKeys() here, however there is a bug in
443
+ //JRuby <= 9.1.2.0 that makes this not always the case, so we have to check
444
+ return selector .selectedKeys ().contains (key ) ? Boolean .TRUE : Boolean .FALSE ;
443
445
}
444
446
}
445
447
catch (InterruptedException interrupt ) { return Boolean .FALSE ; }
@@ -469,11 +471,13 @@ public void wakeup() {
469
471
debugStackTrace (runtime , e );
470
472
}
471
473
472
- // remove this thread as a blocker against the given IO
473
- io .removeBlockingThread (thread );
474
+ if (blocking ) {
475
+ // remove this thread as a blocker against the given IO
476
+ io .removeBlockingThread (thread );
474
477
475
- // clear thread state from blocking call
476
- thread .afterBlockingCall ();
478
+ // clear thread state from blocking call
479
+ thread .afterBlockingCall ();
480
+ }
477
481
}
478
482
}
479
483
0 commit comments