summaryrefslogtreecommitdiff
path: root/thread.c
diff options
context:
space:
mode:
authornobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2013-10-05 02:21:12 +0000
committernobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2013-10-05 02:21:12 +0000
commit57b8687debea4e532898cdf0380d63bb62749b9a (patch)
tree748f2ba1d9f13dbbda58037652357afa4e1dc89f /thread.c
parenta10c9a0e7660cfe9022a3ee74d048355518426f7 (diff)
thread.c: fix some mutexes remaining locked after forking
* thread.c (terminate_atfork_i): fix locking mutexes not unlocked in forks when not tracked in thread. [ruby-core:55102] [Bug #8433] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@43148 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'thread.c')
-rw-r--r--thread.c32
1 files changed, 26 insertions, 6 deletions
diff --git a/thread.c b/thread.c
index ea11ee064c..463f5d3b0e 100644
--- a/thread.c
+++ b/thread.c
@@ -396,6 +396,8 @@ typedef struct rb_mutex_struct
} rb_mutex_t;
static void rb_mutex_abandon_all(rb_mutex_t *mutexes);
+static void rb_mutex_abandon_keeping_mutexes(rb_thread_t *th);
+static void rb_mutex_abandon_locking_mutex(rb_thread_t *th);
static const char* rb_mutex_unlock_th(rb_mutex_t *mutex, rb_thread_t volatile *th);
void
@@ -3892,10 +3894,8 @@ terminate_atfork_i(st_data_t key, st_data_t val, st_data_t current_th)
GetThreadPtr(thval, th);
if (th != (rb_thread_t *)current_th) {
- if (th->keeping_mutexes) {
- rb_mutex_abandon_all(th->keeping_mutexes);
- }
- th->keeping_mutexes = NULL;
+ rb_mutex_abandon_keeping_mutexes(th);
+ rb_mutex_abandon_locking_mutex(th);
thread_cleanup_func(th, TRUE);
}
return ST_CONTINUE;
@@ -4155,8 +4155,6 @@ thgroup_add(VALUE group, VALUE thread)
#define GetMutexPtr(obj, tobj) \
TypedData_Get_Struct((obj), rb_mutex_t, &mutex_data_type, (tobj))
-static const char *rb_mutex_unlock_th(rb_mutex_t *mutex, rb_thread_t volatile *th);
-
#define mutex_mark NULL
static void
@@ -4488,6 +4486,28 @@ rb_mutex_unlock(VALUE self)
}
static void
+rb_mutex_abandon_keeping_mutexes(rb_thread_t *th)
+{
+ if (th->keeping_mutexes) {
+ rb_mutex_abandon_all(th->keeping_mutexes);
+ }
+ th->keeping_mutexes = NULL;
+}
+
+static void
+rb_mutex_abandon_locking_mutex(rb_thread_t *th)
+{
+ rb_mutex_t *mutex;
+
+ if (!th->locking_mutex) return;
+
+ GetMutexPtr(th->locking_mutex, mutex);
+ if (mutex->th == th)
+ rb_mutex_abandon_all(mutex);
+ th->locking_mutex = Qfalse;
+}
+
+static void
rb_mutex_abandon_all(rb_mutex_t *mutexes)
{
rb_mutex_t *mutex;