summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorkosaki <kosaki@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2012-09-09 06:30:21 +0000
committerkosaki <kosaki@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2012-09-09 06:30:21 +0000
commitc2cb8ea3174b60b3b87cd2fa916cf10e6776864b (patch)
tree89b2db52acd9aec8111fe9df7276fddbdfada0d6
parent09729a5693a782bcb7602d93d94bf2268d4f114c (diff)
merge revision(s) 36926:
* thread.c (rb_mutex_lock): stop multiple threads use pthread_cond_timedwait() concurrently. [Bug #6278] [ruby-core:44275] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_1_9_3@36928 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
-rw-r--r--ChangeLog5
-rw-r--r--thread.c16
-rw-r--r--version.h8
3 files changed, 24 insertions, 5 deletions
diff --git a/ChangeLog b/ChangeLog
index ab704cdf6c..16b12421d8 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+Sun Sep 9 02:30:20 2012 KOSAKI Motohiro <kosaki.motohiro@gmail.com>
+
+ * 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@ruby-lang.org>
* lib/uri/ftp.rb (URI::FTP#initialize): raise InvalidURIError if "//"
diff --git a/thread.c b/thread.c
index 342d4fe22a..eb0be9f1d0 100644
--- a/thread.c
+++ b/thread.c
@@ -3532,6 +3532,13 @@ lock_interrupt(void *ptr)
}
/*
+ * 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 @@ rb_mutex_lock(VALUE self)
* 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 @@ rb_check_deadlock(rb_vm_t *vm)
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);
diff --git a/version.h b/version.h
index f58c666919..21d1dee5d4 100644
--- a/version.h
+++ b/version.h
@@ -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"