summaryrefslogtreecommitdiff
path: root/thread.c
diff options
context:
space:
mode:
authornagachika <nagachika@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2014-02-19 16:28:06 +0000
committernagachika <nagachika@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2014-02-19 16:28:06 +0000
commit579f47111a0ed9271698d3224ba07a5f7ebf2252 (patch)
treeab12dc58ad9dd58be6f9d89a57ca04af93dc6086 /thread.c
parentc143700f35ac45e097618ee699477c075667b36f (diff)
downloadruby-579f47111a0ed9271698d3224ba07a5f7ebf2252.tar.gz
merge revision(s) r43148,r43149,r43152: [Backport #8433]
* 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/branches/ruby_2_0_0@45049 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 d859982fe5..142ed5dbf5 100644
--- a/thread.c
+++ b/thread.c
@@ -384,6 +384,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
@@ -3832,10 +3834,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;
@@ -4099,8 +4099,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
@@ -4432,6 +4430,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;