Bug #2103: rev23993 causes Virtual Timer Expired when forking
http://redmine.ruby-lang.org/issues/show/2103

Author: Aman Gupta
Status: Open, Priority: Normal
Assigned to: Nobuyoshi Nakada
ruby -v: ruby 1.8.7 (2009-09-11 patchlevel 202) [x86_64-linux]

When forking, the thread timer is always started in the forked process, even though there are no threads running. The following patch by nobu should fix the issue:

diff --git a/eval.c b/eval.c
index 37c460d..d6359fe 100644
--- a/eval.c
+++ b/eval.c
@@ -12244,6 +12244,12 @@ rb_thread_alloc(klass)
 
 static int thread_init;
 
+#if defined(POSIX_SIGNAL)
+#define CATCH_VTALRM() posix_signal(SIGVTALRM, catch_timer)
+#else
+#define CATCH_VTALRM() signal(SIGVTALRM, catch_timer)
+#endif
+
 #if defined(_THREAD_SAFE)
 static void
 catch_timer(sig)
@@ -12327,6 +12333,8 @@ rb_thread_start_timer()
     static pthread_cond_t start = PTHREAD_COND_INITIALIZER;
 
     if (thread_init) return;
+    if (rb_thread_alone()) return;
+    CATCH_VTALRM();
     args[0] = &time_thread;
     args[1] = &start;
     safe_mutex_lock(&time_thread.lock);
@@ -12368,6 +12376,8 @@ rb_thread_start_timer()
     struct itimerval tval;
 
     if (thread_init) return;
+    if (rb_thread_alone()) return;
+    CATCH_VTALRM();
     tval.it_interval.tv_sec = 0;
     tval.it_interval.tv_usec = 10000;
     tval.it_value = tval.it_interval;
@@ -12408,17 +12418,11 @@ rb_thread_start_0(fn, arg, th)
 		 "can't start a new thread (frozen ThreadGroup)");
     }
 
-    if (!thread_init) {
 #if defined(HAVE_SETITIMER) || defined(_THREAD_SAFE)
-#if defined(POSIX_SIGNAL)
-	posix_signal(SIGVTALRM, catch_timer);
-#else
-	signal(SIGVTALRM, catch_timer);
-#endif
-
+    if (!thread_init) {
 	rb_thread_start_timer();
-#endif
     }
+#endif
 
     if (THREAD_SAVE_CONTEXT(curr_thread)) {
 	return thread;
@@ -13167,6 +13171,9 @@ rb_thread_atfork()
     main_thread = curr_thread;
     curr_thread->next = curr_thread;
     curr_thread->prev = curr_thread;
+#if defined(HAVE_SETITIMER) || defined(_THREAD_SAFE)
+    rb_thread_stop_timer();
+#endif
 }


----------------------------------------
http://redmine.ruby-lang.org