ruby-changes:24876
From: kosaki <ko1@a...>
Date: Sun, 9 Sep 2012 15:30:32 +0900 (JST)
Subject: [ruby-changes:24876] kosaki:r36928 (ruby_1_9_3): merge revision(s) 36926:
kosaki 2012-09-09 15:30:21 +0900 (Sun, 09 Sep 2012) New Revision: 36928 http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=36928 Log: merge revision(s) 36926: * thread.c (rb_mutex_lock): stop multiple threads use pthread_cond_timedwait() concurrently. [Bug #6278] [ruby-core:44275] Modified files: branches/ruby_1_9_3/ChangeLog branches/ruby_1_9_3/thread.c branches/ruby_1_9_3/version.h Index: ruby_1_9_3/ChangeLog =================================================================== --- ruby_1_9_3/ChangeLog (revision 36927) +++ ruby_1_9_3/ChangeLog (revision 36928) @@ -1,3 +1,8 @@ +Sun Sep 9 02:30:20 2012 KOSAKI Motohiro <kosaki.motohiro@g...> + + * thread.c (rb_mutex_lock): stop multiple threads use + pthread_cond_timedwait() concurrently. [Bug #6278] [ruby-core:44275] + Thu Aug 30 09:24:43 2012 NARUSE, Yui <naruse@r...> * lib/uri/ftp.rb (URI::FTP#initialize): raise InvalidURIError if "//" Index: ruby_1_9_3/thread.c =================================================================== --- ruby_1_9_3/thread.c (revision 36927) +++ ruby_1_9_3/thread.c (revision 36928) @@ -3532,6 +3532,13 @@ } /* + * At maximum, only one thread can use cond_timedwait and watch deadlock + * periodically. Multiple polling thread (i.e. concurrent deadlock check) + * introduces new race conditions. [Bug #6278] [ruby-core:44275] + */ +rb_thread_t *patrol_thread = NULL; + +/* * call-seq: * mutex.lock -> self * @@ -3568,14 +3575,20 @@ * vm->sleepr is unstable value. we have to avoid both deadlock * and busy loop. */ - if (vm_living_thread_num(th->vm) == th->vm->sleeper) { + if ((vm_living_thread_num(th->vm) == th->vm->sleeper) && + !patrol_thread) { timeout_ms = 100; + patrol_thread = th; } + GVL_UNLOCK_BEGIN(); interrupted = lock_func(th, mutex, timeout_ms); native_mutex_unlock(&mutex->lock); GVL_UNLOCK_END(); + if (patrol_thread == th) + patrol_thread = NULL; + reset_unblock_function(th, &oldubf); th->locking_mutex = Qfalse; @@ -4780,6 +4793,7 @@ if (vm_living_thread_num(vm) > vm->sleeper) return; if (vm_living_thread_num(vm) < vm->sleeper) rb_bug("sleeper must not be more than vm_living_thread_num(vm)"); + if (patrol_thread && patrol_thread != GET_THREAD()) return; st_foreach(vm->living_threads, check_deadlock_i, (st_data_t)&found); Index: ruby_1_9_3/version.h =================================================================== --- ruby_1_9_3/version.h (revision 36927) +++ ruby_1_9_3/version.h (revision 36928) @@ -1,10 +1,10 @@ #define RUBY_VERSION "1.9.3" -#define RUBY_PATCHLEVEL 265 +#define RUBY_PATCHLEVEL 266 -#define RUBY_RELEASE_DATE "2012-08-31" +#define RUBY_RELEASE_DATE "2012-09-09" #define RUBY_RELEASE_YEAR 2012 -#define RUBY_RELEASE_MONTH 8 -#define RUBY_RELEASE_DAY 31 +#define RUBY_RELEASE_MONTH 9 +#define RUBY_RELEASE_DAY 9 #include "ruby/version.h" -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/