summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authork0kubun <k0kubun@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2018-10-22 09:40:44 +0000
committerk0kubun <k0kubun@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2018-10-22 09:40:44 +0000
commit821ff80c0cdf19351739147e43f1bc2d853a51d0 (patch)
treef919249a8c677cee3c12901ed3e6f6e6cee65675
parent7fbf01348b0a255863405860f1f5e428bd797de4 (diff)
mjit_worker.c: make sure copy job wait is unblocked
by stop_worker(). Previously copy_cache_from_main_thread() might loop forever even with stop_worker() is being called from ruby_cleanup(). git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@65299 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
-rw-r--r--mjit_worker.c19
1 files changed, 15 insertions, 4 deletions
diff --git a/mjit_worker.c b/mjit_worker.c
index 2234dcd8f1..9ea0fe72f5 100644
--- a/mjit_worker.c
+++ b/mjit_worker.c
@@ -1171,19 +1171,29 @@ struct mjit_copy_job {
static void mjit_copy_job_handler(void *data);
/* We're lazily copying cache values from main thread because these cache values
- could be different between ones on enqueue timing and ones on dequeue timing. */
-static void
+ could be different between ones on enqueue timing and ones on dequeue timing.
+ Return TRUE if copy succeeds. */
+static int
copy_cache_from_main_thread(struct mjit_copy_job *job)
{
+ int success_p = TRUE;
job->finish_p = FALSE;
- rb_postponed_job_register(0, mjit_copy_job_handler, (void *)job);
+ if (!rb_postponed_job_register(0, mjit_copy_job_handler, (void *)job))
+ return FALSE;
+
CRITICAL_SECTION_START(3, "in MJIT copy job wait");
while (!job->finish_p) {
rb_native_cond_wait(&mjit_worker_wakeup, &mjit_engine_mutex);
verbose(3, "Getting wakeup from client");
+
+ if (worker_stopped) { /* for cond broadcast from stop_worker() */
+ success_p = FALSE;
+ break;
+ }
}
CRITICAL_SECTION_FINISH(3, "in MJIT copy job wait");
+ return success_p;
}
/* The function implementing a worker. It is executed in a separate
@@ -1234,7 +1244,8 @@ mjit_worker(void)
/* Copy ISeq's inline caches values to avoid race condition. */
if (job.cc_entries != NULL || job.is_entries != NULL) {
- copy_cache_from_main_thread(&job);
+ if (copy_cache_from_main_thread(&job) == FALSE)
+ continue; /* retry postponed_job failure, or stop worker */
}
/* JIT compile */