[#47562] [Backport 200 - Backport #8716][Open] segmation fault 正規表現で大量のグループを利用時 — "taka-yoshi (taka-yoshi taka)" <smokeonthewater222@...>

15 messages 2013/08/01

[#47569] [ruby-trunk - Feature #8726][Open] Class#source_location — "takiuchi (Genki Takiuchi)" <genki@...21g.com>

14 messages 2013/08/03

[#47663] Re: [ruby-core:56878] [ruby-trunk - misc #8835][Open] Introducing a semantic versioning scheme and branching policy — "Akinori MUSHA" <knu@...>

At Fri, 30 Aug 2013 21:49:34 +0900,

6 messages 2013/08/30

[ruby-dev:47611] Re: [ruby-cvs:49669] naruse:r42527 (trunk): refix r42525 set stdio_file only if stdio

From: Tanaka Akira <akr@...>
Date: 2013-08-12 02:58:35 UTC
List: ruby-dev #47611
2013年8月12日 11:38 NARUSE, Yui <naruse@airemix.jp>:
> あぁ、[ruby-dev:47608]見てませんでした。
>
>> そこでの f は fdopen で作ったものなので、stdin や stdout と等しくなることは
>> ないと思うんですが、どうなんでしょうか。
>> そんなことはないのでしょうか。
>
> ん?それは元のなんでもかんでも rb_io_stdio_file してたコードがバグってたって話ですか?

rb_io_stdio_file で得られる FILE 構造体の寿命は readline 側からは制御できないので
問題だったのはそうでしょう。

それはそれとして、Ruby 1.9 以降は、blocking regeion で rl_getc を呼べばいいんじゃないの、
と思って
http://bugs.ruby-lang.org/issues/8749
のメールにリプライしたのですが...
なんか残ってないなぁ。

書いたパッチはこんなかんじで、こういう方向性はどうかなぁ。
editline での問題を解決するかどうかはわからないんですが。

% svn diff --diff-cmd diff -x '-u -p'
Index: ext/readline/readline.c
===================================================================
--- ext/readline/readline.c	(revision 42429)
+++ ext/readline/readline.c	(working copy)
@@ -35,6 +35,7 @@

 #include "ruby/ruby.h"
 #include "ruby/io.h"
+#include "ruby/thread.h"

 #ifdef HAVE_UNISTD_H
 #include <unistd.h>
@@ -135,35 +136,35 @@ static VALUE readline_outstream;
 #define rl_getc(f) EOF
 #endif

-static int readline_getc(FILE *);
+struct getc_struct {
+  FILE *input;
+  int ret;
+};
+
 static int
-readline_getc(FILE *input)
+getc_body(FILE *input)
 {
-    rb_io_t *ifp = 0;
-    VALUE c;
-    if (!readline_instream) return rl_getc(input);
-    GetOpenFile(readline_instream, ifp);
-    if (rl_instream != ifp->stdio_file) return rl_getc(input);
 #if defined(_WIN32)
+    int fd = fileno(input);
     {
         INPUT_RECORD ir;
         int n;
         static int prior_key = '0';
         for (;;) {
             if (prior_key > 0xff) {
-                prior_key = rl_getc(ifp->stdio_file);
+                prior_key = rl_getc(input);
                 return prior_key;
             }
-            if (PeekConsoleInput((HANDLE)_get_osfhandle(ifp->fd),
&ir, 1, &n)) {
+            if (PeekConsoleInput((HANDLE)_get_osfhandle(fd), &ir, 1, &n)) {
                 if (n == 1) {
                     if (ir.EventType == KEY_EVENT &&
ir.Event.KeyEvent.bKeyDown) {
-                        prior_key = rl_getc(ifp->stdio_file);
+                        prior_key = rl_getc(input);
                         return prior_key;
                     } else {
-
ReadConsoleInput((HANDLE)_get_osfhandle(ifp->fd), &ir, 1, &n);
+                        ReadConsoleInput((HANDLE)_get_osfhandle(fd),
&ir, 1, &n);
                     }
                 } else {
-                    HANDLE h = (HANDLE)_get_osfhandle(ifp->fd);
+                    HANDLE h = (HANDLE)_get_osfhandle(fd);
                     rb_w32_wait_events(&h, 1, INFINITE);
                 }
             } else {
@@ -172,21 +173,27 @@ readline_getc(FILE *input)
         }
     }
 #endif
-    c = rb_io_getbyte(readline_instream);
-    if (NIL_P(c)) return EOF;
-#ifdef ESC
-    if (c == INT2FIX(ESC) &&
-        RL_ISSTATE(RL_STATE_ISEARCH) && /* isn't needed in other states? */
-        rb_io_read_pending(ifp)) {
-        int meta = 0;
-        c = rb_io_getbyte(readline_instream);
-        if (FIXNUM_P(c) && isascii(FIX2INT(c))) meta = 1;
-        rb_io_ungetbyte(readline_instream, c);
-        if (meta) rl_execute_next(ESC);
-        return ESC;
-    }
-#endif
-    return FIX2INT(c);
+    return rl_getc(input);
+}
+
+static void *
+getc_func(void *data1)
+{
+    struct getc_struct *p = data1;
+    FILE *input = p->input;
+    p->ret = getc_body(input);
+    return NULL;
+}
+
+static int readline_getc(FILE *);
+static int
+readline_getc(FILE *input)
+{
+    struct getc_struct data;
+    data.input = input;
+    data.ret = -1;
+    rb_thread_call_without_gvl(getc_func, &data, RUBY_UBF_IO, NULL);
+    return data.ret;
 }
 #elif defined HAVE_RL_EVENT_HOOK
 #define BUSY_WAIT 0
-- 
[田中 哲][たなか あきら][Tanaka Akira]

In This Thread