summaryrefslogtreecommitdiff
path: root/process.c
diff options
context:
space:
mode:
authorJean Boussier <byroot@ruby-lang.org>2023-03-03 08:40:00 +0100
committerJean Boussier <jean.boussier@gmail.com>2023-03-23 09:08:19 +0000
commit3563e1383fe4ce13168cd3b9f4d5222d69d00061 (patch)
tree666b61248378187c92056113a6fcd725aa10223e /process.c
parenta9146bd81e8a9085cfa920ee485deb43b3a2a776 (diff)
downloadruby-3563e1383fe4ce13168cd3b9f4d5222d69d00061.tar.gz
thread_pthread.c: Use a `fork_gen` to protect against fork instead of getpid()
[Feature #19443] Until recently most libc would cache `getpid()` so this was a cheap check to make. However as of glibc version 2.25 the PID cache is removed and calls to getpid() always invoke the actual system call which significantly degrades the performance of existing applications. The reason glibc removed the cache is that some libraries were bypassing fork(2) by issuing system calls themselves, causing stale cache issues. That isn't a concern for Ruby as bypassing MRI's primitive for forking would render the VM unusable, so we can safely cache the PID.
Diffstat (limited to 'process.c')
-rw-r--r--process.c19
1 files changed, 7 insertions, 12 deletions
diff --git a/process.c b/process.c
index 517b4b3808..8d7e8e782a 100644
--- a/process.c
+++ b/process.c
@@ -511,13 +511,6 @@ clear_pid_cache(void)
cached_pid = Qnil;
}
-static inline void
-rb_process_atfork(void)
-{
- clear_pid_cache();
- rb_thread_atfork(); /* calls mjit_resume() */
-}
-
/*
* call-seq:
* Process.pid -> integer
@@ -1564,9 +1557,13 @@ before_fork_ruby(void)
}
static void
-after_fork_ruby(void)
+after_fork_ruby(rb_pid_t pid)
{
rb_threadptr_pending_interrupt_clear(GET_THREAD());
+ if (pid == 0) {
+ clear_pid_cache();
+ rb_thread_atfork();
+ }
after_exec();
}
#endif
@@ -4073,11 +4070,10 @@ rb_fork_ruby2(struct rb_process_status *status)
status->pid = pid;
status->error = err;
}
- after_fork_ruby();
+ after_fork_ruby(pid);
disable_child_handler_fork_parent(&old); /* yes, bad name */
if (pid >= 0) { /* fork succeed */
- if (pid == 0) rb_process_atfork();
return pid;
}
@@ -6849,8 +6845,7 @@ rb_daemon(int nochdir, int noclose)
#ifdef HAVE_DAEMON
before_fork_ruby();
err = daemon(nochdir, noclose);
- after_fork_ruby();
- rb_process_atfork();
+ after_fork_ruby(0);
#else
int n;