diff options
author | normal <normal@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2018-12-08 19:25:37 +0000 |
---|---|---|
committer | normal <normal@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2018-12-08 19:25:37 +0000 |
commit | 2b1dcc1dd1eb260fd20ff1e6e0dfb0e5624a3cc6 (patch) | |
tree | 5da68d30a828638d4aeac9b299d9ccdf0c52601c /thread_pthread.c | |
parent | 726ea30ac2882a875610c44ab8f6cc7f25bc4e8c (diff) |
thread_pthread.c: fix memory leak from fork loop leapfrog
Constantly forking a single-threaded process in a loop leads to
a memory leak when using POSIX timers.
==> fork_leapfrog.rb <==
require 'io/wait'
Dir.chdir '/proc'
prev = 0
loop do
pid = fork
exit!(0) if pid
# show the number of 4K pages used (Linux-only)
n = File.read("#$$/statm").split(-' ')[1].to_i
if n > prev
puts "#{prev} => #{n}"
prev = n
end
# since Ctrl-C from a terminal can't stop this loop,
# allow the user to just hit any key to stop
break if STDIN.wait(0)
end
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@66288 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'thread_pthread.c')
-rw-r--r-- | thread_pthread.c | 15 |
1 files changed, 8 insertions, 7 deletions
diff --git a/thread_pthread.c b/thread_pthread.c index c87e952750..18624f42c9 100644 --- a/thread_pthread.c +++ b/thread_pthread.c @@ -1726,16 +1726,12 @@ rb_thread_create_timer_thread(void) if (setup_communication_pipe_internal(signal_self_pipe.normal) < 0) return; if (setup_communication_pipe_internal(signal_self_pipe.ub_main) < 0) return; + ubf_timer_create(current); if (owner != current) { /* validate pipe on this process */ - ubf_timer_create(current); sigwait_th = THREAD_INVALID; signal_self_pipe.owner_process = current; } - else if (UBF_TIMER == UBF_TIMER_PTHREAD) { - /* UBF_TIMER_PTHREAD needs to recreate after fork */ - ubf_timer_pthread_create(current); - } } static void @@ -1763,7 +1759,13 @@ ubf_timer_disarm(void) static void ubf_timer_destroy(void) { -#if UBF_TIMER == UBF_TIMER_PTHREAD +#if UBF_TIMER == UBF_TIMER_POSIX + if (timer_posix.owner == getpid()) { + if (timer_delete(timer_posix.timerid) < 0) + rb_sys_fail("timer_delete"); + memset(&timer_posix, 0, sizeof(timer_posix)); + } +#elif UBF_TIMER == UBF_TIMER_PTHREAD int err; timer_pthread.owner = 0; @@ -1774,7 +1776,6 @@ ubf_timer_destroy(void) rb_raise(rb_eThreadError, "native_thread_join() failed (%d)", err); } #endif -/* no need to destroy real POSIX timers */ } static int |