# \[ruby-trunk - Bug #8749\]\[Open\] Readline.readline stops STDOUT?

**URL:** <https://www.ruby-forum.com/t/ruby-trunk-bug-8749-open-readline-readline-stops-stdout/246004>\
**Category:** Development\
**Created:** [August 7, 2013, 3:56pm UTC](https://www.ruby-forum.com/t/ruby-trunk-bug-8749-open-readline-readline-stops-stdout/246004 "2013-08-07T15:56:51Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![Sadaf\_N](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/858c86/32.png) [@Sadaf\_N](https://www.ruby-forum.com/u/Sadaf_N)\
**Post date:** [August 7, 2013, 3:56pm UTC](https://www.ruby-forum.com/t/ruby-trunk-bug-8749-open-readline-readline-stops-stdout/246004/1 "2013-08-07T15:56:51Z")

</div>

Issue #8749 has been reported by no6v (Nobuhiro IMAI).

* * *

Bug #8749: Readline.readline stops STDOUT?

> **[Bug #8749: Readline.readline stops STDOUT? - Ruby master - Ruby Issue...](https://bugs.ruby-lang.org/issues/8749)**
>
> Redmine

Author: no6v (Nobuhiro IMAI)  
Status: Open  
Priority: Normal  
Assignee:  
Category: ext  
Target version:  
ruby -v: ruby 2.1.0dev (2013-08-06 trunk 42402) [x86\_64-linux]  
Backport: 1.9.3: UNKNOWN, 2.0.0: UNKNOWN

=begin  
r42402 $B$G!“0J2\<$N$h$&$J%9%/%j%W%H$N5sF0$,JQ$o$C$F$$$^$9!#(B  
(Enter $B$r2!$9$+$I$&$+$O4X78$J$/$F!”(B)Readline.readline  
$B$r\<B9TCf$KI8=`=PNO$X$N=PNO$,=PMh$J$/$J$C$F$$$k$h$&$K8+$($^$9!#(B

$ cat rl.rb  
require “readline”

th = Thread.new do  
p Readline.readline("\> ")  
end

loop do  
p :hi  
sleep 2  
break unless th.alive?  
end  
$ ruby -v rl.rb  
ruby 2.1.0dev (2013-08-06 trunk 42401) [x86\_64-linux]  
:hi

> :hi  
> :hi  
> :hi  
> :hi  
> # $B$7$P$i$/J|CV$7$F$3$3$G(B Enter  
> “”  
> $ ruby -v rl.rb  
> $ /tmp/ruby/bin/ruby -v /tmp/r.rb  
> ruby 2.1.0dev (2013-08-06 trunk 42402) [x86\_64-linux]  
> :hi  
> # $B$7$P$i$/J|CV$7$F$3$3$G(B Enter  
> “”  
> $  
> =end

---

<div class="post-metadata">

**Author:** ![no6v\_SNobuhiro\_IMAI](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/n/fbc32d/32.png) [@no6v\_SNobuhiro\_IMAI](https://www.ruby-forum.com/u/no6v_SNobuhiro_IMAI)\
**Post date:** [August 8, 2013, 1:05am UTC](https://www.ruby-forum.com/t/ruby-trunk-bug-8749-open-readline-readline-stops-stdout/246004/2 "2013-08-08T01:05:56Z")

</div>

2013/8/7 no6v (Nobuhiro IMAI) [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid):

> Bug #8749: Readline.readline stops STDOUT?  
> [Bug #8749: Readline.readline stops STDOUT? - Ruby - Ruby Issue Tracking System](https://bugs.ruby-lang.org/issues/8749)

> r42402 $B$G!“0J2\<$N$h$&$J%9%/%j%W%H$N5sF0$,JQ$o$C$F$$$^$9!#(B  
> (Enter $B$r2!$9$+$I$&$+$O4X78$J$/$F!”(B)Readline.readline  
> $B$r\<B9TCf$KI8=`=PNO$X$N=PNO$,=PMh$J$/$J$C$F$$$k$h$&$K8+$($^$9!#(B

$B$&$%$`!#(BReadline.readline $B$,(B GVL  
$B$r3NJ]$7$?$^$^%V%m%C%/$7$F$7$^$C$F!"(B  
$B%a%$%s%9%l%C%I$,?J$^$J$/$J$C$F$$$k$h$&$G$9!#(B

$B$H$j$"$($:$b$H$N%3!\<%I$r$J$k$Y$/J]B8$9$k$J$i$3$&$+$J$!!#(B

# % 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)  
@@ -127,6 +127,7 @@ static char \*\*readline\_attempted\_complet  
\*/

static VALUE readline\_instream;  
+static int readline\_infd = -1;  
static VALUE readline\_outstream;

#if defined HAVE\_RL\_GETC\_FUNCTION  
@@ -143,7 +144,7 @@ readline\_getc(FILE \*input)  
VALUE c;  
if (!readline\_instream) return rl\_getc(input);  
GetOpenFile(readline\_instream, ifp);

- if (rl\_instream != ifp-\>stdio\_file) return rl\_getc(input);

- if (fileno(rl\_instream) != readline\_infd) return rl\_getc(input);  
#if defined(\_WIN32)  
{  
INPUT\_RECORD ir;  
@@ -398,6 +399,7 @@ readline\_readline(int argc, VALUE \*argv,  
rl\_instream = NULL;  
}  
readline\_instream = Qfalse;
- 

```
       readline_infd = -1;
       rb_raise(rb_eIOError, "closed stdin");
   }

```

}  
@@ -467,6 +469,7 @@ clear\_rl\_instream(void)  
}  
}  
readline\_instream = Qfalse;
- 

```
   readline_infd = -1;
   rl_instream = NULL;

```

}  
}  
@@ -504,6 +507,7 @@ readline\_s\_set\_input(VALUE self, VALUE i  
}  
rl\_instream = f;  
readline\_instream = input;
- 

```
   readline_infd = fd;

```

}  
return input;  
}

$B$G$b!“(Breadline\_getc $B$G$OC1$K(B GVL $B$r30$7$F(B rl\_getc  
$B$r8F$Y$P$$$$$N$G$O$J$$$+!”$H$$$&5$$b$7$^$9!#(B

---

<div class="post-metadata">

**Author:** ![no6v\_SNobuhiro\_IMAI](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/n/fbc32d/32.png) [@no6v\_SNobuhiro\_IMAI](https://www.ruby-forum.com/u/no6v_SNobuhiro_IMAI)\
**Post date:** [August 8, 2013, 3:20am UTC](https://www.ruby-forum.com/t/ruby-trunk-bug-8749-open-readline-readline-stops-stdout/246004/3 "2013-08-08T03:20:35Z")

</div>

2013$BG/(B8$B7n(B8$BF|(B 8:05 Tanaka A. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid):

> $B$G$b!“(Breadline\_getc $B$G$OC1$K(B GVL $B$r30$7$F(B rl\_getc  
> $B$r8F$Y$P$$$$$N$G$O$J$$$+!”$H$$$&5$$b$7$^$9!#(B

$B$3$&$9$k$J$i!"$3$&$G$9$+$M$'!#(B

# % 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

arton $B$5$s$,=q$$$?(B Windows  
$BMQ$N%3!\<%I$,I,MW$+$I$&$+$O$h$/$o$+$i$J$$$N$G$9$,!“(B  
$B$$$A$\*$&;D$7$F$”$j$^$9!#%F%9%H$O$7$F$$$^$;$s!#(B

---

<div class="post-metadata">

**Author:** ![no6v\_SNobuhiro\_IMAI](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/n/fbc32d/32.png) [@no6v\_SNobuhiro\_IMAI](https://www.ruby-forum.com/u/no6v_SNobuhiro_IMAI)\
**Post date:** [August 12, 2013, 2:22pm UTC](https://www.ruby-forum.com/t/ruby-trunk-bug-8749-open-readline-readline-stops-stdout/246004/4 "2013-08-12T14:22:14Z")

</div>

Issue #8749 has been updated by akr (Akira T.).

File readline-release-gvl.patch added

何通か書いたメールが redmine に登録されていないので redmine で書きます。  
(メールは (化けてますが) [[ruby-trunk - Bug #8749][Open] Readline.readline stops STDOUT? - Development - Ruby-Forum](https://www.ruby-forum.com/topic/4416224) で見れます。)

読み込みでブロックしている時に GVL を解放していなくて他のスレッドが動けないようです。

readline\_getc は Ruby 1.8 時代の名残りか、  
Ruby の IO 読み込み関数 (rb\_io\_getbyte) を使うことによって  
読み込みでブロックしている最中も他のスレッドを動かせるようにしていますが、  
それには IO オブジェクトが必要なため、IO オブジェクトがないときは無理だとか  
中途半端です。

その判断のところが r42402 で変化してしまって、他のスレッドが動けなくなっていた  
のですが、Ruby 1.9 以降では、GVL を外して読み込めばブロック中に  
他のスレッドは動けるのでそうするのがいいんじゃないでしょうか。

readline-release-gvl.patch みたいなのはどうですかね。

なお、シグナルがきたときに  
rb\_thread\_call\_with\_gvl 経由で rb\_thread\_check\_ints を呼んでいますが、  
rb\_thread\_interrupted を使うと設定した trap が即座には起動しなかったためです。  
これは私の想定する rb\_thread\_interrupted の動作と違うんですが、私の理解と  
rb\_thread\_interrupted のどちらが間違っているのかは分かりません。

* * *

Bug #8749: Readline.readline stops STDOUT?

> **[Updated by akr (Akira Tanaka) about 13 years ago ActionsCopy link 1... - Bug...](https://bugs.ruby-lang.org/issues/8749#change-41109)**
>
> 何通か書いたメールが redmine に登録されていないので redmine で書きます。 (メールは (化けてますが) https://www.ruby-forum.com/topic/4416224 で見れます。) | Redmine

Author: no6v (Nobuhiro IMAI)  
Status: Open  
Priority: Normal  
Assignee:  
Category: ext  
Target version:  
ruby -v: ruby 2.1.0dev (2013-08-06 trunk 42402) [x86\_64-linux]  
Backport: 1.9.3: UNKNOWN, 2.0.0: UNKNOWN

=begin  
r42402 で、以下のようなスクリプトの挙動が変わっています。  
(Enter を押すかどうかは関係なくて、)Readline.readline を実行中に標準出力への出力が出来なくなっているように見えます。

$ cat rl.rb  
require “readline”

th = Thread.new do  
p Readline.readline("\> ")  
end

loop do  
p :hi  
sleep 2  
break unless th.alive?  
end  
$ ruby -v rl.rb  
ruby 2.1.0dev (2013-08-06 trunk 42401) [x86\_64-linux]  
:hi

> :hi  
> :hi  
> :hi  
> :hi  
> # しばらく放置してここで Enter  
> “”  
> $ ruby -v rl.rb  
> $ /tmp/ruby/bin/ruby -v /tmp/r.rb  
> ruby 2.1.0dev (2013-08-06 trunk 42402) [x86\_64-linux]  
> :hi  
> # しばらく放置してここで Enter  
> “”  
> $  
> =end

---

<div class="post-metadata">

**Author:** ![no6v\_SNobuhiro\_IMAI](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/n/fbc32d/32.png) [@no6v\_SNobuhiro\_IMAI](https://www.ruby-forum.com/u/no6v_SNobuhiro_IMAI)\
**Post date:** [August 13, 2013, 2:48am UTC](https://www.ruby-forum.com/t/ruby-trunk-bug-8749-open-readline-readline-stops-stdout/246004/5 "2013-08-13T02:48:42Z")

</div>

Issue #8749 has been updated by kouji (Kouji T.).

Assignee set to kouji (Kouji T.)

* * *

Bug #8749: Readline.readline stops STDOUT?

> **[Updated by kouji (Kouji Takao) about 13 years ago ActionsCopy link 2... - Bug...](https://bugs.ruby-lang.org/issues/8749#change-41122)**
>
> 何通か書いたメールが redmine に登録されていないので redmine で書きます。 (メールは (化けてますが) https://www.ruby-forum.com/topic/4416224 で見れます。) | Redmine

Author: no6v (Nobuhiro IMAI)  
Status: Open  
Priority: Normal  
Assignee: kouji (Kouji T.)  
Category: ext  
Target version:  
ruby -v: ruby 2.1.0dev (2013-08-06 trunk 42402) [x86\_64-linux]  
Backport: 1.9.3: UNKNOWN, 2.0.0: UNKNOWN

=begin  
r42402 で、以下のようなスクリプトの挙動が変わっています。  
(Enter を押すかどうかは関係なくて、)Readline.readline を実行中に標準出力への出力が出来なくなっているように見えます。

$ cat rl.rb  
require “readline”

th = Thread.new do  
p Readline.readline("\> ")  
end

loop do  
p :hi  
sleep 2  
break unless th.alive?  
end  
$ ruby -v rl.rb  
ruby 2.1.0dev (2013-08-06 trunk 42401) [x86\_64-linux]  
:hi

> :hi  
> :hi  
> :hi  
> :hi  
> # しばらく放置してここで Enter  
> “”  
> $ ruby -v rl.rb  
> $ /tmp/ruby/bin/ruby -v /tmp/r.rb  
> ruby 2.1.0dev (2013-08-06 trunk 42402) [x86\_64-linux]  
> :hi  
> # しばらく放置してここで Enter  
> “”  
> $  
> =end

---

<div class="post-metadata">

**Author:** ![no6v\_SNobuhiro\_IMAI](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/n/fbc32d/32.png) [@no6v\_SNobuhiro\_IMAI](https://www.ruby-forum.com/u/no6v_SNobuhiro_IMAI)\
**Post date:** [August 15, 2013, 5:12am UTC](https://www.ruby-forum.com/t/ruby-trunk-bug-8749-open-readline-readline-stops-stdout/246004/6 "2013-08-15T05:12:09Z")

</div>

Issue #8749 has been updated by no6v (Nobuhiro IMAI).

> 読み込みでブロックしている時に GVL を解放していなくて他のスレッドが動けないようです。

ありがとうございます。出力じゃなくメインスレッド自体が止まっていたんですね。

> その判断のところが r42402 で変化してしまって、他のスレッドが動けなくなっていた  
> のですが、Ruby 1.9 以降では、GVL を外して読み込めばブロック中に  
> 他のスレッドは動けるのでそうするのがいいんじゃないでしょうか。
> 
> readline-release-gvl.patch みたいなのはどうですかね。

今回問題にした挙動は r42525 で一旦直って r42527 でまた壊れはしたものの  
r42528 でまた直っているようです。これはたまたまでしょうか。

もちろん attachment:readline-release-gvl.patch を当てても動きます。  
(コンパイル時に以下の警告が出ました)

compiling ../../../../git/ruby/ext/readline/readline.c  
../../../../git/ruby/ext/readline/readline.c: In function ‘check\_ints’:  
../../../../git/ruby/ext/readline/readline.c:148:1: warning: no return  
statement in function returning non-void [-Wreturn-type]  
}  
^

* * *

Bug #8749: Readline.readline stops STDOUT?

> **[Updated by no6v (Nobuhiro IMAI) about 13 years ago ActionsCopy link 3... - Bug...](https://bugs.ruby-lang.org/issues/8749#change-41167)**
>
> 何通か書いたメールが redmine に登録されていないので redmine で書きます。 (メールは (化けてますが) https://www.ruby-forum.com/topic/4416224 で見れます。) | Redmine

Author: no6v (Nobuhiro IMAI)  
Status: Open  
Priority: Normal  
Assignee: kouji (Kouji T.)  
Category: ext  
Target version:  
ruby -v: ruby 2.1.0dev (2013-08-06 trunk 42402) [x86\_64-linux]  
Backport: 1.9.3: UNKNOWN, 2.0.0: UNKNOWN

=begin  
r42402 で、以下のようなスクリプトの挙動が変わっています。  
(Enter を押すかどうかは関係なくて、)Readline.readline を実行中に標準出力への出力が出来なくなっているように見えます。

$ cat rl.rb  
require “readline”

th = Thread.new do  
p Readline.readline("\> ")  
end

loop do  
p :hi  
sleep 2  
break unless th.alive?  
end  
$ ruby -v rl.rb  
ruby 2.1.0dev (2013-08-06 trunk 42401) [x86\_64-linux]  
:hi

> :hi  
> :hi  
> :hi  
> :hi  
> # しばらく放置してここで Enter  
> “”  
> $ ruby -v rl.rb  
> $ /tmp/ruby/bin/ruby -v /tmp/r.rb  
> ruby 2.1.0dev (2013-08-06 trunk 42402) [x86\_64-linux]  
> :hi  
> # しばらく放置してここで Enter  
> “”  
> $  
> =end

---

<div class="post-metadata">

**Author:** ![no6v\_SNobuhiro\_IMAI](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/n/fbc32d/32.png) [@no6v\_SNobuhiro\_IMAI](https://www.ruby-forum.com/u/no6v_SNobuhiro_IMAI)\
**Post date:** [August 8, 2013, 3:37pm UTC](https://www.ruby-forum.com/t/ruby-trunk-bug-8749-open-readline-readline-stops-stdout/246004/7 "2013-08-08T15:37:49Z")

</div>

2013/8/8 Tanaka A. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid):

> 2013$BG/(B8$B7n(B8$BF|(B 8:05 Tanaka A. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid):
> 
> > $B$G$b!“(Breadline\_getc $B$G$OC1$K(B GVL $B$r30$7$F(B rl\_getc  
> > $B$r8F$Y$P$$$$$N$G$O$J$$$+!”$H$$$&5$$b$7$^$9!#(B
> 
> $B$3$&$9$k$J$i!"$3$&$G$9$+$M$'!#(B

$B$\*$C$H!"$3$l$@$H(B ^C $B$,8z$-$^$;$s$G$7$?!#(B  
$B$3$&$+$J!#(B

# % svn diff --diff-cmd diff -x ‘-u -p’ Index: ext/readline/readline.c

— ext/readline/readline.c (revision 42432)  
+++ 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,15 +136,19 @@ 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);

- int fd = fileno(input);
- char ch;
- ssize\_t ss;
- int ret;
- 

#if defined(\_WIN32)  
{  
INPUT\_RECORD ir;  
@@ -151,19 +156,19 @@ readline\_getc(FILE \*input)  
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 +177,56 @@ 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;

```

- }

- 
- again:
- ss = read(fd, &ch, 1);
- if (ss == 0)
- 

```
   return EOF;

```

- if (ss == -1) {
- 

```
   if (errno == EINTR)

```

- 

```
       return EOF;

```

- 

```
   if (errno == EWOULDBLOCK || errno == EAGAIN) {

```

+#ifdef HAVE\_POLL

- 

```
       struct pollfd pfd;

```

- 

```
       pfd.fd = fd;

```

- 

```
       pfd.events = POLLIN;

```

- 

```
       pfd.revents = 0;

```

- 

```
       ret = poll(&pfd, 1, -1);

```

- 

```
       if (ret < 0)

```

- 

```
           return EOF;

```

+#else

- 

```
       rb_fdset_t rfds;

```

- 

```
       rb_fd_init(&rfds);

```

- 

```
       rb_fd_set(fd, &rfds);

```

- 

```
       ret = rb_fd_select(fd+1, &rfds, NULL, NULL, NULL);

```

- 

```
       rb_fd_term(&rfds);

```

- 

```
       if (ret < 0)

```

- 

```
           return EOF;

```

#endif

- return FIX2INT(c);

- 

```
       goto again;

```

- 

```
   }

```

- }
- return (unsigned char)ch;  
+}
- 

+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

---

<div class="post-metadata">

**Author:** ![no6v\_SNobuhiro\_IMAI](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/n/fbc32d/32.png) [@no6v\_SNobuhiro\_IMAI](https://www.ruby-forum.com/u/no6v_SNobuhiro_IMAI)\
**Post date:** [October 27, 2013, 1:11pm UTC](https://www.ruby-forum.com/t/ruby-trunk-bug-8749-open-readline-readline-stops-stdout/246004/8 "2013-10-27T13:11:27Z")

</div>

Issue #8749 has been updated by akr (Akira T.).

この [ruby-dev:47033] [Bug #8749] と  
[ruby-core:57951] [Bug #9040] の件をあわせて修正する変更を入れました。

パッチを出してから 2ヵ月くらい経っていますが反応が無く、  
[ruby-core:57951] [Bug #9040] の件も見つかったし、  
Ruby 2.1.0 のリリース直前に変更するのもよくないとおもうので。

問題があったら言ってください。

* * *

Bug #8749: Readline.readline stops STDOUT?

> **[Updated by akr (Akira Tanaka) almost 13 years ago ActionsCopy link 6... - Bug...](https://bugs.ruby-lang.org/issues/8749#change-42635)**
>
> 何通か書いたメールが redmine に登録されていないので redmine で書きます。 (メールは (化けてますが) https://www.ruby-forum.com/topic/4416224 で見れます。) | Redmine

Author: no6v (Nobuhiro IMAI)  
Status: Closed  
Priority: Normal  
Assignee: kouji (Kouji T.)  
Category: ext  
Target version:  
ruby -v: ruby 2.1.0dev (2013-08-06 trunk 42402) [x86\_64-linux]  
Backport: 1.9.3: UNKNOWN, 2.0.0: UNKNOWN

=begin  
r42402 で、以下のようなスクリプトの挙動が変わっています。  
(Enter を押すかどうかは関係なくて、)Readline.readline を実行中に標準出力への出力が出来なくなっているように見えます。

$ cat rl.rb  
require “readline”

th = Thread.new do  
p Readline.readline("\> ")  
end

loop do  
p :hi  
sleep 2  
break unless th.alive?  
end  
$ ruby -v rl.rb  
ruby 2.1.0dev (2013-08-06 trunk 42401) [x86\_64-linux]  
:hi

> :hi  
> :hi  
> :hi  
> :hi  
> # しばらく放置してここで Enter  
> “”  
> $ ruby -v rl.rb  
> $ /tmp/ruby/bin/ruby -v /tmp/r.rb  
> ruby 2.1.0dev (2013-08-06 trunk 42402) [x86\_64-linux]  
> :hi  
> # しばらく放置してここで Enter  
> “”  
> $  
> =end

---

<div class="post-metadata">

**Author:** ![no6v\_SNobuhiro\_IMAI](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/n/fbc32d/32.png) [@no6v\_SNobuhiro\_IMAI](https://www.ruby-forum.com/u/no6v_SNobuhiro_IMAI)\
**Post date:** [August 15, 2013, 6:42am UTC](https://www.ruby-forum.com/t/ruby-trunk-bug-8749-open-readline-readline-stops-stdout/246004/9 "2013-08-15T06:42:40Z")

</div>

Issue #8749 has been updated by akr (Akira T.).

File readline-release-gvl-2.patch added

no6v (Nobuhiro IMAI) wrote:

> 今回問題にした挙動は r42525 で一旦直って r42527 でまた壊れはしたものの  
> r42528 でまた直っているようです。これはたまたまでしょうか。

readline\_getc で、rl\_getc を呼び出すか、rb\_io\_getbyte を呼び出すかという条件判断が問題で、  
前者なら GVL を離さないので他のスレッドは動けず、後者なら動けます。

r42525 で直ったのは、ifp-\>stdio\_file に代入したので、readline\_getc 内の  
if (rl\_instream != ifp-\>stdio\_file) return rl\_getc(input);  
という条件が成立しなくなったためでしょう。  
しかし、[ruby-dev:47608] で述べたように、ifp-\>stdio\_file に readline 側で  
作った FILE 構造体を代入すると、IO#close で解放されてしまって、ひいては SEGV になる可能性が出てきます。

r42527 は if 文で上記の ifp-\>stdio\_file への代入をガードしていますが、  
[ruby-dev:47609] で述べたように、その条件は決して成り立たないので、実質、  
r42525 の revert のようなものです。

r42528 は  
if (rl\_instream != ifp-\>stdio\_file) return rl\_getc(input);  
という文を削除していて、そのため、rl\_getc じゃなくて下のほうに制御が行って、  
rb\_io\_getbyte を呼び出すようになったのでしょう。  
ここで rb\_io\_getbyte は readline\_instream という IO オブジェクトから読むので、  
それが input という FILE 構造体と対応しているのかという疑問があるわけで、  
だからこそ対応していなかったら input から読むという処理が入っているのだと思いますが、  
どういう理由かは知りませんが、消してしまっているようです。

> もちろん attachment:readline-release-gvl.patch を当てても動きます。  
> (コンパイル時に以下の警告が出ました)
> 
> compiling ../../../../git/ruby/ext/readline/readline.c  
> ../../../../git/ruby/ext/readline/readline.c: In function ‘check\_ints’:  
> ../../../../git/ruby/ext/readline/readline.c:148:1: warning: no return statement  
> in function returning non-void [-Wreturn-type]  
> }  
> ^

おっと、return NULL; を忘れていました。  
つけたのを readline-release-gvl-2.patch として添付します。

* * *

Bug #8749: Readline.readline stops STDOUT?

> **[Updated by akr (Akira Tanaka) about 13 years ago ActionsCopy link 4 - Bug #8749:...](https://bugs.ruby-lang.org/issues/8749#change-41168)**
>
> 何通か書いたメールが redmine に登録されていないので redmine で書きます。 (メールは (化けてますが) https://www.ruby-forum.com/topic/4416224 で見れます。) | Redmine

Author: no6v (Nobuhiro IMAI)  
Status: Open  
Priority: Normal  
Assignee: kouji (Kouji T.)  
Category: ext  
Target version:  
ruby -v: ruby 2.1.0dev (2013-08-06 trunk 42402) [x86\_64-linux]  
Backport: 1.9.3: UNKNOWN, 2.0.0: UNKNOWN

=begin  
r42402 で、以下のようなスクリプトの挙動が変わっています。  
(Enter を押すかどうかは関係なくて、)Readline.readline を実行中に標準出力への出力が出来なくなっているように見えます。

$ cat rl.rb  
require “readline”

th = Thread.new do  
p Readline.readline("\> ")  
end

loop do  
p :hi  
sleep 2  
break unless th.alive?  
end  
$ ruby -v rl.rb  
ruby 2.1.0dev (2013-08-06 trunk 42401) [x86\_64-linux]  
:hi

> :hi  
> :hi  
> :hi  
> :hi  
> # しばらく放置してここで Enter  
> “”  
> $ ruby -v rl.rb  
> $ /tmp/ruby/bin/ruby -v /tmp/r.rb  
> ruby 2.1.0dev (2013-08-06 trunk 42402) [x86\_64-linux]  
> :hi  
> # しばらく放置してここで Enter  
> “”  
> $  
> =end
