* ext/curses/curses.c: use rb_thread_blocking_region to avoid

rb_read_check.  This makes other threads runnable in getstr and
  wgetstr.
  (getch_func): extracted from curses_getch.
  (curses_getch): use rb_thread_blocking_region with getch_func.
  (getstr_func): extracted from curses_getstr.
  (curses_getstr): use rb_thread_blocking_region with getstr_func.
  (wgetch_func): extracted from window_getch.
  (window_getch): use rb_thread_blocking_region with wgetch_func.
  (wgetstr_func): extracted from window_getstr.
  (window_getstr): use rb_thread_blocking_region with wgetstr_func.

* include/ruby/io.h (rb_read_check): deprecated because it access
  internal of stdio.


git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@25286 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
akr 2009-10-10 10:49:47 +00:00
parent 7c669071c4
commit f65dbbd24a
3 changed files with 82 additions and 20 deletions

View File

@ -1,3 +1,20 @@
Sat Oct 10 19:03:29 2009 Tanaka Akira <akr@fsij.org>
* ext/curses/curses.c: use rb_thread_blocking_region to avoid
rb_read_check. This makes other threads runnable in getstr and
wgetstr.
(getch_func): extracted from curses_getch.
(curses_getch): use rb_thread_blocking_region with getch_func.
(getstr_func): extracted from curses_getstr.
(curses_getstr): use rb_thread_blocking_region with getstr_func.
(wgetch_func): extracted from window_getch.
(window_getch): use rb_thread_blocking_region with wgetch_func.
(wgetstr_func): extracted from window_getstr.
(window_getstr): use rb_thread_blocking_region with wgetstr_func.
* include/ruby/io.h (rb_read_check): deprecated because it access
internal of stdio.
Sat Oct 10 18:59:17 2009 Nobuyoshi Nakada <nobu@ruby-lang.org> Sat Oct 10 18:59:17 2009 Nobuyoshi Nakada <nobu@ruby-lang.org>
* configure.in (cflags, cxxflags): remove duplicating options. * configure.in (cflags, cxxflags): remove duplicating options.

View File

@ -410,15 +410,22 @@ curses_addstr(VALUE obj, VALUE str)
return Qnil; return Qnil;
} }
static VALUE
getch_func(void *arg)
{
int *ip = (int *)arg;
*ip = getch();
return Qnil;
}
/* def getch */ /* def getch */
static VALUE static VALUE
curses_getch(VALUE obj) curses_getch(VALUE obj)
{ {
int c; int c;
rb_read_check(stdin);
curses_stdscr(); curses_stdscr();
c = getch(); rb_thread_blocking_region(getch_func, (void *)&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;
@ -428,19 +435,29 @@ curses_getch(VALUE obj)
return UINT2NUM(c); return UINT2NUM(c);
} }
/* This should be big enough.. I hope */
#define GETSTR_BUF_SIZE 1024
static VALUE
getstr_func(void *arg)
{
char *rtn = (char *)arg;
#if defined(HAVE_GETNSTR)
getnstr(rtn,GETSTR_BUF_SIZE-1);
#else
getstr(rtn);
#endif
return Qnil;
}
/* def getstr */ /* def getstr */
static VALUE static VALUE
curses_getstr(VALUE obj) curses_getstr(VALUE obj)
{ {
char rtn[1024]; /* This should be big enough.. I hope */ char rtn[GETSTR_BUF_SIZE];
curses_stdscr(); curses_stdscr();
rb_read_check(stdin); rb_thread_blocking_region(getstr_func, (void *)rtn, RUBY_UBF_IO, 0);
#if defined(HAVE_GETNSTR)
getnstr(rtn,1023);
#else
getstr(rtn);
#endif
return rb_locale_str_new_cstr(rtn); return rb_locale_str_new_cstr(rtn);
} }
@ -1213,16 +1230,31 @@ window_addstr2(VALUE obj, VALUE str)
return obj; return obj;
} }
struct wgetch_arg {
WINDOW *win;
int c;
};
static VALUE
wgetch_func(void *_arg)
{
struct wgetch_arg *arg = (struct wgetch_arg *)_arg;
arg->c = wgetch(arg->win);
return Qnil;
}
/* def getch */ /* def getch */
static VALUE static VALUE
window_getch(VALUE obj) window_getch(VALUE obj)
{ {
struct windata *winp; struct windata *winp;
struct wgetch_arg arg;
int c; int c;
rb_read_check(stdin);
GetWINDOW(obj, winp); GetWINDOW(obj, winp);
c = wgetch(winp->window); arg.win = winp->window;
rb_thread_blocking_region(wgetch_func, (void *)&arg, RUBY_UBF_IO, 0);
c = arg.c;
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;
@ -1232,21 +1264,34 @@ window_getch(VALUE obj)
return UINT2NUM(c); return UINT2NUM(c);
} }
struct wgetstr_arg {
WINDOW *win;
char rtn[GETSTR_BUF_SIZE];
};
static VALUE
wgetstr_func(void *_arg)
{
struct wgetstr_arg *arg = (struct wgetstr_arg *)_arg;
#if defined(HAVE_WGETNSTR)
wgetnstr(arg->win, arg->rtn, GETSTR_BUF_SIZE-1);
#else
wgetstr(arg->win, arg->rtn);
#endif
return Qnil;
}
/* def getstr */ /* def getstr */
static VALUE static VALUE
window_getstr(VALUE obj) window_getstr(VALUE obj)
{ {
struct windata *winp; struct windata *winp;
char rtn[1024]; /* This should be big enough.. I hope */ struct wgetstr_arg arg;
GetWINDOW(obj, winp); GetWINDOW(obj, winp);
rb_read_check(stdin); arg.win = winp->window;
#if defined(HAVE_WGETNSTR) rb_thread_blocking_region(wgetstr_func, (void *)&arg, RUBY_UBF_IO, 0);
wgetnstr(winp->window, rtn, 1023); return rb_locale_str_new_cstr(arg.rtn);
#else
wgetstr(winp->window, rtn);
#endif
return rb_locale_str_new_cstr(rtn);
} }
/* def delch */ /* def delch */

View File

@ -164,7 +164,7 @@ NORETURN(void rb_eof_error(void));
void rb_io_read_check(rb_io_t*); void rb_io_read_check(rb_io_t*);
int rb_io_read_pending(rb_io_t*); int rb_io_read_pending(rb_io_t*);
void rb_read_check(FILE*); DEPRECATED(void rb_read_check(FILE*));
#if defined(__cplusplus) #if defined(__cplusplus)
#if 0 #if 0