1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00

rb_thread_call_without_gvl

* include/ruby/thread.h: new header file for thread stuff.
* thread.c (rb_thread_call_without_gvl): export.  [Feature#4328]
  returns void* instead of VALUE.  [Feature #5543]
* thread.c (rb_thread_blocking_region): deprecate.  [ruby-core:46295]

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@36355 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
nobu 2012-07-10 13:57:11 +00:00
parent 1a853390ee
commit c51a826764
21 changed files with 134 additions and 80 deletions

View file

@ -1,3 +1,12 @@
Tue Jul 10 22:57:03 2012 Nobuyoshi Nakada <nobu@ruby-lang.org>
* include/ruby/thread.h: new header file for thread stuff.
* thread.c (rb_thread_call_without_gvl): export. [Feature#4328]
returns void* instead of VALUE. [Feature #5543]
* thread.c (rb_thread_blocking_region): deprecate. [ruby-core:46295]
Tue Jul 10 10:48:59 2012 NAKAMURA Usaku <usa@ruby-lang.org> Tue Jul 10 10:48:59 2012 NAKAMURA Usaku <usa@ruby-lang.org>
* include/ruby/win32.h (NT, NtInitialize): removed unused old macros. * include/ruby/win32.h (NT, NtInitialize): removed unused old macros.

View file

@ -10,6 +10,7 @@
**********************************************************************/ **********************************************************************/
#include "ruby/ruby.h" #include "ruby/ruby.h"
#include "ruby/thread.h"
#include "ruby/util.h" #include "ruby/util.h"
#include "internal.h" #include "internal.h"
@ -2591,7 +2592,7 @@ struct big_div_struct {
VALUE stop; VALUE stop;
}; };
static VALUE static void *
bigdivrem1(void *ptr) bigdivrem1(void *ptr)
{ {
struct big_div_struct *bds = (struct big_div_struct*)ptr; struct big_div_struct *bds = (struct big_div_struct*)ptr;
@ -2605,7 +2606,7 @@ bigdivrem1(void *ptr)
j = nx==ny?nx+1:nx; j = nx==ny?nx+1:nx;
for (nyzero = 0; !yds[nyzero]; nyzero++); for (nyzero = 0; !yds[nyzero]; nyzero++);
do { do {
if (bds->stop) return Qnil; if (bds->stop) return 0;
if (zds[j] == yds[ny-1]) q = (BDIGIT)BIGRAD-1; if (zds[j] == yds[ny-1]) q = (BDIGIT)BIGRAD-1;
else q = (BDIGIT)((BIGUP(zds[j]) + zds[j-1])/yds[ny-1]); else q = (BDIGIT)((BIGUP(zds[j]) + zds[j-1])/yds[ny-1]);
if (q) { if (q) {
@ -2633,7 +2634,7 @@ bigdivrem1(void *ptr)
} }
zds[j] = q; zds[j] = q;
} while (--j >= ny); } while (--j >= ny);
return Qnil; return 0;
} }
static void static void
@ -2725,7 +2726,7 @@ bigdivrem(VALUE x, VALUE y, volatile VALUE *divp, volatile VALUE *modp)
bds.yds = yds; bds.yds = yds;
bds.stop = Qfalse; bds.stop = Qfalse;
if (nx > 10000 || ny > 10000) { if (nx > 10000 || ny > 10000) {
rb_thread_blocking_region(bigdivrem1, &bds, rb_big_stop, &bds.stop); rb_thread_call_without_gvl(bigdivrem1, &bds, rb_big_stop, &bds.stop);
} }
else { else {
bigdivrem1(&bds); bigdivrem1(&bds);

View file

@ -616,7 +616,7 @@ addr2line.$(OBJEXT): {$(VPATH)}addr2line.c {$(VPATH)}addr2line.h {$(VPATH)}confi
array.$(OBJEXT): {$(VPATH)}array.c $(RUBY_H_INCLUDES) {$(VPATH)}util.h \ array.$(OBJEXT): {$(VPATH)}array.c $(RUBY_H_INCLUDES) {$(VPATH)}util.h \
$(ENCODING_H_INCLUDES) {$(VPATH)}internal.h $(ENCODING_H_INCLUDES) {$(VPATH)}internal.h
bignum.$(OBJEXT): {$(VPATH)}bignum.c $(RUBY_H_INCLUDES) {$(VPATH)}util.h \ bignum.$(OBJEXT): {$(VPATH)}bignum.c $(RUBY_H_INCLUDES) {$(VPATH)}util.h \
{$(VPATH)}internal.h {$(VPATH)}thread.h {$(VPATH)}internal.h
class.$(OBJEXT): {$(VPATH)}class.c $(RUBY_H_INCLUDES) \ class.$(OBJEXT): {$(VPATH)}class.c $(RUBY_H_INCLUDES) \
$(VM_CORE_H_INCLUDES) {$(VPATH)}debug.h {$(VPATH)}internal.h \ $(VM_CORE_H_INCLUDES) {$(VPATH)}debug.h {$(VPATH)}internal.h \
{$(VPATH)}constant.h {$(VPATH)}constant.h
@ -658,13 +658,15 @@ file.$(OBJEXT): {$(VPATH)}file.c $(RUBY_H_INCLUDES) {$(VPATH)}io.h \
gc.$(OBJEXT): {$(VPATH)}gc.c $(RUBY_H_INCLUDES) {$(VPATH)}re.h \ gc.$(OBJEXT): {$(VPATH)}gc.c $(RUBY_H_INCLUDES) {$(VPATH)}re.h \
{$(VPATH)}regex.h $(ENCODING_H_INCLUDES) $(VM_CORE_H_INCLUDES) \ {$(VPATH)}regex.h $(ENCODING_H_INCLUDES) $(VM_CORE_H_INCLUDES) \
{$(VPATH)}gc.h {$(VPATH)}io.h {$(VPATH)}eval_intern.h {$(VPATH)}util.h \ {$(VPATH)}gc.h {$(VPATH)}io.h {$(VPATH)}eval_intern.h {$(VPATH)}util.h \
{$(VPATH)}debug.h {$(VPATH)}internal.h {$(VPATH)}constant.h {$(VPATH)}debug.h {$(VPATH)}internal.h {$(VPATH)}constant.h \
{$(VPATH)}thread.h
hash.$(OBJEXT): {$(VPATH)}hash.c $(RUBY_H_INCLUDES) {$(VPATH)}util.h \ hash.$(OBJEXT): {$(VPATH)}hash.c $(RUBY_H_INCLUDES) {$(VPATH)}util.h \
$(ENCODING_H_INCLUDES) $(ENCODING_H_INCLUDES)
inits.$(OBJEXT): {$(VPATH)}inits.c $(RUBY_H_INCLUDES) \ inits.$(OBJEXT): {$(VPATH)}inits.c $(RUBY_H_INCLUDES) \
{$(VPATH)}internal.h {$(VPATH)}internal.h
io.$(OBJEXT): {$(VPATH)}io.c $(RUBY_H_INCLUDES) {$(VPATH)}io.h \ io.$(OBJEXT): {$(VPATH)}io.c $(RUBY_H_INCLUDES) {$(VPATH)}io.h \
{$(VPATH)}util.h $(ENCODING_H_INCLUDES) {$(VPATH)}dln.h {$(VPATH)}internal.h {$(VPATH)}util.h $(ENCODING_H_INCLUDES) {$(VPATH)}dln.h \
{$(VPATH)}internal.h {$(VPATH)}thread.h
main.$(OBJEXT): {$(VPATH)}main.c $(RUBY_H_INCLUDES) {$(VPATH)}debug.h \ main.$(OBJEXT): {$(VPATH)}main.c $(RUBY_H_INCLUDES) {$(VPATH)}debug.h \
{$(VPATH)}node.h {$(VPATH)}node.h
marshal.$(OBJEXT): {$(VPATH)}marshal.c $(RUBY_H_INCLUDES) {$(VPATH)}io.h \ marshal.$(OBJEXT): {$(VPATH)}marshal.c $(RUBY_H_INCLUDES) {$(VPATH)}io.h \
@ -690,7 +692,8 @@ proc.$(OBJEXT): {$(VPATH)}proc.c {$(VPATH)}eval_intern.h \
{$(VPATH)}debug.h {$(VPATH)}internal.h {$(VPATH)}iseq.h {$(VPATH)}debug.h {$(VPATH)}internal.h {$(VPATH)}iseq.h
process.$(OBJEXT): {$(VPATH)}process.c $(RUBY_H_INCLUDES) \ process.$(OBJEXT): {$(VPATH)}process.c $(RUBY_H_INCLUDES) \
{$(VPATH)}util.h {$(VPATH)}io.h $(ENCODING_H_INCLUDES) {$(VPATH)}dln.h \ {$(VPATH)}util.h {$(VPATH)}io.h $(ENCODING_H_INCLUDES) {$(VPATH)}dln.h \
$(VM_CORE_H_INCLUDES) {$(VPATH)}debug.h {$(VPATH)}internal.h $(VM_CORE_H_INCLUDES) {$(VPATH)}debug.h {$(VPATH)}internal.h \
{$(VPATH)}thread.h
random.$(OBJEXT): {$(VPATH)}random.c $(RUBY_H_INCLUDES) random.$(OBJEXT): {$(VPATH)}random.c $(RUBY_H_INCLUDES)
range.$(OBJEXT): {$(VPATH)}range.c $(RUBY_H_INCLUDES) \ range.$(OBJEXT): {$(VPATH)}range.c $(RUBY_H_INCLUDES) \
$(ENCODING_H_INCLUDES) {$(VPATH)}internal.h $(ENCODING_H_INCLUDES) {$(VPATH)}internal.h
@ -730,7 +733,7 @@ struct.$(OBJEXT): {$(VPATH)}struct.c $(RUBY_H_INCLUDES) {$(VPATH)}internal.h
thread.$(OBJEXT): {$(VPATH)}thread.c {$(VPATH)}eval_intern.h \ thread.$(OBJEXT): {$(VPATH)}thread.c {$(VPATH)}eval_intern.h \
$(RUBY_H_INCLUDES) {$(VPATH)}gc.h $(VM_CORE_H_INCLUDES) \ $(RUBY_H_INCLUDES) {$(VPATH)}gc.h $(VM_CORE_H_INCLUDES) \
{$(VPATH)}debug.h {$(VPATH)}thread_$(THREAD_MODEL).c $(ENCODING_H_INCLUDES) \ {$(VPATH)}debug.h {$(VPATH)}thread_$(THREAD_MODEL).c $(ENCODING_H_INCLUDES) \
{$(VPATH)}internal.h {$(VPATH)}io.h {$(VPATH)}internal.h {$(VPATH)}io.h {$(VPATH)}thread.h
transcode.$(OBJEXT): {$(VPATH)}transcode.c $(RUBY_H_INCLUDES) \ transcode.$(OBJEXT): {$(VPATH)}transcode.c $(RUBY_H_INCLUDES) \
$(ENCODING_H_INCLUDES) {$(VPATH)}transcode_data.h {$(VPATH)}internal.h $(ENCODING_H_INCLUDES) {$(VPATH)}transcode_data.h {$(VPATH)}internal.h
cont.$(OBJEXT): {$(VPATH)}cont.c $(RUBY_H_INCLUDES) \ cont.$(OBJEXT): {$(VPATH)}cont.c $(RUBY_H_INCLUDES) \

View file

@ -18,6 +18,7 @@
#include "ruby.h" #include "ruby.h"
#include "ruby/io.h" #include "ruby/io.h"
#include "ruby/thread.h"
#if defined(HAVE_NCURSES_H) #if defined(HAVE_NCURSES_H)
# include <ncurses.h> # include <ncurses.h>
@ -634,12 +635,12 @@ curses_addstr(VALUE obj, VALUE str)
return Qnil; return Qnil;
} }
static VALUE static void *
getch_func(void *arg) getch_func(void *arg)
{ {
int *ip = (int *)arg; int *ip = (int *)arg;
*ip = getch(); *ip = getch();
return Qnil; return 0;
} }
/* /*
@ -656,7 +657,7 @@ curses_getch(VALUE obj)
int c; int c;
curses_stdscr(); curses_stdscr();
rb_thread_blocking_region(getch_func, (void *)&c, RUBY_UBF_IO, 0); rb_thread_call_without_gvl(getch_func, &c, RUBY_UBF_IO, 0);
if (c == EOF) return Qnil; if (c == EOF) return Qnil;
if (rb_isprint(c)) { if (rb_isprint(c)) {
char ch = (char)c; char ch = (char)c;
@ -669,7 +670,7 @@ curses_getch(VALUE obj)
/* This should be big enough.. I hope */ /* This should be big enough.. I hope */
#define GETSTR_BUF_SIZE 1024 #define GETSTR_BUF_SIZE 1024
static VALUE static void *
getstr_func(void *arg) getstr_func(void *arg)
{ {
char *rtn = (char *)arg; char *rtn = (char *)arg;
@ -678,7 +679,7 @@ getstr_func(void *arg)
#else #else
getstr(rtn); getstr(rtn);
#endif #endif
return Qnil; return 0;
} }
/* /*
@ -693,7 +694,7 @@ curses_getstr(VALUE obj)
char rtn[GETSTR_BUF_SIZE]; char rtn[GETSTR_BUF_SIZE];
curses_stdscr(); curses_stdscr();
rb_thread_blocking_region(getstr_func, (void *)rtn, RUBY_UBF_IO, 0); rb_thread_call_without_gvl(getstr_func, rtn, RUBY_UBF_IO, 0);
return rb_locale_str_new_cstr(rtn); return rb_locale_str_new_cstr(rtn);
} }
@ -1955,12 +1956,12 @@ struct wgetch_arg {
int c; int c;
}; };
static VALUE static void *
wgetch_func(void *_arg) wgetch_func(void *_arg)
{ {
struct wgetch_arg *arg = (struct wgetch_arg *)_arg; struct wgetch_arg *arg = (struct wgetch_arg *)_arg;
arg->c = wgetch(arg->win); arg->c = wgetch(arg->win);
return Qnil; return 0;
} }
/* /*
@ -1980,7 +1981,7 @@ window_getch(VALUE obj)
GetWINDOW(obj, winp); GetWINDOW(obj, winp);
arg.win = winp->window; arg.win = winp->window;
rb_thread_blocking_region(wgetch_func, (void *)&arg, RUBY_UBF_IO, 0); rb_thread_call_without_gvl(wgetch_func, (void *)&arg, RUBY_UBF_IO, 0);
c = arg.c; c = arg.c;
if (c == EOF) return Qnil; if (c == EOF) return Qnil;
if (rb_isprint(c)) { if (rb_isprint(c)) {
@ -1996,7 +1997,7 @@ struct wgetstr_arg {
char rtn[GETSTR_BUF_SIZE]; char rtn[GETSTR_BUF_SIZE];
}; };
static VALUE static void *
wgetstr_func(void *_arg) wgetstr_func(void *_arg)
{ {
struct wgetstr_arg *arg = (struct wgetstr_arg *)_arg; struct wgetstr_arg *arg = (struct wgetstr_arg *)_arg;
@ -2005,7 +2006,7 @@ wgetstr_func(void *_arg)
#else #else
wgetstr(arg->win, arg->rtn); wgetstr(arg->win, arg->rtn);
#endif #endif
return Qnil; return 0;
} }
/* /*
@ -2022,7 +2023,7 @@ window_getstr(VALUE obj)
GetWINDOW(obj, winp); GetWINDOW(obj, winp);
arg.win = winp->window; arg.win = winp->window;
rb_thread_blocking_region(wgetstr_func, (void *)&arg, RUBY_UBF_IO, 0); rb_thread_call_without_gvl(wgetstr_func, (void *)&arg, RUBY_UBF_IO, 0);
return rb_locale_str_new_cstr(arg.rtn); return rb_locale_str_new_cstr(arg.rtn);
} }

View file

@ -1 +1 @@
curses.o: curses.c $(hdrdir)/ruby.h $(topdir)/config.h $(hdrdir)/defines.h curses.o: curses.c $(hdrdir)/ruby.h $(topdir)/config.h $(hdrdir)/defines.h $(hdrdir)/thread.h

View file

@ -30,6 +30,7 @@ extern "C" {
#endif #endif
#include <ruby.h> #include <ruby.h>
#include <ruby/io.h> #include <ruby/io.h>
#include <ruby/thread.h>
/* /*
* Check the OpenSSL version * Check the OpenSSL version

View file

@ -90,12 +90,12 @@ struct dh_blocking_gen_arg {
int result; int result;
}; };
static VALUE static void *
dh_blocking_gen(void *arg) dh_blocking_gen(void *arg)
{ {
struct dh_blocking_gen_arg *gen = (struct dh_blocking_gen_arg *)arg; struct dh_blocking_gen_arg *gen = (struct dh_blocking_gen_arg *)arg;
gen->result = DH_generate_parameters_ex(gen->dh, gen->size, gen->gen, gen->cb); gen->result = DH_generate_parameters_ex(gen->dh, gen->size, gen->gen, gen->cb);
return Qnil; return 0;
} }
#endif #endif
@ -123,7 +123,7 @@ dh_generate(int size, int gen)
dh_blocking_gen(&gen_arg); dh_blocking_gen(&gen_arg);
} else { } else {
/* there's a chance to unblock */ /* there's a chance to unblock */
rb_thread_blocking_region(dh_blocking_gen, &gen_arg, ossl_generate_cb_stop, &cb_arg); rb_thread_call_without_gvl(dh_blocking_gen, &gen_arg, ossl_generate_cb_stop, &cb_arg);
} }
if (!gen_arg.result) { if (!gen_arg.result) {

View file

@ -87,12 +87,12 @@ struct dsa_blocking_gen_arg {
int result; int result;
}; };
static VALUE static void *
dsa_blocking_gen(void *arg) dsa_blocking_gen(void *arg)
{ {
struct dsa_blocking_gen_arg *gen = (struct dsa_blocking_gen_arg *)arg; struct dsa_blocking_gen_arg *gen = (struct dsa_blocking_gen_arg *)arg;
gen->result = DSA_generate_parameters_ex(gen->dsa, gen->size, gen->seed, gen->seed_len, gen->counter, gen->h, gen->cb); gen->result = DSA_generate_parameters_ex(gen->dsa, gen->size, gen->seed, gen->seed_len, gen->counter, gen->h, gen->cb);
return Qnil; return 0;
} }
#endif #endif
@ -130,7 +130,7 @@ dsa_generate(int size)
dsa_blocking_gen(&gen_arg); dsa_blocking_gen(&gen_arg);
} else { } else {
/* there's a chance to unblock */ /* there's a chance to unblock */
rb_thread_blocking_region(dsa_blocking_gen, &gen_arg, ossl_generate_cb_stop, &cb_arg); rb_thread_call_without_gvl(dsa_blocking_gen, &gen_arg, ossl_generate_cb_stop, &cb_arg);
} }
if (!gen_arg.result) { if (!gen_arg.result) {
DSA_free(dsa); DSA_free(dsa);

View file

@ -85,12 +85,12 @@ struct rsa_blocking_gen_arg {
int result; int result;
}; };
static VALUE static void *
rsa_blocking_gen(void *arg) rsa_blocking_gen(void *arg)
{ {
struct rsa_blocking_gen_arg *gen = (struct rsa_blocking_gen_arg *)arg; struct rsa_blocking_gen_arg *gen = (struct rsa_blocking_gen_arg *)arg;
gen->result = RSA_generate_key_ex(gen->rsa, gen->size, gen->e, gen->cb); gen->result = RSA_generate_key_ex(gen->rsa, gen->size, gen->e, gen->cb);
return Qnil; return 0;
} }
#endif #endif
@ -133,7 +133,7 @@ rsa_generate(int size, unsigned long exp)
rsa_blocking_gen(&gen_arg); rsa_blocking_gen(&gen_arg);
} else { } else {
/* there's a chance to unblock */ /* there's a chance to unblock */
rb_thread_blocking_region(rsa_blocking_gen, &gen_arg, ossl_generate_cb_stop, &cb_arg); rb_thread_call_without_gvl(rsa_blocking_gen, &gen_arg, ossl_generate_cb_stop, &cb_arg);
} }
if (!gen_arg.result) { if (!gen_arg.result) {
BN_free(e); BN_free(e);

View file

@ -1110,11 +1110,11 @@ struct sendmsg_args_struct {
int flags; int flags;
}; };
static VALUE static void *
nogvl_sendmsg_func(void *ptr) nogvl_sendmsg_func(void *ptr)
{ {
struct sendmsg_args_struct *args = ptr; struct sendmsg_args_struct *args = ptr;
return sendmsg(args->fd, args->msg, args->flags); return (void *)sendmsg(args->fd, args->msg, args->flags);
} }
static ssize_t static ssize_t
@ -1124,7 +1124,7 @@ rb_sendmsg(int fd, const struct msghdr *msg, int flags)
args.fd = fd; args.fd = fd;
args.msg = msg; args.msg = msg;
args.flags = flags; args.flags = flags;
return rb_thread_blocking_region(nogvl_sendmsg_func, &args, RUBY_UBF_IO, 0); return (ssize_t)rb_thread_call_without_gvl(nogvl_sendmsg_func, &args, RUBY_UBF_IO, 0);
} }
static VALUE static VALUE
@ -1368,12 +1368,12 @@ rsock_recvmsg(int socket, struct msghdr *message, int flags)
return recvmsg(socket, message, flags); return recvmsg(socket, message, flags);
} }
static VALUE static void *
nogvl_recvmsg_func(void *ptr) nogvl_recvmsg_func(void *ptr)
{ {
struct recvmsg_args_struct *args = ptr; struct recvmsg_args_struct *args = ptr;
int flags = args->flags; int flags = args->flags;
return rsock_recvmsg(args->fd, args->msg, flags); return (void *)rsock_recvmsg(args->fd, args->msg, flags);
} }
static ssize_t static ssize_t
@ -1383,7 +1383,7 @@ rb_recvmsg(int fd, struct msghdr *msg, int flags)
args.fd = fd; args.fd = fd;
args.msg = msg; args.msg = msg;
args.flags = flags; args.flags = flags;
return rb_thread_blocking_region(nogvl_recvmsg_func, &args, RUBY_UBF_IO, 0); return (ssize_t)rb_thread_call_without_gvl(nogvl_recvmsg_func, &args, RUBY_UBF_IO, 0);
} }
#if defined(HAVE_ST_MSG_CONTROL) #if defined(HAVE_ST_MSG_CONTROL)

