diff options
author | nobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2013-10-05 02:21:12 +0000 |
---|---|---|
committer | nobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2013-10-05 02:21:12 +0000 |
commit | 57b8687debea4e532898cdf0380d63bb62749b9a (patch) | |
tree | 748f2ba1d9f13dbbda58037652357afa4e1dc89f /thread.c | |
parent | a10c9a0e7660cfe9022a3ee74d048355518426f7 (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.c | 32 |
1 files changed, 26 insertions, 6 deletions
@@ -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; |