ruby-changes:51986
From: normal <ko1@a...>
Date: Mon, 6 Aug 2018 10:06:29 +0900 (JST)
Subject: [ruby-changes:51986] normal:r64201 (trunk): process.c: ensure th->interrupt lock is held when migrating
normal 2018-08-06 10:06:21 +0900 (Mon, 06 Aug 2018) New Revision: 64201 https://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=64201 Log: process.c: ensure th->interrupt lock is held when migrating w->cond may be changed without our knowledge in waitpid_nogvl without th->interrupt_lock Modified files: trunk/process.c Index: process.c =================================================================== --- process.c (revision 64200) +++ process.c (revision 64201) @@ -941,6 +941,24 @@ int rb_sigwait_fd_get(const rb_thread_t https://github.com/ruby/ruby/blob/trunk/process.c#L941 void rb_sigwait_sleep(const rb_thread_t *, int fd, const struct timespec *); void rb_sigwait_fd_put(const rb_thread_t *, int fd); +static int +sigwait_fd_migrate_signaled_p(struct waitpid_state *w) +{ + int signaled = FALSE; + rb_thread_t *th = w->ec ? rb_ec_thread_ptr(w->ec) : 0; + + if (th) rb_native_mutex_lock(&th->interrupt_lock); + + if (w->cond) { + rb_native_cond_signal(w->cond); + signaled = TRUE; + } + + if (th) rb_native_mutex_unlock(&th->interrupt_lock); + + return signaled; +} + /* * When a thread is done using sigwait_fd and there are other threads * sleeping on waitpid, we must kick one of the threads out of @@ -952,14 +970,10 @@ sigwait_fd_migrate_sleeper(rb_vm_t *vm) https://github.com/ruby/ruby/blob/trunk/process.c#L970 struct waitpid_state *w = 0; list_for_each(&vm->waiting_pids, w, wnode) { - if (!w->cond) continue; /* somebody else already got sigwait_fd */ - rb_native_cond_signal(w->cond); - return; + if (sigwait_fd_migrate_signaled_p(w)) return; } list_for_each(&vm->waiting_grps, w, wnode) { - if (!w->cond) continue; /* somebody else already got sigwait_fd */ - rb_native_cond_signal(w->cond); - return; + if (sigwait_fd_migrate_signaled_p(w)) return; } } -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/