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 git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@64201 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
217bdd776f
commit
5ca416bdf6
26
process.c
26
process.c
@ -941,6 +941,24 @@ int rb_sigwait_fd_get(const rb_thread_t *);
|
|||||||
void rb_sigwait_sleep(const rb_thread_t *, int fd, const struct timespec *);
|
void rb_sigwait_sleep(const rb_thread_t *, int fd, const struct timespec *);
|
||||||
void rb_sigwait_fd_put(const rb_thread_t *, int fd);
|
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
|
* 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
|
* sleeping on waitpid, we must kick one of the threads out of
|
||||||
@ -952,14 +970,10 @@ sigwait_fd_migrate_sleeper(rb_vm_t *vm)
|
|||||||
struct waitpid_state *w = 0;
|
struct waitpid_state *w = 0;
|
||||||
|
|
||||||
list_for_each(&vm->waiting_pids, w, wnode) {
|
list_for_each(&vm->waiting_pids, w, wnode) {
|
||||||
if (!w->cond) continue; /* somebody else already got sigwait_fd */
|
if (sigwait_fd_migrate_signaled_p(w)) return;
|
||||||
rb_native_cond_signal(w->cond);
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
list_for_each(&vm->waiting_grps, w, wnode) {
|
list_for_each(&vm->waiting_grps, w, wnode) {
|
||||||
if (!w->cond) continue; /* somebody else already got sigwait_fd */
|
if (sigwait_fd_migrate_signaled_p(w)) return;
|
||||||
rb_native_cond_signal(w->cond);
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user