View file

@ -1,5 +1,5 @@
SOCK_HEADERS = $(srcdir)/rubysocket.h $(hdrdir)/ruby/ruby.h $(arch_hdrdir)/ruby/config.h \ SOCK_HEADERS = $(srcdir)/rubysocket.h $(hdrdir)/ruby/ruby.h $(arch_hdrdir)/ruby/config.h \
$(hdrdir)/ruby/defines.h $(hdrdir)/ruby/io.h \ $(hdrdir)/ruby/defines.h $(hdrdir)/ruby/io.h $(hdrdir)/ruby/thread.h \
$(srcdir)/addrinfo.h $(srcdir)/sockport.h constdefs.h $(top_srcdir)/internal.h $(srcdir)/addrinfo.h $(srcdir)/sockport.h constdefs.h $(top_srcdir)/internal.h
init.o: init.c $(SOCK_HEADERS) init.o: init.c $(SOCK_HEADERS)

View file

@ -154,11 +154,11 @@ struct getaddrinfo_arg
struct addrinfo **res; struct addrinfo **res;
}; };
static VALUE static void *
nogvl_getaddrinfo(void *arg) nogvl_getaddrinfo(void *arg)
{ {
struct getaddrinfo_arg *ptr = arg; struct getaddrinfo_arg *ptr = arg;
return getaddrinfo(ptr->node, ptr->service, return (void *)getaddrinfo(ptr->node, ptr->service,
ptr->hints, ptr->res); ptr->hints, ptr->res);
} }
#endif #endif
@ -178,7 +178,7 @@ rb_getaddrinfo(const char *node, const char *service,
arg.service = service; arg.service = service;
arg.hints = hints; arg.hints = hints;
arg.res = res; arg.res = res;
ret = (int)BLOCKING_REGION(nogvl_getaddrinfo, &arg); ret = (int)rb_thread_call_without_gvl(nogvl_getaddrinfo, &arg, RUBY_UBF_IO, 0);
return ret; return ret;
#endif #endif
} }
@ -195,11 +195,11 @@ struct getnameinfo_arg
int flags; int flags;
}; };
static VALUE static void *
nogvl_getnameinfo(void *arg) nogvl_getnameinfo(void *arg)
{ {
struct getnameinfo_arg *ptr = arg; struct getnameinfo_arg *ptr = arg;
return getnameinfo(ptr->sa, ptr->salen, return (void *)getnameinfo(ptr->sa, ptr->salen,
ptr->host, (socklen_t)ptr->hostlen, ptr->host, (socklen_t)ptr->hostlen,
ptr->serv, (socklen_t)ptr->servlen, ptr->serv, (socklen_t)ptr->servlen,
ptr->flags); ptr->flags);
@ -223,7 +223,7 @@ rb_getnameinfo(const struct sockaddr *sa, socklen_t salen,
arg.serv = serv; arg.serv = serv;
arg.servlen = servlen; arg.servlen = servlen;
arg.flags = flags; arg.flags = flags;
ret = (int)BLOCKING_REGION(nogvl_getnameinfo, &arg); ret = (int)rb_thread_call_without_gvl(nogvl_getnameinfo, &arg, RUBY_UBF_IO, 0);
return ret; return ret;
#endif #endif
} }

View file

@ -3,6 +3,7 @@
#include "ruby/ruby.h" #include "ruby/ruby.h"
#include "ruby/io.h" #include "ruby/io.h"
#include "ruby/thread.h"
#include "ruby/util.h" #include "ruby/util.h"
#include "internal.h" #include "internal.h"
#include <stdio.h> #include <stdio.h>

View file

@ -10,6 +10,7 @@
#include <zlib.h> #include <zlib.h>
#include <time.h> #include <time.h>
#include <ruby/io.h> #include <ruby/io.h>
#include <ruby/thread.h>
#ifdef HAVE_VALGRIND_MEMCHECK_H #ifdef HAVE_VALGRIND_MEMCHECK_H
# include <valgrind/memcheck.h> # include <valgrind/memcheck.h>
@ -916,7 +917,7 @@ zstream_end(struct zstream *z)
return Qnil; return Qnil;
} }
static VALUE static void *
zstream_run_func(void *ptr) zstream_run_func(void *ptr)
{ {
struct zstream_run_args *args = (struct zstream_run_args *)ptr; struct zstream_run_args *args = (struct zstream_run_args *)ptr;
@ -950,7 +951,7 @@ zstream_run_func(void *ptr)
} }
} }
return (VALUE)err; return (void *)err;
} }
/* /*
@ -994,7 +995,7 @@ zstream_run(struct zstream *z, Bytef *src, long len, int flush)
} }
loop: loop:
err = (int)rb_thread_blocking_region( err = (int)rb_thread_call_without_gvl(
zstream_run_func, (void *)&args, zstream_run_func, (void *)&args,
zstream_unblock_func, (void *)&args); zstream_unblock_func, (void *)&args);

1
gc.c
View file

@ -15,6 +15,7 @@
#include "ruby/st.h" #include "ruby/st.h"
#include "ruby/re.h" #include "ruby/re.h"
#include "ruby/io.h" #include "ruby/io.h"
#include "ruby/thread.h"
#include "ruby/util.h" #include "ruby/util.h"
#include "eval_intern.h" #include "eval_intern.h"
#include "vm_core.h" #include "vm_core.h"

View file

@ -826,6 +826,7 @@ void rb_thread_check_ints(void);
int rb_thread_interrupted(VALUE thval); int rb_thread_interrupted(VALUE thval);
VALUE rb_thread_blocking_region(rb_blocking_function_t *func, void *data1, VALUE rb_thread_blocking_region(rb_blocking_function_t *func, void *data1,
rb_unblock_function_t *ubf, void *data2); rb_unblock_function_t *ubf, void *data2);
DEPRECATED(VALUE rb_thread_blocking_region());
#define RUBY_UBF_IO ((rb_unblock_function_t *)-1) #define RUBY_UBF_IO ((rb_unblock_function_t *)-1)
#define RUBY_UBF_PROCESS ((rb_unblock_function_t *)-1) #define RUBY_UBF_PROCESS ((rb_unblock_function_t *)-1)
VALUE rb_mutex_new(void); VALUE rb_mutex_new(void);

43
include/ruby/thread.h Normal file
View file

@ -0,0 +1,43 @@
/**********************************************************************
thread.h -
$Author: matz $
created at: Tue Jul 10 17:35:43 JST 2012
Copyright (C) 2007 Yukihiro Matsumoto
**********************************************************************/
#ifndef RUBY_THREAD_H
#define RUBY_THREAD_H 1
#if defined(__cplusplus)
extern "C" {
#if 0
} /* satisfy cc-mode */
#endif
#endif
#include "ruby/intern.h"
#if defined __GNUC__ && __GNUC__ >= 4
#pragma GCC visibility push(default)
#endif
void *rb_thread_call_with_gvl(void *(*func)(void *), void *data1);
void *rb_thread_call_without_gvl(void *(*func)(void *), void *data1,
rb_unblock_function_t *ubf, void *data2);
#if defined __GNUC__ && __GNUC__ >= 4
#pragma GCC visibility pop
#endif
#if defined(__cplusplus)
#if 0
{ /* satisfy cc-mode */
#endif
} /* extern "C" { */
#endif
#endif /* RUBY_THREAD_H */

