Skip to content

Commit eee2598

Browse files
committed
Fix mutex_free so it doesn't call into Ruby code during GC
While freeing a locked mutex, if there is a waiter for the mutex it could call `rb_fiber_scheduler_unblock` which calls into Ruby code. The function `rb_mutex_unlock_th` was a footgun because it was used during normal Ruby code and also during GC. The fix is to not call this function during GC and simply remove the mutex from th->keeping_mutexes.
1 parent a450f09 commit eee2598

1 file changed

Lines changed: 3 additions & 2 deletions

File tree

thread_sync.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -148,13 +148,14 @@ mutex_locked_p(rb_mutex_t *mutex)
148148
return mutex->ec_serial != 0;
149149
}
150150

151+
static void thread_mutex_remove(rb_thread_t *thread, rb_mutex_t *mutex);
152+
151153
static void
152154
mutex_free(void *ptr)
153155
{
154156
rb_mutex_t *mutex = ptr;
155157
if (mutex_locked_p(mutex)) {
156-
const char *err = rb_mutex_unlock_th(mutex, mutex->th, 0, true);
157-
if (err) rb_bug("%s", err);
158+
thread_mutex_remove(mutex->th, mutex);
158159
}
159160
ruby_xfree(ptr);
160161
}

0 commit comments

Comments
 (0)