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