View file

@ -294,16 +294,6 @@ const char *rb_objspace_data_type_name(VALUE obj);
/* Temporary. This API will be removed (renamed). */ /* Temporary. This API will be removed (renamed). */
VALUE rb_thread_io_blocking_region(rb_blocking_function_t *func, void *data1, int fd); VALUE rb_thread_io_blocking_region(rb_blocking_function_t *func, void *data1, int fd);
/* experimental.
* These APIs can be changed on Ruby 1.9.4 or later.
* We will change these APIs (spac, name and so on) if there are something wrong.
* If you use these APIs, catch up future changes.
*/
void *rb_thread_call_with_gvl(void *(*func)(void *), void *data1);
VALUE rb_thread_call_without_gvl(
rb_blocking_function_t *func, void *data1,
rb_unblock_function_t *ubf, void *data2);
/* io.c */ /* io.c */
void rb_maygvl_fd_fix_cloexec(int fd); void rb_maygvl_fd_fix_cloexec(int fd);

14
io.c
View file

@ -13,6 +13,7 @@
#include "ruby/ruby.h" #include "ruby/ruby.h"
#include "ruby/io.h" #include "ruby/io.h"
#include "ruby/thread.h"
#include "dln.h" #include "dln.h"
#include "internal.h" #include "internal.h"
#include <ctype.h> #include <ctype.h>
@ -5009,19 +5010,19 @@ struct sysopen_struct {
mode_t perm; mode_t perm;
}; };
static VALUE static void *
sysopen_func(void *ptr) sysopen_func(void *ptr)
{ {
const struct sysopen_struct *data = ptr; const struct sysopen_struct *data = ptr;
const char *fname = RSTRING_PTR(data->fname); const char *fname = RSTRING_PTR(data->fname);
return (VALUE)rb_cloexec_open(fname, data->oflags, data->perm); return (void *)rb_cloexec_open(fname, data->oflags, data->perm);
} }
static inline int static inline int
rb_sysopen_internal(struct sysopen_struct *data) rb_sysopen_internal(struct sysopen_struct *data)
{ {
int fd; int fd;
fd = (int)rb_thread_blocking_region(sysopen_func, data, RUBY_UBF_IO, 0); fd = (int)rb_thread_call_without_gvl(sysopen_func, data, RUBY_UBF_IO, 0);
if (0 <= fd) if (0 <= fd)
rb_update_max_fd(fd); rb_update_max_fd(fd);
return fd; return fd;
@ -9733,7 +9734,7 @@ nogvl_copy_stream_read_write(struct copy_stream_struct *stp)
} }
} }
static VALUE static void *
nogvl_copy_stream_func(void *arg) nogvl_copy_stream_func(void *arg)
{ {
struct copy_stream_struct *stp = (struct copy_stream_struct *)arg; struct copy_stream_struct *stp = (struct copy_stream_struct *)arg;
@ -9752,7 +9753,7 @@ nogvl_copy_stream_func(void *arg)
#ifdef USE_SENDFILE #ifdef USE_SENDFILE
finish: finish:
#endif #endif
return Qnil; return 0;
} }
static VALUE static VALUE
@ -9938,7 +9939,8 @@ copy_stream_body(VALUE arg)
rb_fd_set(src_fd, &stp->fds); rb_fd_set(src_fd, &stp->fds);
rb_fd_set(dst_fd, &stp->fds); rb_fd_set(dst_fd, &stp->fds);
return rb_thread_blocking_region(nogvl_copy_stream_func, (void*)stp, RUBY_UBF_IO, 0); rb_thread_call_without_gvl(nogvl_copy_stream_func, (void*)stp, RUBY_UBF_IO, 0);
return Qnil;
} }
static VALUE static VALUE

