diff --git a/thread_pthread.c b/thread_pthread.c index 730ecb5416..83fd37d0ea 100644 --- a/thread_pthread.c +++ b/thread_pthread.c @@ -3166,20 +3166,26 @@ rb_thread_create_timer_thread(void) timer_thread_setup_mn(); } - pthread_create(&timer_th.pthread_id, NULL, timer_thread_func, GET_VM()); + if (pthread_create(&timer_th.pthread_id, NULL, timer_thread_func, GET_VM()) != 0) { + system_working = 0; + // NOTE: safe to call into VM here even if we're in the middle of a call to `rb_fork_ruby()` + rb_warn("Couldn't create timer thread, error: %s", strerror(errno)); + } } static int native_stop_timer_thread(void) { - RUBY_ATOMIC_SET(system_working, 0); + if (RUBY_ATOMIC_LOAD(system_working)) { + RUBY_ATOMIC_SET(system_working, 0); - RUBY_DEBUG_LOG("wakeup send %d", timer_th.comm_fds[1]); - timer_thread_wakeup_force(); - RUBY_DEBUG_LOG("wakeup sent"); - pthread_join(timer_th.pthread_id, NULL); + RUBY_DEBUG_LOG("wakeup send %d", timer_th.comm_fds[1]); + timer_thread_wakeup_force(); + RUBY_DEBUG_LOG("wakeup sent"); + pthread_join(timer_th.pthread_id, NULL); - if (TT_DEBUG) fprintf(stderr, "stop timer thread\n"); + if (TT_DEBUG) fprintf(stderr, "stop timer thread\n"); + } return 1; } diff --git a/thread_win32.c b/thread_win32.c index 576f617e8d..0944e22fba 100644 --- a/thread_win32.c +++ b/thread_win32.c @@ -797,19 +797,27 @@ rb_thread_create_timer_thread(void) } timer_thread.id = w32_create_thread(1024 + (USE_RUBY_DEBUG_LOG ? BUFSIZ : 0), timer_thread_func, 0); - w32_resume_thread(timer_thread.id); + if (timer_thread.id == 0) { + system_working = 0; + rb_warn("Couldn't create timer thread, error:%s", strerror(thread_errno)); + } + else { + w32_resume_thread(timer_thread.id); + } } } static int native_stop_timer_thread(void) { - RUBY_ATOMIC_SET(system_working, 0); + if (RUBY_ATOMIC_LOAD(system_working)) { + RUBY_ATOMIC_SET(system_working, 0); - SetEvent(timer_thread.lock); - native_thread_join(timer_thread.id); - CloseHandle(timer_thread.lock); - timer_thread.lock = 0; + SetEvent(timer_thread.lock); + native_thread_join(timer_thread.id); + CloseHandle(timer_thread.lock); + timer_thread.lock = 0; + } return 1; }