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
This commit is contained in:
parent
726ea30ac2
commit
2b1dcc1dd1
@ -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.normal) < 0) return;
|
||||||
if (setup_communication_pipe_internal(signal_self_pipe.ub_main) < 0) return;
|
if (setup_communication_pipe_internal(signal_self_pipe.ub_main) < 0) return;
|
||||||
|
|
||||||
|
ubf_timer_create(current);
|
||||||
if (owner != current) {
|
if (owner != current) {
|
||||||
/* validate pipe on this process */
|
/* validate pipe on this process */
|
||||||
ubf_timer_create(current);
|
|
||||||
sigwait_th = THREAD_INVALID;
|
sigwait_th = THREAD_INVALID;
|
||||||
signal_self_pipe.owner_process = current;
|
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
|
static void
|
||||||
@ -1763,7 +1759,13 @@ ubf_timer_disarm(void)
|
|||||||
static void
|
static void
|
||||||
ubf_timer_destroy(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;
|
int err;
|
||||||
|
|
||||||
timer_pthread.owner = 0;
|
timer_pthread.owner = 0;
|
||||||
@ -1774,7 +1776,6 @@ ubf_timer_destroy(void)
|
|||||||
rb_raise(rb_eThreadError, "native_thread_join() failed (%d)", err);
|
rb_raise(rb_eThreadError, "native_thread_join() failed (%d)", err);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
/* no need to destroy real POSIX timers */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
|
Loading…
x
Reference in New Issue
Block a user