diff options
-rw-r--r-- | ChangeLog | 17 | ||||
-rw-r--r-- | ext/curses/curses.c | 83 | ||||
-rw-r--r-- | include/ruby/io.h | 2 |
3 files changed, 82 insertions, 20 deletions
@@ -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> * configure.in (cflags, cxxflags): remove duplicating options. diff --git a/ext/curses/curses.c b/ext/curses/curses.c index c8c63de395..7f68b2186a 100644 --- a/ext/curses/curses.c +++ b/ext/curses/curses.c @@ -410,15 +410,22 @@ curses_addstr(VALUE obj, VALUE str) return Qnil; } +static VALUE +getch_func(void *arg) +{ + int *ip = (int *)arg; + *ip = getch(); + return Qnil; +} + /* def getch */ static VALUE curses_getch(VALUE obj) { int c; - rb_read_check(stdin); curses_stdscr(); - c = getch(); + rb_thread_blocking_region(getch_func, (void *)&c, RUBY_UBF_IO, 0); if (c == EOF) return Qnil; if (rb_isprint(c)) { char ch = (char)c; @@ -428,19 +435,29 @@ curses_getch(VALUE obj) return UINT2NUM(c); } -/* def getstr */ +/* This should be big enough.. I hope */ +#define GETSTR_BUF_SIZE 1024 + static VALUE -curses_getstr(VALUE obj) +getstr_func(void *arg) { - char rtn[1024]; /* This should be big enough.. I hope */ - - curses_stdscr(); - rb_read_check(stdin); + char *rtn = (char *)arg; #if defined(HAVE_GETNSTR) - getnstr(rtn,1023); + getnstr(rtn,GETSTR_BUF_SIZE-1); #else getstr(rtn); #endif + return Qnil; +} + +/* def getstr */ +static VALUE +curses_getstr(VALUE obj) +{ + char rtn[GETSTR_BUF_SIZE]; + + curses_stdscr(); + rb_thread_blocking_region(getstr_func, (void *)rtn, RUBY_UBF_IO, 0); return rb_locale_str_new_cstr(rtn); } @@ -1213,16 +1230,31 @@ window_addstr2(VALUE obj, VALUE str) 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 */ static VALUE window_getch(VALUE obj) { struct windata *winp; + struct wgetch_arg arg; int c; - rb_read_check(stdin); 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 (rb_isprint(c)) { char ch = (char)c; @@ -1232,21 +1264,34 @@ window_getch(VALUE obj) 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 */ static VALUE window_getstr(VALUE obj) { struct windata *winp; - char rtn[1024]; /* This should be big enough.. I hope */ + struct wgetstr_arg arg; GetWINDOW(obj, winp); - rb_read_check(stdin); -#if defined(HAVE_WGETNSTR) - wgetnstr(winp->window, rtn, 1023); -#else - wgetstr(winp->window, rtn); -#endif - return rb_locale_str_new_cstr(rtn); + arg.win = winp->window; + rb_thread_blocking_region(wgetstr_func, (void *)&arg, RUBY_UBF_IO, 0); + return rb_locale_str_new_cstr(arg.rtn); } /* def delch */ diff --git a/include/ruby/io.h b/include/ruby/io.h index 45384db586..2ccaf0f1f9 100644 --- a/include/ruby/io.h +++ b/include/ruby/io.h @@ -164,7 +164,7 @@ NORETURN(void rb_eof_error(void)); void rb_io_read_check(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 0 |