Would you have time to turn that into a (tested ;) ) patch?

With attached patch on top of 1.9.3~preview1+svn33077-3

"make test"

#244 test_fork.rb:51:in `<top (required)>':
     a = []
     trap(:INT) { a.push(1) }
     trap(:TERM) { a.push(2) }
     pid = $$
     begin
       fork do
         sleep 0.5
         Process.kill(:INT, pid)
         Process.kill(:TERM, pid)
       end

       sleep 1
       a.sort
     rescue NotImplementedError
       [1, 2]
     end
  #=> "[]" (expected "[1, 2]")  [ruby-dev:44005] [Ruby 1.9 - Bug #4950]
#934 test_thread.rb:389:in `<top (required)>':
     open("zzz.rb", "w") do |f|
       f.puts <<-END
         begin
           m = Mutex.new
           Thread.new { m.lock; sleep 1 }
           sleep 0.3
           parent = Thread.current
           Thread.new do
             sleep 0.3
             begin
               fork { GC.start }
             rescue Exception
               parent.raise $!
             end
           end
           m.lock
           pid, status = Process.wait2
           $result = status.success? ? :ok : :ng
         rescue NotImplementedError
           $result = :ok
         end
       END
     end
     require "./zzz.rb"
     $result
  #=> "" (expected "ok")
FAIL 2/937 tests failed
make: *** [yes-btest-ruby] Error 1
--- ruby1.9.1-1.9.3~preview1+svn33077.orig/thread_pthread.c
+++ ruby1.9.1-1.9.3~preview1+svn33077/thread_pthread.c
@@ -1045,6 +1045,36 @@ static pthread_t timer_thread_id;
 static int timer_thread_pipe[2] = {-1, -1};
 static int timer_thread_pipe_owner_process;
 
+#if 0
+static inline int 
+timer_thread_running() {
+   return timer_thread_pipe_owner_process == getpid() ? 1 : 0;
+}
+   
+static inline void timer_thread_set() {
+    timer_thread_pipe_owner_process = getpid();
+}
+
+RUBY_FUNC_EXPORTED
+void timer_thread_child_at_fork() {
+};
+      
+#else
+static inline int 
+timer_thread_running() {
+   return timer_thread_pipe_owner_process;
+}
+   
+static inline void timer_thread_set() {
+    timer_thread_pipe_owner_process = 1;
+}
+
+RUBY_FUNC_EXPORTED
+void timer_thread_child_at_fork() {
+    timer_thread_pipe_owner_process = 0;
+};
+#endif
+
 #define TT_DEBUG 0
 
 #define WRITE_CONST(fd, str) (void)(write((fd),(str),sizeof(str)-1)<0)
@@ -1056,7 +1086,7 @@ rb_thread_wakeup_timer_thread(void)
     ssize_t result;
 
     /* already opened */
-    if (timer_thread_pipe_owner_process == getpid()) {
+    if (timer_thread_running()) {
 	const char *buff = "!";
       retry:
 	if ((result = write(timer_thread_pipe[1], buff, 1)) <= 0) {
@@ -1199,7 +1229,7 @@ rb_thread_create_timer_thread(void)
 #endif
 
 	/* communication pipe with timer thread and signal handler */
-	if (timer_thread_pipe_owner_process != getpid()) {
+	if (!timer_thread_running()) {
 	    if (timer_thread_pipe[0] != -1) {
 		/* close pipe of parent process */
 		close_communication_pipe();
@@ -1229,7 +1259,7 @@ rb_thread_create_timer_thread(void)
 #endif /* defined(HAVE_FCNTL) && defined(F_GETFL) && defined(F_SETFL) */
 
 	    /* validate pipe on this process */
-	    timer_thread_pipe_owner_process = getpid();
+	    timer_thread_set();
 	}
 
 	/* create timer thread */
--- ruby1.9.1-1.9.3~preview1+svn33077.orig/main.c
+++ ruby1.9.1-1.9.3~preview1+svn33077/main.c
@@ -21,6 +22,8 @@
 
 RUBY_GLOBAL_SETUP
 
+extern void timer_thread_child_at_fork();
+
 int
 main(int argc, char **argv)
 {
@@ -31,6 +34,10 @@ main(int argc, char **argv)
     setlocale(LC_CTYPE, "");
 #endif
 
+#if 1
+    pthread_atfork(NULL, NULL, timer_thread_child_at_fork);
+#endif
+    
     ruby_sysinit(&argc, &argv);
     {
 	RUBY_INIT_STACK;

Reply via email to