View file

@ -13,6 +13,7 @@
#include "ruby/ruby.h" #include "ruby/ruby.h"
#include "ruby/io.h" #include "ruby/io.h"
#include "ruby/thread.h"
#include "ruby/util.h" #include "ruby/util.h"
#include "internal.h" #include "internal.h"
#include "vm_core.h" #include "vm_core.h"
@ -628,7 +629,7 @@ struct waitpid_arg {
}; };
#endif #endif
static VALUE static void *
rb_waitpid_blocking(void *data) rb_waitpid_blocking(void *data)
{ {
rb_pid_t result; rb_pid_t result;
@ -644,7 +645,7 @@ rb_waitpid_blocking(void *data)
result = wait4(arg->pid, arg->st, arg->flags, NULL); result = wait4(arg->pid, arg->st, arg->flags, NULL);
#endif #endif
return (VALUE)result; return (void *)result;
} }
rb_pid_t rb_pid_t
@ -658,7 +659,7 @@ rb_waitpid(rb_pid_t pid, int *st, int flags)
arg.pid = pid; arg.pid = pid;
arg.st = st; arg.st = st;
arg.flags = flags; arg.flags = flags;
result = (rb_pid_t)rb_thread_blocking_region(rb_waitpid_blocking, &arg, result = (rb_pid_t)rb_thread_call_without_gvl(rb_waitpid_blocking, &arg,
RUBY_UBF_PROCESS, 0); RUBY_UBF_PROCESS, 0);
if (result < 0) { if (result < 0) {
if (errno == EINTR) { if (errno == EINTR) {

View file

@ -48,6 +48,7 @@
#include "gc.h" #include "gc.h"
#include "internal.h" #include "internal.h"
#include "ruby/io.h" #include "ruby/io.h"
#include "ruby/thread.h"
#ifndef USE_NATIVE_THREAD_PRIORITY #ifndef USE_NATIVE_THREAD_PRIORITY
#define USE_NATIVE_THREAD_PRIORITY 0 #define USE_NATIVE_THREAD_PRIORITY 0
@ -1114,12 +1115,11 @@ rb_thread_blocking_region_end(struct rb_blocking_region_buffer *region)
* they will work without GVL, and may acquire GVL * they will work without GVL, and may acquire GVL
* when GC is needed. * when GC is needed.
*/ */
VALUE void *
rb_thread_blocking_region( rb_thread_call_without_gvl(void *(*func)(void *), void *data1,
rb_blocking_function_t *func, void *data1,
rb_unblock_function_t *ubf, void *data2) rb_unblock_function_t *ubf, void *data2)
{ {
VALUE val; void *val;
rb_thread_t *th = GET_THREAD(); rb_thread_t *th = GET_THREAD();
int saved_errno = 0; int saved_errno = 0;
@ -1156,14 +1156,13 @@ rb_thread_io_blocking_region(rb_blocking_function_t *func, void *data1, int fd)
return val; return val;
} }
/* alias of rb_thread_blocking_region() */
VALUE VALUE
rb_thread_call_without_gvl( rb_thread_blocking_region(
rb_blocking_function_t *func, void *data1, rb_blocking_function_t *func, void *data1,
rb_unblock_function_t *ubf, void *data2) rb_unblock_function_t *ubf, void *data2)
{ {
return rb_thread_blocking_region(func, data1, ubf, data2); void *(*f)(void*) = (void *(*)(void*))func;
return (VALUE)rb_thread_call_without_gvl(f, data1, ubf, data2);
} }
/* /*