Expose scheduler as public interface & bug fixes. (#3945)

* Rename `rb_scheduler` to `rb_fiber_scheduler`.

* Use public interface if available.

* Use `rb_check_funcall` where possible.

* Don't use `unblock` unless the fiber was non-blocking.
This commit is contained in:
Samuel Williams 2021-02-09 19:39:56 +13:00 committed by GitHub
parent 3c593f28ed
commit 5f69a7f604
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
Notes: git 2021-02-09 15:40:27 +09:00
Merged-By: ioquatix <samuel@codeotaku.com>
18 changed files with 356 additions and 245 deletions

62
io.c
View file

@ -13,7 +13,7 @@
#include "ruby/internal/config.h"
#include "internal/scheduler.h"
#include "ruby/fiber/scheduler.h"
#ifdef _WIN32
# include "ruby/ruby.h"
@ -1264,10 +1264,10 @@ io_fflush(rb_io_t *fptr)
VALUE
rb_io_wait(VALUE io, VALUE events, VALUE timeout)
{
VALUE scheduler = rb_scheduler_current();
VALUE scheduler = rb_fiber_scheduler_current();
if (scheduler != Qnil) {
return rb_scheduler_io_wait(scheduler, io, events, timeout);
return rb_fiber_scheduler_io_wait(scheduler, io, events, timeout);
}
rb_io_t * fptr = NULL;
@ -1306,10 +1306,10 @@ rb_io_from_fd(int fd)
int
rb_io_wait_readable(int f)
{
VALUE scheduler = rb_scheduler_current();
VALUE scheduler = rb_fiber_scheduler_current();
if (scheduler != Qnil) {
return RTEST(
rb_scheduler_io_wait_readable(scheduler, rb_io_from_fd(f))
rb_fiber_scheduler_io_wait_readable(scheduler, rb_io_from_fd(f))
);
}
@ -1337,10 +1337,10 @@ rb_io_wait_readable(int f)
int
rb_io_wait_writable(int f)
{
VALUE scheduler = rb_scheduler_current();
VALUE scheduler = rb_fiber_scheduler_current();
if (scheduler != Qnil) {
return RTEST(
rb_scheduler_io_wait_writable(scheduler, rb_io_from_fd(f))
rb_fiber_scheduler_io_wait_writable(scheduler, rb_io_from_fd(f))
);
}
@ -1377,11 +1377,11 @@ rb_io_wait_writable(int f)
int
rb_wait_for_single_fd(int fd, int events, struct timeval *timeout)
{
VALUE scheduler = rb_scheduler_current();
VALUE scheduler = rb_fiber_scheduler_current();
if (scheduler != Qnil) {
return RTEST(
rb_scheduler_io_wait(scheduler, rb_io_from_fd(fd), RB_INT2NUM(events), rb_scheduler_timeout(timeout))
rb_fiber_scheduler_io_wait(scheduler, rb_io_from_fd(fd), RB_INT2NUM(events), rb_fiber_scheduler_make_timeout(timeout))
);
}
@ -1538,15 +1538,17 @@ io_binwrite(VALUE str, const char *ptr, long len, rb_io_t *fptr, int nosync)
if ((n = len) <= 0) return n;
VALUE scheduler = rb_scheduler_current();
if (scheduler != Qnil && rb_scheduler_supports_io_write(scheduler)) {
ssize_t length = RB_NUM2SSIZE(
rb_scheduler_io_write(scheduler, fptr->self, str, offset, len)
);
VALUE scheduler = rb_fiber_scheduler_current();
if (scheduler != Qnil) {
VALUE result = rb_fiber_scheduler_io_write(scheduler, fptr->self, str, offset, len);
if (length < 0) rb_sys_fail_path(fptr->pathv);
if (result != Qundef) {
ssize_t length = RB_NUM2SSIZE(result);
return length;
if (length < 0) rb_sys_fail_path(fptr->pathv);
return length;
}
}
if (fptr->wbuf.ptr == NULL && !(!nosync && (fptr->mode & FMODE_SYNC))) {
@ -2623,15 +2625,17 @@ bufread_call(VALUE arg)
static long
io_fread(VALUE str, long offset, long size, rb_io_t *fptr)
{
VALUE scheduler = rb_scheduler_current();
if (scheduler != Qnil && rb_scheduler_supports_io_read(scheduler)) {
ssize_t length = RB_NUM2SSIZE(
rb_scheduler_io_read(scheduler, fptr->self, str, offset, size)
);
VALUE scheduler = rb_fiber_scheduler_current();
if (scheduler != Qnil) {
VALUE result = rb_fiber_scheduler_io_read(scheduler, fptr->self, str, offset, size);
if (length < 0) rb_sys_fail_path(fptr->pathv);
if (result != Qundef) {
ssize_t length = RB_NUM2SSIZE(result);
return length;
if (length < 0) rb_sys_fail_path(fptr->pathv);
return length;
}
}
long len;
@ -11024,11 +11028,11 @@ struct wait_for_single_fd {
};
static void *
rb_thread_scheduler_wait_for_single_fd(void * _args)
rb_thread_fiber_scheduler_wait_for_single_fd(void * _args)
{
struct wait_for_single_fd *args = (struct wait_for_single_fd *)_args;
args->result = rb_scheduler_io_wait(args->scheduler, rb_io_from_fd(args->fd), INT2NUM(args->events), Qnil);
args->result = rb_fiber_scheduler_io_wait(args->scheduler, rb_io_from_fd(args->fd), INT2NUM(args->events), Qnil);
return NULL;
}
@ -11040,10 +11044,10 @@ STATIC_ASSERT(pollout_expected, POLLOUT == RB_WAITFD_OUT);
static int
nogvl_wait_for_single_fd(VALUE th, int fd, short events)
{
VALUE scheduler = rb_thread_scheduler_current(th);
VALUE scheduler = rb_fiber_scheduler_current_for_thread(th);
if (scheduler != Qnil) {
struct wait_for_single_fd args = {.scheduler = scheduler, .fd = fd, .events = events};
rb_thread_call_with_gvl(rb_thread_scheduler_wait_for_single_fd, &args);
rb_thread_call_with_gvl(rb_thread_fiber_scheduler_wait_for_single_fd, &args);
return RTEST(args.result);
}
@ -11059,10 +11063,10 @@ nogvl_wait_for_single_fd(VALUE th, int fd, short events)
static int
nogvl_wait_for_single_fd(VALUE th, int fd, short events)
{
VALUE scheduler = rb_thread_scheduler_current(th);
VALUE scheduler = rb_fiber_scheduler_current_for_thread(th);
if (scheduler != Qnil) {
struct wait_for_single_fd args = {.scheduler = scheduler, .fd = fd, .events = events};
rb_thread_call_with_gvl(rb_thread_scheduler_wait_for_single_fd, &args);
rb_thread_call_with_gvl(rb_thread_fiber_scheduler_wait_for_single_fd, &args);
return RTEST(args.result);
}