aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog17
-rw-r--r--ext/curses/curses.c83
-rw-r--r--include/ruby/io.h2
3 files changed, 82 insertions, 20 deletions
diff --git a/ChangeLog b/ChangeLog
index c9e9f3e3c0..bb5127228e 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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