diff options
author | Eric Wong <e@80x24.org> | 2014-02-08 20:40:40 +0000 |
---|---|---|
committer | Eric Wong <e@80x24.org> | 2014-02-08 20:40:40 +0000 |
commit | c9e8f1ee4abed6906fd2bead991eeb2c623185da (patch) | |
tree | 94405ca4595cb1b9ad3c6f7cbc74451918b99603 | |
parent | 00f0737e158924d88cc5000e9a7bb891e5ba3a1b (diff) | |
download | kgio-c9e8f1ee4abed6906fd2bead991eeb2c623185da.tar.gz |
It'll be OK to use rb_thread_call_without_gvl when rb_thread_blocking_region is not detectable at all. We still use rb_thread_blocking_region for Ruby 2.0-2.1 because rb_thread_call_without_gvl was detectable in 1.9.3, but not usable as an internal symbol. ref: https://bugs.ruby-lang.org/issues/9502
-rw-r--r-- | ext/kgio/accept.c | 8 | ||||
-rw-r--r-- | ext/kgio/blocking_io_region.h | 2 | ||||
-rw-r--r-- | ext/kgio/connect.c | 4 | ||||
-rw-r--r-- | ext/kgio/kgio.h | 15 | ||||
-rw-r--r-- | ext/kgio/poll.c | 8 | ||||
-rw-r--r-- | ext/kgio/tryopen.c | 25 | ||||
-rw-r--r-- | ext/kgio/write.c | 4 |
7 files changed, 35 insertions, 31 deletions
diff --git a/ext/kgio/accept.c b/ext/kgio/accept.c index eb40f32..c847c92 100644 --- a/ext/kgio/accept.c +++ b/ext/kgio/accept.c @@ -13,7 +13,7 @@ static VALUE cKgio_Socket; static VALUE mSocketMethods; static VALUE iv_kgio_addr; -#if defined(__linux__) && defined(KGIO_HAVE_THREAD_CALL_WITHOUT_GVL) +#if defined(__linux__) && defined(KGIO_WITHOUT_GVL) static int accept4_flags = SOCK_CLOEXEC; #else /* ! linux */ static int accept4_flags = SOCK_CLOEXEC | SOCK_NONBLOCK; @@ -79,7 +79,7 @@ static VALUE xaccept(void *ptr) return (VALUE)rv; } -#ifdef KGIO_HAVE_THREAD_CALL_WITHOUT_GVL +#ifdef KGIO_WITHOUT_GVL # include <time.h> # include "blocking_io_region.h" static int thread_accept(struct accept_args *a, int force_nonblock) @@ -89,7 +89,7 @@ static int thread_accept(struct accept_args *a, int force_nonblock) return (int)rb_thread_io_blocking_region(xaccept, a, a->fd); } -#else /* ! KGIO_HAVE_THREAD_CALL_WITHOUT_GVL */ +#else /* ! KGIO_WITHOUT_GVL */ # include <rubysig.h> static int thread_accept(struct accept_args *a, int force_nonblock) { @@ -106,7 +106,7 @@ static int thread_accept(struct accept_args *a, int force_nonblock) TRAP_END; return rv; } -#endif /* ! KGIO_HAVE_THREAD_CALL_WITHOUT_GVL */ +#endif /* ! KGIO_WITHOUT_GVL */ static void prepare_accept(struct accept_args *a, VALUE self, int argc, const VALUE *argv) diff --git a/ext/kgio/blocking_io_region.h b/ext/kgio/blocking_io_region.h index 10e7533..db76eac 100644 --- a/ext/kgio/blocking_io_region.h +++ b/ext/kgio/blocking_io_region.h @@ -1,4 +1,4 @@ -#ifdef KGIO_HAVE_THREAD_CALL_WITHOUT_GVL +#ifdef KGIO_WITHOUT_GVL # if defined(HAVE_RB_THREAD_IO_BLOCKING_REGION) /* temporary API for Ruby 1.9.3 */ VALUE rb_thread_io_blocking_region(rb_blocking_function_t *, void *, int); diff --git a/ext/kgio/connect.c b/ext/kgio/connect.c index 2261b10..19cfa8f 100644 --- a/ext/kgio/connect.c +++ b/ext/kgio/connect.c @@ -145,7 +145,7 @@ static const struct sockaddr *sockaddr_from(socklen_t *addrlen, VALUE addr) return NULL; } -#if defined(MSG_FASTOPEN) && defined(KGIO_HAVE_THREAD_CALL_WITHOUT_GVL) +#if defined(MSG_FASTOPEN) && defined(KGIO_WITHOUT_GVL) #ifndef HAVE_RB_STR_SUBSEQ #define rb_str_subseq rb_str_substr #endif @@ -383,7 +383,7 @@ void init_kgio_connect(void) rb_define_singleton_method(cKgio_Socket, "new", kgio_new, -1); rb_define_singleton_method(cKgio_Socket, "connect", kgio_connect, 1); rb_define_singleton_method(cKgio_Socket, "start", kgio_start, 1); -#if defined(MSG_FASTOPEN) && defined(KGIO_HAVE_THREAD_CALL_WITHOUT_GVL) +#if defined(MSG_FASTOPEN) && defined(KGIO_WITHOUT_GVL) rb_define_method(cKgio_Socket, "kgio_fastopen", fastopen, 2); #endif /* diff --git a/ext/kgio/kgio.h b/ext/kgio/kgio.h index 6c5da5b..66a8705 100644 --- a/ext/kgio/kgio.h +++ b/ext/kgio/kgio.h @@ -39,16 +39,17 @@ void kgio_autopush_send(VALUE); VALUE kgio_call_wait_writable(VALUE io); VALUE kgio_call_wait_readable(VALUE io); -#if defined(HAVE_RB_THREAD_CALL_WITHOUT_GVL) -# define KGIO_HAVE_THREAD_CALL_WITHOUT_GVL 1 -typedef void *(*kgio_blocking_fn_t)(void*); -# define rb_thread_blocking_region(fn,data1,ubf,data2) \ - rb_thread_call_without_gvl((kgio_blocking_fn_t)(fn),(data1),(ubf),(data2)) +#if defined(HAVE_RB_THREAD_CALL_WITHOUT_GVL) && \ + !defined(HAVE_RB_THREAD_BLOCKING_REGION) +# define KGIO_WITHOUT_GVL(fn,data1,ubf,data2) \ + rb_thread_call_without_gvl((fn),(data1),(ubf),(data2)) #elif defined(HAVE_RB_THREAD_BLOCKING_REGION) -# define KGIO_HAVE_THREAD_CALL_WITHOUT_GVL 1 +typedef VALUE(*kgio_blocking_fn_t)(void*); +# define KGIO_WITHOUT_GVL(fn,data1,ubf,data2) \ + rb_thread_blocking_region((kgio_blocking_fn_t)(fn),(data1),(ubf),(data2)) #endif /* HAVE_RB_THREAD_CALL_WITHOUT_GVL || HAVE_RB_THREAD_BLOCKING_REGION */ -#if defined(KGIO_HAVE_THREAD_CALL_WITHOUT_GVL) && defined(HAVE_POLL) +#if defined(KGIO_WITHOUT_GVL) && defined(HAVE_POLL) # define USE_KGIO_POLL #endif /* USE_KGIO_POLL */ diff --git a/ext/kgio/poll.c b/ext/kgio/poll.c index ae8d235..41bebf6 100644 --- a/ext/kgio/poll.c +++ b/ext/kgio/poll.c @@ -107,14 +107,16 @@ static void hash2pollfds(struct poll_args *a) rb_hash_foreach(a->ios, io_to_pollfd_i, (VALUE)a); } -static VALUE nogvl_poll(void *ptr) +static void * nogvl_poll(void *ptr) { struct poll_args *a = ptr; + long n; if (a->timeout > 0) clock_gettime(hopefully_CLOCK_MONOTONIC, &a->start); - return (VALUE)poll(a->fds, a->nfds, a->timeout); + n = poll(a->fds, a->nfds, a->timeout); + return (void *)n; } static VALUE poll_result(int nr, struct poll_args *a) @@ -145,7 +147,7 @@ static VALUE do_poll(VALUE args) retry: hash2pollfds(a); - nr = (long)rb_thread_blocking_region(nogvl_poll, a, RUBY_UBF_IO, NULL); + nr = (long)KGIO_WITHOUT_GVL(nogvl_poll, a, RUBY_UBF_IO, NULL); if (nr < 0) { if (interrupted()) { if (retryable(a)) { diff --git a/ext/kgio/tryopen.c b/ext/kgio/tryopen.c index 50bacf4..20f3f6d 100644 --- a/ext/kgio/tryopen.c +++ b/ext/kgio/tryopen.c @@ -33,23 +33,24 @@ struct open_args { # define rb_cloexec_open(p,f,m) open((p),(f),(m)) #endif -static VALUE nogvl_open(void *ptr) +static void * nogvl_open(void *ptr) { struct open_args *o = ptr; + long fd = (long)rb_cloexec_open(o->pathname, o->flags, o->mode); - return (VALUE)rb_cloexec_open(o->pathname, o->flags, o->mode); + return (void *)fd; } -#ifndef KGIO_HAVE_THREAD_CALL_WITHOUT_GVL +#ifndef KGIO_WITHOUT_GVL # define RUBY_UBF_IO ((void *)(-1)) # include "rubysig.h" -typedef void rb_unblock_function_t(void *); -typedef VALUE rb_blocking_function_t(void *); -static VALUE my_thread_blocking_region( - rb_blocking_function_t *fn, void *data1, - rb_unblock_function_t *ubf, void *data2) +typedef void my_unblock_function_t(void *); +typedef void *my_blocking_function_t(void *); +static void * my_thread_blocking_region( + my_blocking_function_t *fn, void *data1, + my_unblock_function_t *ubf, void *data2) { - VALUE rv; + void *rv; TRAP_BEG; /* for FIFO */ rv = fn(data1); @@ -57,9 +58,9 @@ static VALUE my_thread_blocking_region( return rv; } -#define rb_thread_blocking_region(fn,data1,ubf,data2) \ +#define KGIO_WITHOUT_GVL(fn,data1,ubf,data2) \ my_thread_blocking_region((fn),(data1),(ubf),(data2)) -#endif /* ! KGIO_HAVE_THREAD_CALL_WITHOUT_GVL */ +#endif /* ! KGIO_WITHOUT_GVL */ /* * call-seq: @@ -107,7 +108,7 @@ static VALUE s_tryopen(int argc, VALUE *argv, VALUE klass) } retry: - fd = (long)rb_thread_blocking_region(nogvl_open, &o, RUBY_UBF_IO, 0); + fd = (long)KGIO_WITHOUT_GVL(nogvl_open, &o, RUBY_UBF_IO, 0); if (fd < 0) { if (errno == EMFILE || errno == ENFILE || errno == ENOMEM) { rb_gc(); diff --git a/ext/kgio/write.c b/ext/kgio/write.c index fa152d8..cdf97b1 100644 --- a/ext/kgio/write.c +++ b/ext/kgio/write.c @@ -155,7 +155,7 @@ static VALUE kgio_trysend(VALUE io, VALUE str) # define kgio_trysend kgio_trywrite #endif /* ! USE_MSG_DONTWAIT */ -#if defined(KGIO_HAVE_THREAD_CALL_WITHOUT_GVL) +#if defined(KGIO_WITHOUT_GVL) # include "blocking_io_region.h" #ifdef MSG_DONTWAIT /* Linux only */ # define MY_MSG_DONTWAIT (MSG_DONTWAIT) @@ -256,7 +256,7 @@ void init_kgio_write(void) rb_define_method(mSocketMethods, "kgio_write", kgio_send, 1); rb_define_method(mSocketMethods, "kgio_trywrite", kgio_trysend, 1); -#if defined(KGIO_HAVE_THREAD_CALL_WITHOUT_GVL) +#if defined(KGIO_WITHOUT_GVL) rb_define_method(mSocketMethods, "kgio_syssend", kgio_syssend, 2); #endif } |