[前][次][番号順一覧][スレッド一覧]

ruby-changes:13510

From: akr <ko1@a...>
Date: Sat, 10 Oct 2009 19:51:48 +0900 (JST)
Subject: [ruby-changes:13510] Ruby:r25286 (trunk): * ext/curses/curses.c: use rb_thread_blocking_region to avoid

akr	2009-10-10 19:49:47 +0900 (Sat, 10 Oct 2009)

  New Revision: 25286

  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=25286

  Log:
    * 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.

  Modified files:
    trunk/ChangeLog
    trunk/ext/curses/curses.c
    trunk/include/ruby/io.h

Index: include/ruby/io.h
===================================================================
--- include/ruby/io.h	(revision 25285)
+++ include/ruby/io.h	(revision 25286)
@@ -164,7 +164,7 @@
 
 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
Index: ChangeLog
===================================================================
--- ChangeLog	(revision 25285)
+++ ChangeLog	(revision 25286)
@@ -1,3 +1,20 @@
+Sat Oct 10 19:03:29 2009  Tanaka Akira  <akr@f...>
+
+	* 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@r...>
 
 	* configure.in (cflags, cxxflags): remove duplicating options.
Index: ext/curses/curses.c
===================================================================
--- ext/curses/curses.c	(revision 25285)
+++ ext/curses/curses.c	(revision 25286)
@@ -410,15 +410,22 @@
     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 @@
     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 */
 static VALUE
 curses_getstr(VALUE obj)
 {
-    char rtn[1024]; /* This should be big enough.. I hope */
+    char rtn[GETSTR_BUF_SIZE];
 
     curses_stdscr();
-    rb_read_check(stdin);
-#if defined(HAVE_GETNSTR)
-    getnstr(rtn,1023);
-#else
-    getstr(rtn);
-#endif
+    rb_thread_blocking_region(getstr_func, (void *)rtn, RUBY_UBF_IO, 0);
     return rb_locale_str_new_cstr(rtn);
 }
 
@@ -1213,16 +1230,31 @@
     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 @@
     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 */

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]