thread_pthread.c: fix memory leak from fork loop leapfrog (v2)

Constantly forking a single-threaded process in a loop leads to
a memory leak when using POSIX timers.

v2: disarm before timer_delete

==> 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@66290 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
normal 2018-12-08 21:45:50 +00:00
Родитель 1a17766e6a
Коммит 043047a8fd
1 изменённых файлов: 9 добавлений и 7 удалений

Просмотреть файл

@ -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,14 @@ 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()) {
ubf_timer_disarm();
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 +1777,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