summaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
authorJean Boussier <byroot@ruby-lang.org>2023-02-16 19:36:31 +0100
committerJean Boussier <jean.boussier@gmail.com>2023-03-20 08:21:23 +0000
commit1db8951d3a8be6a756c9d3d3b87231997b301985 (patch)
tree450ed624fb3b8afc145ef2fd3e85258f64b08bf3 /test
parent70ea58bd5ba42b26ff39f51079af0efa422ac036 (diff)
Cache `Process.pid`
[Feature #19443] It's not uncommon for database client and similar network libraries to protect themselves from Process.fork by regularly checking Process.pid 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.
Notes
Notes: Merged: https://github.com/ruby/ruby/pull/7326
Diffstat (limited to 'test')
-rw-r--r--test/ruby/test_process.rb20
1 files changed, 20 insertions, 0 deletions
diff --git a/test/ruby/test_process.rb b/test/ruby/test_process.rb
index beb181ccd4..3d0b11547e 100644
--- a/test/ruby/test_process.rb
+++ b/test/ruby/test_process.rb
@@ -2586,6 +2586,26 @@ EOS
end
end if Process.respond_to?(:_fork)
+ def test__fork_pid_cache
+ parent_pid = Process.pid
+ r, w = IO.pipe
+ pid = Process._fork
+ if pid == 0
+ begin
+ r.close
+ w << "ok: #{Process.pid}"
+ w.close
+ ensure
+ exit!
+ end
+ else
+ w.close
+ assert_equal("ok: #{pid}", r.read)
+ r.close
+ Process.waitpid(pid)
+ end
+ end if Process.respond_to?(:_fork)
+
def test__fork_hook
%w(fork Process.fork).each do |method|
feature17795 = '[ruby-core:103400] [Feature #17795]'