Ruby-1.8.6系のSIGVTALRMバグ
1.8.7系では修正されているのですが、1.8.6系ではp420を含めてバックポートされていないようです。
こんなの
Virtual timer expired
以下は1.8.7系での修正を1.8.6系へ移植したものです。
diff -Naur ruby-1.8.6-p420//eval.c ruby-1.8.6-p420-SIGVTALRM//eval.c --- ruby-1.8.6-p420//eval.c 2010-06-22 05:32:00.000000000 +0900 +++ ruby-1.8.6-p420-SIGVTALRM//eval.c 2010-10-26 10:48:20.658203999 +0900 @@ -11953,6 +11953,12 @@ 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) @@ -12036,6 +12042,8 @@ 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); @@ -12078,6 +12086,8 @@ 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; @@ -12117,17 +12127,11 @@ "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; @@ -12876,6 +12880,9 @@ 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 }
バージョンコードが同じだと色々困るので、version.h にも手をいれて使っています。
diff -Naur ruby-1.8.6-p420//version.h ruby-1.8.6-p420-SIGVTALRM//version.h --- ruby-1.8.6-p420//version.h 2010-09-02 00:14:52.000000000 +0900 +++ ruby-1.8.6-p420-SIGVTALRM//version.h 2010-10-26 10:53:51.608203999 +0900 @@ -1,7 +1,7 @@ #define RUBY_VERSION "1.8.6" -#define RUBY_RELEASE_DATE "2010-09-02" +#define RUBY_RELEASE_DATE "2010-10-26" #define RUBY_VERSION_CODE 186 -#define RUBY_RELEASE_CODE 20100902 +#define RUBY_RELEASE_CODE 20101026 #define RUBY_PATCHLEVEL 420 #define RUBY_VERSION_MAJOR 1