Project

General

Profile

Feature #11517 ยป ruby_queue_conditional_pop.patch

jonathanscruz (Jonathan Cruz), 09/09/2015 03:02 PM

View differences:

ChangeLog (working copy)
1
Tue Sep  9 02:33:45 2015  Jonathan Cruz  <jcruz@trustwave.com>
2

  
3
	* thread_sync.c: Update Queue#pop(should_block=true)
4
	  Allow the caller to provide a block that accepts data from the
5
	  queue. Return the first element for which the block returns a
6
	  truthy value, and remove it from the queue.
7

  
1 8
Thu Sep  3 21:12:12 2015  Nobuyoshi Nakada  <nobu@ruby-lang.org>
2 9

  
3 10
	* lib/cgi/session.rb (create_new_id): use SHA512 instead of MD5.
thread_sync.c (working copy)
794 794
static VALUE
795 795
queue_do_pop(VALUE self, int should_block)
796 796
{
797
    VALUE que = GET_QUEUE_QUE(self);
797 798
    struct waiting_delete args;
798 799
    args.waiting = GET_QUEUE_WAITERS(self);
799 800
    args.th	 = rb_thread_current();
800 801

  
801
    while (queue_length(self) == 0) {
802
	if (!should_block) {
803
	    rb_raise(rb_eThreadError, "queue empty");
804
	}
805
	else if (queue_closed_p(self)) {
806
	    return queue_closed_result(self);
807
	}
808
	else {
809
	    assert(queue_length(self) == 0);
810
	    assert(queue_closed_p(self) == 0);
802
   for(;;) {
803
        VALUE obj = 0;
804
        int obj_index = -1;
811 805

  
812
	    rb_ary_push(args.waiting, args.th);
813
	    rb_ensure(queue_sleep, (VALUE)0, queue_delete_from_waiting, (VALUE)&args);
814
	}
806
        if (rb_block_given_p()) {
807
            for (i=0; i < RARRAY_LEN(que); i++) {
808
                obj = RARRAY_AREF(que, i)
809
                if (rb_yield(obj)) {
810
                    obj_index = i;
811
                    break;
812
                }
813
            }
814
        }
815
        else if (RARRAY_LEN(que) > 0) {
816
            return rb_ary_shift(que);
817
        }
818

  
819
        if (obj_index >= 0) {
820
            rb_ary_delete_at(que, obj_index);
821
            return obj;
822
        }
823

  
824
        if (!should_block) {
825
            rb_raise(rb_eThreadError, "queue empty");
826
        }
827
        else if (queue_closed_p(self)) {
828
            return queue_closed_result(self);
829
        }
830
        else {
831
            assert(queue_length(self) == 0);
832
            assert(queue_closed_p(self) == 0);
833

  
834
            rb_ary_push(args.waiting, args.th);
835
            rb_ensure(queue_sleep, (VALUE)0, queue_delete_from_waiting, (VALUE)&args);
836
        }
815 837
    }
816

  
817
    return rb_ary_shift(GET_QUEUE_QUE(self));
818 838
}
819 839

  
820 840
static int
......
835 855
 *   deq(non_block=false)
836 856
 *   shift(non_block=false)
837 857
 *
838
 * Retrieves data from the queue.
858
 * Retrieves data from the queue. If +block+ is given, retrieves data from the
859
 * queue for which the given +block+ returns a true value.
839 860
 *
840
 * If the queue is empty, the calling thread is suspended until data is pushed
841
 * onto the queue. If +non_block+ is true, the thread isn't suspended, and an
842
 * exception is raised.
861
 * If the queue is empty (or +block+ never returns true), the calling thread is
862
 * suspended until data is pushed onto the queue. If +non_block+ is true, the
863
 * thread isn't suspended, and an exception is raised.
843 864
 */
844 865

  
845 866
static VALUE
......
1067 1088
 *   deq(non_block=false)
1068 1089
 *   shift(non_block=false)
1069 1090
 *
1070
 * Retrieves data from the queue.
1091
 * Retrieves data from the queue. If +block+ is given, retrieves data from the
1092
 * queue for which the given +block+ returns a true value.
1071 1093
 *
1072
 * If the queue is empty, the calling thread is suspended until data is pushed
1073
 * onto the queue. If +non_block+ is true, the thread isn't suspended, and an
1074
 * exception is raised.
1094
 * If the queue is empty (or +block+ never returns true), the calling thread is
1095
 * suspended until data is pushed onto the queue. If +non_block+ is true, the
1096
 * thread isn't suspended, and an exception is raised.
1075 1097
 */
1076 1098

  
1077 1099
static VALUE