diff options
author | normal <normal@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2018-07-30 06:35:08 +0000 |
---|---|---|
committer | normal <normal@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2018-07-30 06:35:08 +0000 |
commit | 7018acc946882f21d519af7c42ccf84b22a46b27 (patch) | |
tree | 7f72c989b3fc577baa2a76a0dc28477bdfa54e65 | |
parent | 56491afc7916fb24f5c4dc2c632fb93fa7063992 (diff) |
process.c (waitpid_nogvl): prevent conflicting use of sleep_cond
We reuse sleep_cond for waitpid notifications as well as GVL
waiting. So we must take care to not hold onto sleep_cond
when we try to reacquire GVL.
[ruby-core:88183]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@64117 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
-rw-r--r-- | process.c | 18 |
1 files changed, 17 insertions, 1 deletions
@@ -1144,6 +1144,9 @@ waitpid_nogvl(void *x) rb_sigwait_fd_put(th, sigwait_fd); } else { + if (!w->cond) + w->cond = rb_sleep_cond_get(w->ec); + /* another thread calling rb_sigwait_sleep will process * signals for us */ if (SIGCHLD_LOSSY) { @@ -1152,6 +1155,16 @@ waitpid_nogvl(void *x) rb_native_cond_wait(w->cond, &th->interrupt_lock); } } + + /* + * we must release th->native_thread_data.sleep_cond when + * re-acquiring GVL: + */ + if (w->cond) { + rb_sleep_cond_put(w->cond); + w->cond = 0; + } + rb_native_mutex_unlock(&th->interrupt_lock); if (sigwait_fd >= 0) @@ -1183,7 +1196,10 @@ waitpid_cleanup(VALUE x) list_del(&w->wnode); rb_native_mutex_unlock(&vm->waitpid_lock); } - rb_sleep_cond_put(w->cond); + + /* we may have never released and re-acquired GVL */ + if (w->cond) + rb_sleep_cond_put(w->cond); return Qfalse; } |