Feature #11517 ยป ruby_queue_conditional_pop.patch
ChangeLog (working copy) | ||
---|---|---|
Tue Sep 9 02:33:45 2015 Jonathan Cruz <jcruz@trustwave.com>
|
||
* thread_sync.c: Update Queue#pop(should_block=true)
|
||
Allow the caller to provide a block that accepts data from the
|
||
queue. Return the first element for which the block returns a
|
||
truthy value, and remove it from the queue.
|
||
Thu Sep 3 21:12:12 2015 Nobuyoshi Nakada <nobu@ruby-lang.org>
|
||
* lib/cgi/session.rb (create_new_id): use SHA512 instead of MD5.
|
thread_sync.c (working copy) | ||
---|---|---|
static VALUE
|
||
queue_do_pop(VALUE self, int should_block)
|
||
{
|
||
VALUE que = GET_QUEUE_QUE(self);
|
||
struct waiting_delete args;
|
||
args.waiting = GET_QUEUE_WAITERS(self);
|
||
args.th = rb_thread_current();
|
||
while (queue_length(self) == 0) {
|
||
if (!should_block) {
|
||
rb_raise(rb_eThreadError, "queue empty");
|
||
}
|
||
else if (queue_closed_p(self)) {
|
||
return queue_closed_result(self);
|
||
}
|
||
else {
|
||
assert(queue_length(self) == 0);
|
||
assert(queue_closed_p(self) == 0);
|
||
for(;;) {
|
||
VALUE obj = 0;
|
||
int obj_index = -1;
|
||
rb_ary_push(args.waiting, args.th);
|
||
rb_ensure(queue_sleep, (VALUE)0, queue_delete_from_waiting, (VALUE)&args);
|
||
}
|
||
if (rb_block_given_p()) {
|
||
for (i=0; i < RARRAY_LEN(que); i++) {
|
||
obj = RARRAY_AREF(que, i)
|
||
if (rb_yield(obj)) {
|
||
obj_index = i;
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
else if (RARRAY_LEN(que) > 0) {
|
||
return rb_ary_shift(que);
|
||
}
|
||
if (obj_index >= 0) {
|
||
rb_ary_delete_at(que, obj_index);
|
||
return obj;
|
||
}
|
||
if (!should_block) {
|
||
rb_raise(rb_eThreadError, "queue empty");
|
||
}
|
||
else if (queue_closed_p(self)) {
|
||
return queue_closed_result(self);
|
||
}
|
||
else {
|
||
assert(queue_length(self) == 0);
|
||
assert(queue_closed_p(self) == 0);
|
||
rb_ary_push(args.waiting, args.th);
|
||
rb_ensure(queue_sleep, (VALUE)0, queue_delete_from_waiting, (VALUE)&args);
|
||
}
|
||
}
|
||
return rb_ary_shift(GET_QUEUE_QUE(self));
|
||
}
|
||
static int
|
||
... | ... | |
* deq(non_block=false)
|
||
* shift(non_block=false)
|
||
*
|
||
* Retrieves data from the queue.
|
||
* Retrieves data from the queue. If +block+ is given, retrieves data from the
|
||
* queue for which the given +block+ returns a true value.
|
||
*
|
||
* If the queue is empty, the calling thread is suspended until data is pushed
|
||
* onto the queue. If +non_block+ is true, the thread isn't suspended, and an
|
||
* exception is raised.
|
||
* If the queue is empty (or +block+ never returns true), the calling thread is
|
||
* suspended until data is pushed onto the queue. If +non_block+ is true, the
|
||
* thread isn't suspended, and an exception is raised.
|
||
*/
|
||
static VALUE
|
||
... | ... | |
* deq(non_block=false)
|
||
* shift(non_block=false)
|
||
*
|
||
* Retrieves data from the queue.
|
||
* Retrieves data from the queue. If +block+ is given, retrieves data from the
|
||
* queue for which the given +block+ returns a true value.
|
||
*
|
||
* If the queue is empty, the calling thread is suspended until data is pushed
|
||
* onto the queue. If +non_block+ is true, the thread isn't suspended, and an
|
||
* exception is raised.
|
||
* If the queue is empty (or +block+ never returns true), the calling thread is
|
||
* suspended until data is pushed onto the queue. If +non_block+ is true, the
|
||
* thread isn't suspended, and an exception is raised.
|
||
*/
|
||
static VALUE
|