aboutsummaryrefslogtreecommitdiffstats
path: root/mjit.c
diff options
context:
space:
mode:
authornormal <normal@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2018-07-08 07:27:24 +0000
committernormal <normal@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2018-07-08 07:27:24 +0000
commitc93adfc170079a54965e939a5a4d57139cd714e1 (patch)
treefccf7a5a80e337ef710f0516b5f59a0bddc7f2ce /mjit.c
parenta1e589498d1b80e3bc8b3e8c5c07874afcf0cb17 (diff)
downloadruby-c93adfc170079a54965e939a5a4d57139cd714e1.tar.gz
mjit: get rid of memory leak in pause+resume loop
pthread_atfork is not idempotent and repeatedly calling it causes it to register the same hook repeatedly; leading to unbound memory growth. Ruby already has a (confusing-named) internal API for to call in the forked child process: rb_thread_atfork Call the MJIT child_after_fork hook inside that to prevent unbound growth with the following loop: loop do RubyVM::MJIT.pause RubyVM::MJIT.resume end git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@63884 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'mjit.c')
-rw-r--r--mjit.c14
1 files changed, 8 insertions, 6 deletions
diff --git a/mjit.c b/mjit.c
index ea615e9481..7a1b3a1383 100644
--- a/mjit.c
+++ b/mjit.c
@@ -117,7 +117,7 @@ extern void rb_native_cond_signal(rb_nativethread_cond_t *cond);
extern void rb_native_cond_broadcast(rb_nativethread_cond_t *cond);
extern void rb_native_cond_wait(rb_nativethread_cond_t *cond, rb_nativethread_lock_t *mutex);
-extern int rb_thread_create_mjit_thread(void (*child_hook)(void), void (*worker_func)(void));
+extern int rb_thread_create_mjit_thread(void (*worker_func)(void));
/* process.c */
rb_pid_t ruby_waitpid_locked(rb_vm_t *, rb_pid_t, int *status, int options,
@@ -1319,11 +1319,13 @@ init_header_filename(void)
/* This is called after each fork in the child in to switch off MJIT
engine in the child as it does not inherit MJIT threads. */
-static void
-child_after_fork(void)
+void
+mjit_child_after_fork(void)
{
- verbose(3, "Switching off MJIT in a forked child");
- mjit_enabled = FALSE;
+ if (mjit_enabled) {
+ verbose(3, "Switching off MJIT in a forked child");
+ mjit_enabled = FALSE;
+ }
/* TODO: Should we initiate MJIT in the forked Ruby. */
}
@@ -1433,7 +1435,7 @@ start_worker(void)
stop_worker_p = FALSE;
worker_stopped = FALSE;
- if (!rb_thread_create_mjit_thread(child_after_fork, worker)) {
+ if (!rb_thread_create_mjit_thread(worker)) {
mjit_enabled = FALSE;
rb_native_mutex_destroy(&mjit_engine_mutex);
rb_native_cond_destroy(&mjit_pch_wakeup);