Skip to content

Commit

Permalink
(WIP) Force a timer thread when waiting for other threads to finish IO
Browse files Browse the repository at this point in the history
If the initial SIGVTALRM doesn't actually hit the thread doing IO whilst
it's blocked in select(2), we have to keep spamming it so that a signal
_does_ land on it whilst it is blocked in read.

This is not actually a good solution but let's see if it works.
  • Loading branch information
KJTsanaktsidis committed May 31, 2023
1 parent 3bc5f6b commit 5ec9626
Show file tree
Hide file tree
Showing 3 changed files with 8 additions and 2 deletions.
2 changes: 2 additions & 0 deletions include/ruby/thread.h
Expand Up @@ -59,6 +59,8 @@
*/
#define RB_NOGVL_UBF_ASYNC_SAFE (0x2)

#define RB_NOGVL_FORCE_TIMER_THREAD (0x4)

/** @} */

RBIMPL_SYMBOL_EXPORT_BEGIN()
Expand Down
2 changes: 1 addition & 1 deletion io.c
Expand Up @@ -5476,7 +5476,7 @@ fptr_finalize_flush(rb_io_t *fptr, int noraise, int keepgvl,
// Ensure waiting_fd users do not hit EBADF.
if (busy) {
// Wait for them to exit before we call close().
(void)rb_thread_call_without_gvl(call_close_wait_nogvl, busy, RUBY_UBF_IO, 0);
(void)rb_nogvl(call_close_wait_nogvl, busy, RUBY_UBF_IO, 0, RB_NOGVL_FORCE_TIMER_THREAD);
}

// Disable for now.
Expand Down
6 changes: 5 additions & 1 deletion thread.c
Expand Up @@ -1540,10 +1540,14 @@ rb_nogvl(void *(*func)(void *), void *data1,
vm->ubf_async_safe = 1;
}
else {
ubf_th = rb_thread_start_unblock_thread();
flags |= RB_NOGVL_FORCE_TIMER_THREAD;
}
}

if (flags & RB_NOGVL_FORCE_TIMER_THREAD) {
ubf_th = rb_thread_start_unblock_thread();
}

BLOCKING_REGION(th, {
val = func(data1);
saved_errno = errno;
Expand Down

0 comments on commit 5ec9626

Please sign in to comment.