Skip to content

Commit

Permalink
Add gvl and fiber assertions to scheduler interface to catch invalid …
Browse files Browse the repository at this point in the history
…usage.
  • Loading branch information
ioquatix committed Jul 16, 2021
1 parent 3ce2bf4 commit 860c795
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 0 deletions.
1 change: 1 addition & 0 deletions common.mk
Expand Up @@ -12189,6 +12189,7 @@ scheduler.$(OBJEXT): $(top_srcdir)/internal/gc.h
scheduler.$(OBJEXT): $(top_srcdir)/internal/imemo.h
scheduler.$(OBJEXT): $(top_srcdir)/internal/serial.h
scheduler.$(OBJEXT): $(top_srcdir)/internal/static_assert.h
scheduler.$(OBJEXT): $(top_srcdir)/internal/thread.h
scheduler.$(OBJEXT): $(top_srcdir)/internal/vm.h
scheduler.$(OBJEXT): $(top_srcdir)/internal/warnings.h
scheduler.$(OBJEXT): {$(VPATH)}assert.h
Expand Down
34 changes: 34 additions & 0 deletions scheduler.c
Expand Up @@ -11,6 +11,7 @@
#include "vm_core.h"
#include "ruby/fiber/scheduler.h"
#include "ruby/io.h"
#include "internal/thread.h"

static ID id_close;

Expand Down Expand Up @@ -49,6 +50,8 @@ Init_Fiber_Scheduler(void)
VALUE
rb_fiber_scheduler_get(void)
{
VM_ASSERT(ruby_thread_has_gvl_p());

rb_thread_t *thread = GET_THREAD();
VM_ASSERT(thread);

Expand Down Expand Up @@ -78,6 +81,8 @@ verify_interface(VALUE scheduler)
VALUE
rb_fiber_scheduler_set(VALUE scheduler)
{
VM_ASSERT(ruby_thread_has_gvl_p());

rb_thread_t *thread = GET_THREAD();
VM_ASSERT(thread);

Expand Down Expand Up @@ -122,6 +127,8 @@ VALUE rb_fiber_scheduler_current_for_thread(VALUE thread)
VALUE
rb_fiber_scheduler_close(VALUE scheduler)
{
VM_ASSERT(ruby_thread_has_gvl_p());

if (rb_respond_to(scheduler, id_close)) {
return rb_funcall(scheduler, id_close, 0);
}
Expand All @@ -142,19 +149,25 @@ rb_fiber_scheduler_make_timeout(struct timeval *timeout)
VALUE
rb_fiber_scheduler_kernel_sleep(VALUE scheduler, VALUE timeout)
{
VM_ASSERT(ruby_thread_has_gvl_p());

return rb_funcall(scheduler, id_kernel_sleep, 1, timeout);
}

VALUE
rb_fiber_scheduler_kernel_sleepv(VALUE scheduler, int argc, VALUE * argv)
{
VM_ASSERT(ruby_thread_has_gvl_p());

return rb_funcallv(scheduler, id_kernel_sleep, argc, argv);
}

#if 0
VALUE
rb_fiber_scheduler_timeout_after(VALUE scheduler, VALUE timeout, VALUE exception, VALUE message)
{
VM_ASSERT(ruby_thread_has_gvl_p());

VALUE arguments[] = {
timeout, exception, message
};
Expand All @@ -165,13 +178,17 @@ rb_fiber_scheduler_timeout_after(VALUE scheduler, VALUE timeout, VALUE exception
VALUE
rb_fiber_scheduler_timeout_afterv(VALUE scheduler, int argc, VALUE * argv)
{
VM_ASSERT(ruby_thread_has_gvl_p());

return rb_check_funcall(scheduler, id_timeout_after, argc, argv);
}
#endif

VALUE
rb_fiber_scheduler_process_wait(VALUE scheduler, rb_pid_t pid, int flags)
{
VM_ASSERT(ruby_thread_has_gvl_p());

VALUE arguments[] = {
PIDT2NUM(pid), RB_INT2NUM(flags)
};
Expand All @@ -182,36 +199,49 @@ rb_fiber_scheduler_process_wait(VALUE scheduler, rb_pid_t pid, int flags)
VALUE
rb_fiber_scheduler_block(VALUE scheduler, VALUE blocker, VALUE timeout)
{
VM_ASSERT(ruby_thread_has_gvl_p());

return rb_funcall(scheduler, id_block, 2, blocker, timeout);
}

VALUE
rb_fiber_scheduler_unblock(VALUE scheduler, VALUE blocker, VALUE fiber)
{
VM_ASSERT(ruby_thread_has_gvl_p());
VM_ASSERT(rb_obj_is_fiber(fiber));

return rb_funcall(scheduler, id_unblock, 2, blocker, fiber);
}

VALUE
rb_fiber_scheduler_io_wait(VALUE scheduler, VALUE io, VALUE events, VALUE timeout)
{
VM_ASSERT(ruby_thread_has_gvl_p());

return rb_funcall(scheduler, id_io_wait, 3, io, events, timeout);
}

VALUE
rb_fiber_scheduler_io_wait_readable(VALUE scheduler, VALUE io)
{
VM_ASSERT(ruby_thread_has_gvl_p());

return rb_fiber_scheduler_io_wait(scheduler, io, RB_UINT2NUM(RUBY_IO_READABLE), Qnil);
}

VALUE
rb_fiber_scheduler_io_wait_writable(VALUE scheduler, VALUE io)
{
VM_ASSERT(ruby_thread_has_gvl_p());

return rb_fiber_scheduler_io_wait(scheduler, io, RB_UINT2NUM(RUBY_IO_WRITABLE), Qnil);
}

VALUE
rb_fiber_scheduler_io_read(VALUE scheduler, VALUE io, VALUE buffer, size_t offset, size_t length)
{
VM_ASSERT(ruby_thread_has_gvl_p());

VALUE arguments[] = {
io, buffer, SIZET2NUM(offset), SIZET2NUM(length)
};
Expand All @@ -222,6 +252,8 @@ rb_fiber_scheduler_io_read(VALUE scheduler, VALUE io, VALUE buffer, size_t offse
VALUE
rb_fiber_scheduler_io_write(VALUE scheduler, VALUE io, VALUE buffer, size_t offset, size_t length)
{
VM_ASSERT(ruby_thread_has_gvl_p());

VALUE arguments[] = {
io, buffer, SIZET2NUM(offset), SIZET2NUM(length)
};
Expand All @@ -233,6 +265,8 @@ rb_fiber_scheduler_io_write(VALUE scheduler, VALUE io, VALUE buffer, size_t offs
VALUE
rb_fiber_scheduler_address_resolve(VALUE scheduler, VALUE hostname)
{
VM_ASSERT(ruby_thread_has_gvl_p());

VALUE arguments[] = {
hostname
};
Expand Down

0 comments on commit 860c795

Please sign in to comment.