[前][次][番号順一覧][スレッド一覧]

ruby-changes:54069

From: normal <ko1@a...>
Date: Sun, 9 Dec 2018 04:25:43 +0900 (JST)
Subject: [ruby-changes:54069] normal:r66288 (trunk): thread_pthread.c: fix memory leak from fork loop leapfrog

normal	2018-12-09 04:25:37 +0900 (Sun, 09 Dec 2018)

  New Revision: 66288

  https://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=66288

  Log:
    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

  Modified files:
    trunk/thread_pthread.c
Index: thread_pthread.c
===================================================================
--- thread_pthread.c	(revision 66287)
+++ thread_pthread.c	(revision 66288)
@@ -1726,16 +1726,12 @@ rb_thread_create_timer_thread(void) https://github.com/ruby/ruby/blob/trunk/thread_pthread.c#L1726
     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) https://github.com/ruby/ruby/blob/trunk/thread_pthread.c#L1759
 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) https://github.com/ruby/ruby/blob/trunk/thread_pthread.c#L1776
         rb_raise(rb_eThreadError, "native_thread_join() failed (%d)", err);
     }
 #endif
-/* no need to destroy real POSIX timers */
 }
 
 static int

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]