summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authornormal <normal@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2018-07-30 06:35:08 +0000
committernormal <normal@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2018-07-30 06:35:08 +0000
commit7018acc946882f21d519af7c42ccf84b22a46b27 (patch)
tree7f72c989b3fc577baa2a76a0dc28477bdfa54e65
parent56491afc7916fb24f5c4dc2c632fb93fa7063992 (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.c18
1 files changed, 17 insertions, 1 deletions
diff --git a/process.c b/process.c
index 57ad802631..5ac18315ef 100644
--- a/process.c
+++ b/process.c
@@ -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;
}