Project

General

Profile

Feature #10052 ยป ruby10052_sized_queue_push_nonblock.diff

herwinw (Herwin Quarantainenet), 07/17/2014 09:49 AM

View differences:

ext/thread/thread.c
443 443
    return vmax;
444 444
}
445 445

  
446
static VALUE
447
szqueue_push_should_block(int argc, VALUE *argv)
448
{
449
    VALUE should_block = Qtrue;
450
    switch (argc) {
451
      case 0:
452
	rb_raise(rb_eArgError, "wrong number of arguments (0 for 1)");
453
	break;
454
      case 1:
455
	break;
456
      case 2:
457
	should_block = RTEST(argv[1]) ? Qfalse : Qtrue;
458
	break;
459
      default:
460
	rb_raise(rb_eArgError, "wrong number of arguments (%d for 2)", argc);
461
    }
462
    return should_block;
463
}
464

  
446 465
/*
447 466
 * Document-method: SizedQueue#push
448 467
 * call-seq:
......
456 475
 */
457 476

  
458 477
static VALUE
459
rb_szqueue_push(VALUE self, VALUE obj)
478
rb_szqueue_push(int argc, VALUE *argv, VALUE self)
460 479
{
461 480
    struct waiting_delete args;
481
    VALUE should_block = szqueue_push_should_block(argc, argv);
462 482
    args.waiting = GET_SZQUEUE_WAITERS(self);
463 483
    args.th      = rb_thread_current();
464 484

  
465 485
    while (queue_length(self) >= GET_SZQUEUE_ULONGMAX(self)) {
486
	if (!(int)should_block) {
487
	    rb_raise(rb_eThreadError, "queue full");
488
	}
466 489
	rb_ary_push(args.waiting, args.th);
467 490
	rb_ensure((VALUE (*)())rb_thread_sleep_deadly, (VALUE)0, queue_delete_from_waiting, (VALUE)&args);
468 491
    }
469
    return queue_do_push(self, obj);
492
    return queue_do_push(self, argv[0]);
470 493
}
471 494

  
472 495
static VALUE
......
598 621
    rb_define_method(rb_cSizedQueue, "initialize", rb_szqueue_initialize, 1);
599 622
    rb_define_method(rb_cSizedQueue, "max", rb_szqueue_max_get, 0);
600 623
    rb_define_method(rb_cSizedQueue, "max=", rb_szqueue_max_set, 1);
601
    rb_define_method(rb_cSizedQueue, "push", rb_szqueue_push, 1);
624
    rb_define_method(rb_cSizedQueue, "push", rb_szqueue_push, -1);
602 625
    rb_define_method(rb_cSizedQueue, "pop", rb_szqueue_pop, -1);
603 626
    rb_define_method(rb_cSizedQueue, "clear", rb_szqueue_clear, 0);
604 627
    rb_define_method(rb_cSizedQueue, "num_waiting", rb_szqueue_num_waiting, 0);