diff options
| author | Takashi Kokubun <takashikkbn@gmail.com> | 2026-04-03 20:16:38 -0700 |
|---|---|---|
| committer | Takashi Kokubun <takashikkbn@gmail.com> | 2026-04-03 20:16:38 -0700 |
| commit | c38f8732c4ae6448cf05c795ddd5df4040ceeea8 (patch) | |
| tree | df7a61e5d2eebec335e343eb3319f57556f38a34 | |
| parent | 4fa4d71d751a4efeb5616ca7227fa57df0e718b0 (diff) | |
merge revision(s) c8155822c460a5734d700cd468d306ca03b44ce4: [Backport #21959]
reinit rb_internal_thread_event_hooks_rw_lock at fork
| -rw-r--r-- | thread_pthread.c | 20 |
1 files changed, 20 insertions, 0 deletions
diff --git a/thread_pthread.c b/thread_pthread.c index df2940d5cf..0a5195f469 100644 --- a/thread_pthread.c +++ b/thread_pthread.c @@ -1558,6 +1558,8 @@ get_native_thread_id(void) #endif #if defined(HAVE_WORKING_FORK) +void rb_internal_thread_event_hooks_rw_lock_atfork(void); + static void thread_sched_atfork(struct rb_thread_sched *sched) { @@ -1589,6 +1591,8 @@ thread_sched_atfork(struct rb_thread_sched *sched) ccan_list_head_init(&vm->ractor.sched.timeslice_threads); ccan_list_head_init(&vm->ractor.sched.running_threads); + rb_internal_thread_event_hooks_rw_lock_atfork(); + VM_ASSERT(sched->is_running); sched->is_running_timeslice = false; @@ -3400,6 +3404,22 @@ struct rb_internal_thread_event_hook { static pthread_rwlock_t rb_internal_thread_event_hooks_rw_lock = PTHREAD_RWLOCK_INITIALIZER; +#if defined(HAVE_WORKING_FORK) +void +rb_internal_thread_event_hooks_rw_lock_atfork(void) +{ + // After fork(), this rwlock may have been held by a now-dead thread. + // + // pthread_rwlock_destroy() on a held lock is undefined behavior, and + // pthread_rwlock_init() on an already-initialized lock is also undefined + // behavior + // + // Direct assignment of PTHREAD_RWLOCK_INITIALIZER is safe and portable. + rb_internal_thread_event_hooks_rw_lock = + (pthread_rwlock_t)PTHREAD_RWLOCK_INITIALIZER; +} +#endif + rb_internal_thread_event_hook_t * rb_internal_thread_add_event_hook(rb_internal_thread_event_callback callback, rb_event_flag_t internal_event, void *user_data) { |
