summaryrefslogtreecommitdiff
path: root/thread_sync.c
diff options
context:
space:
mode:
authornormal <normal@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2018-12-21 12:32:52 +0000
committernormal <normal@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2018-12-21 12:32:52 +0000
commitfa5601e7b913288988bca347e4744a2921cfb480 (patch)
treed7452641a5efd201fc13efd43286e9bf58e60b7d /thread_sync.c
parent2a742d5f9b6b61f078fb9d73d7025c227b53f52b (diff)
thread_sync.c (rb_mutex_cleanup_keeping_mutexes): update fork_gen
... when clearing waitq. Otherwise, we risk redundantly clearing valid waiters in future calls to `mutex_ptr`. Note: I am not sure if this fixes [Bug #15430], and even if it did, fork_gen is a belt-and-suspenders redundancy for [Bug #15383] which wastes one word for every Mutex object. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@66477 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'thread_sync.c')
-rw-r--r--thread_sync.c16
1 files changed, 16 insertions, 0 deletions
diff --git a/thread_sync.c b/thread_sync.c
index 61e952be41..dda92f196a 100644
--- a/thread_sync.c
+++ b/thread_sync.c
@@ -45,6 +45,16 @@ typedef struct rb_mutex_struct {
rb_thread_t *th;
struct rb_mutex_struct *next_mutex;
struct list_head waitq; /* protected by GVL */
+
+ /*
+ * FIXME: belt-and-suspenders redundancy. This field should NOT
+ * be necessary at all if:
+ * - rb_mutex_cleanup_keeping_mutexes
+ * - rb_mutex_abandon_keeping_mutexes
+ * - rb_mutex_abandon_locking_mutex
+ * are all correct, but I suspect one of them is buggy.
+ * [Bug #15383] [Bug #15430]
+ */
rb_serial_t fork_gen;
} rb_mutex_t;
@@ -126,6 +136,7 @@ mutex_ptr(VALUE obj)
TypedData_Get_Struct(obj, rb_mutex_t, &mutex_data_type, mutex);
+ /* FIXME: remove (see comment at rb_mutex_t definition) */
if (mutex->fork_gen != fork_gen) {
/* forked children can't reach into parent thread stacks */
mutex->fork_gen = fork_gen;
@@ -445,7 +456,12 @@ static void
rb_mutex_cleanup_keeping_mutexes(const rb_thread_t *current_thread)
{
rb_mutex_t *mutex = current_thread->keeping_mutexes;
+ rb_serial_t fork_gen = current_thread->vm->fork_gen;
+
while (mutex) {
+ /* FIXME: remove (see comment at rb_mutex_t definition) */
+ mutex->fork_gen = fork_gen;
+
list_head_init(&mutex->waitq);
mutex = mutex->next_mutex;
}