ruby-changes:11425
From: shyouhei <ko1@a...>
Date: Mon, 23 Mar 2009 19:18:01 +0900 (JST)
Subject: [ruby-changes:11425] Ruby:r23049 (ruby_1_8_7): merge revision(s) 22011:
shyouhei 2009-03-23 19:17:50 +0900 (Mon, 23 Mar 2009) New Revision: 23049 http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=23049 Log: merge revision(s) 22011: * ext/thread/thread.c (rb_queue_pop, rb_queue_push): should not lock mutex if got an exception while waiting, and should ensure unlocked after signaled. [ruby-dev:37545] Modified files: branches/ruby_1_8_7/ChangeLog branches/ruby_1_8_7/ext/thread/thread.c branches/ruby_1_8_7/test/thread/test_thread.rb branches/ruby_1_8_7/version.h Index: ruby_1_8_7/ext/thread/thread.c =================================================================== --- ruby_1_8_7/ext/thread/thread.c (revision 23048) +++ ruby_1_8_7/ext/thread/thread.c (revision 23049) @@ -440,6 +440,12 @@ } static VALUE +lock_mutex_call(VALUE mutex) +{ + return lock_mutex((Mutex *)mutex); +} + +static VALUE rb_mutex_lock(VALUE self) { Mutex *mutex; @@ -492,6 +498,12 @@ } static VALUE +unlock_mutex_call(VALUE mutex) +{ + return unlock_mutex((Mutex *)mutex); +} + +static VALUE rb_mutex_unlock(VALUE self) { Mutex *mutex; @@ -644,9 +656,18 @@ * */ +static void condvar_wakeup(Mutex *mutex); + static void wait_condvar(ConditionVariable *condvar, Mutex *mutex) { + condvar_wakeup(mutex); + rb_ensure(wait_list, (VALUE)&condvar->waiting, lock_mutex_call, (VALUE)mutex); +} + +static void +condvar_wakeup(Mutex *mutex) +{ VALUE waking; rb_thread_critical = 1; @@ -658,7 +679,6 @@ if (RTEST(waking)) { wake_thread(waking); } - rb_ensure(wait_list, (VALUE)&condvar->waiting, lock_mutex, (VALUE)mutex); } static VALUE @@ -741,6 +761,13 @@ } static VALUE +signal_condvar_call(VALUE condvar) +{ + signal_condvar((ConditionVariable *)condvar); + return Qundef; +} + +static VALUE rb_condvar_signal(VALUE self) { ConditionVariable *condvar; @@ -964,6 +991,16 @@ return result; } +static void +wait_queue(ConditionVariable *condvar, Mutex *mutex) +{ + condvar_wakeup(mutex); + wait_list(&condvar->waiting); + lock_mutex(mutex); +} + +static VALUE queue_pop_inner(VALUE arg); + /* * Document-method: pop * call_seq: pop(non_block=false) @@ -979,7 +1016,6 @@ { Queue *queue; int should_block; - VALUE result; Data_Get_Struct(self, Queue, queue); if (argc == 0) { @@ -997,15 +1033,21 @@ } while (!queue->values.entries) { - wait_condvar(&queue->value_available, &queue->mutex); + wait_queue(&queue->value_available, &queue->mutex); } - result = shift_list(&queue->values); + return rb_ensure(queue_pop_inner, (VALUE)queue, + unlock_mutex_call, (VALUE)&queue->mutex); +} + +static VALUE +queue_pop_inner(VALUE arg) +{ + Queue *queue = (Queue *)arg; + VALUE result = shift_list(&queue->values); if (queue->capacity && queue->values.size < queue->capacity) { signal_condvar(&queue->space_available); } - unlock_mutex(&queue->mutex); - return result; } @@ -1025,11 +1067,11 @@ lock_mutex(&queue->mutex); while (queue->capacity && queue->values.size >= queue->capacity) { - wait_condvar(&queue->space_available, &queue->mutex); + wait_queue(&queue->space_available, &queue->mutex); } push_list(&queue->values, value); - signal_condvar(&queue->value_available); - unlock_mutex(&queue->mutex); + rb_ensure(signal_condvar_call, (VALUE)&queue->value_available, + unlock_mutex_call, (VALUE)&queue->mutex); return self; } Index: ruby_1_8_7/ChangeLog =================================================================== --- ruby_1_8_7/ChangeLog (revision 23048) +++ ruby_1_8_7/ChangeLog (revision 23049) @@ -1,3 +1,9 @@ +Mon Mar 23 19:17:06 2009 Nobuyoshi Nakada <nobu@r...> + + * ext/thread/thread.c (rb_queue_pop, rb_queue_push): should not lock + mutex if got an exception while waiting, and should ensure unlocked + after signaled. [ruby-dev:37545] + Mon Mar 23 18:26:57 2009 Nobuyoshi Nakada <nobu@r...> * eval.c (rb_thread_value): missed to change at r17874. [ruby-core:17595] Index: ruby_1_8_7/version.h =================================================================== --- ruby_1_8_7/version.h (revision 23048) +++ ruby_1_8_7/version.h (revision 23049) @@ -2,7 +2,7 @@ #define RUBY_RELEASE_DATE "2009-03-23" #define RUBY_VERSION_CODE 187 #define RUBY_RELEASE_CODE 20090323 -#define RUBY_PATCHLEVEL 152 +#define RUBY_PATCHLEVEL 153 #define RUBY_VERSION_MAJOR 1 #define RUBY_VERSION_MINOR 8 Index: ruby_1_8_7/test/thread/test_thread.rb =================================================================== --- ruby_1_8_7/test/thread/test_thread.rb (revision 23048) +++ ruby_1_8_7/test/thread/test_thread.rb (revision 23049) @@ -77,5 +77,14 @@ assert_equal("exit.", result[/.*\Z/], '[ruby-dev:30653]') } end + + def test_queue_rescue + require "timeout" + queue = Queue.new + assert_raises(Timeout::Error) {Timeout.timeout(0.001) {queue.pop}} + queue.push(1) + assert_nothing_raised("[ruby-dev:37545]") {assert_equal(1, queue.pop)} + assert(queue.empty?) + end end -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/