# \[Bug:trunk\] Thread#kill cannot break BLOCKING\_REGION() on windows

**URL:** <https://www.ruby-forum.com/t/bug-trunk-thread-kill-cannot-break-blocking-region-on-windows/142812>\
**Category:** Development\
**Created:** [July 11, 2008, 7:01pm UTC](https://www.ruby-forum.com/t/bug-trunk-thread-kill-cannot-break-blocking-region-on-windows/142812 "2008-07-11T19:01:36Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![U.Nakamura](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/u/b5ac83/32.png) [@U.Nakamura](https://www.ruby-forum.com/u/U.Nakamura)\
**Post date:** [July 11, 2008, 7:01pm UTC](https://www.ruby-forum.com/t/bug-trunk-thread-kill-cannot-break-blocking-region-on-windows/142812/1 "2008-07-11T19:01:36Z")

</div>

e$B$3$s$K$A$O!"$J$+$`$ie(B(e$B$&e(B)e$B$G$9!#e(B

Windows(e$B=|e(Bcygwin)e$B$G$O!“30It$+$ie(BBLOCKING\_REGION()e$B$rCfCG$5$;$ke(B  
e$B$3$H$,$G$-$J$$$N$G!”$"$k%9%l%C%I$,e(BBLOCKING\_REGION()e$B$KF~$C$F$$e(B  
e$B$k\>l9g!"$=$N%9%l%C%I$re(BThread#kille$B$G=\*N;$5$l$k$3$H$,$G$-$^$;$s!#e(B

e$BNce(B:  
require “socket”  
s = TCPServer.new(0)  
t = Thread.new{s.accept}  
sleep 1  
t.kill  
t.join # \<= accepte$B$,e(BBLOCKING\_REGION()e$BFb$G=hM}$5$l$k$?$a!"e(B  
# e$B$3$3$G1J5W$KBT$A\>uBV$H$J$ke(B

# e$B8=;~E@$GBP:v$,;W$$$D$$$F$$$J$$$N$G$9$,!"K:$l$J$$$h$&$K5-O?e(B

# e$B$K;D$7$^$9!#e(B

e$B$=$l$G$O!#e(B

---

<div class="post-metadata">

**Author:** ![U.Nakamura](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/u/b5ac83/32.png) [@U.Nakamura](https://www.ruby-forum.com/u/U.Nakamura)\
**Post date:** [July 11, 2008, 9:37pm UTC](https://www.ruby-forum.com/t/bug-trunk-thread-kill-cannot-break-blocking-region-on-windows/142812/2 "2008-07-11T21:37:21Z")

</div>

e$B$3$s$K$A$O!"$J$+$`$ie(B(e$B$&e(B)e$B$G$9!#e(B

In message “[ruby-dev:35446] [Bug:trunk] Thread#kill cannot break  
BLOCKING\_REGION() on windows”  
on Jul.12,2008 01:56:54, [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:  
| Windows(e$B=|e(Bcygwin)e$B$G$O!“30It$+$ie(BBLOCKING\_REGION()e$B$rCfCG$5$;$ke(B  
| e$B$3$H$,$G$-$J$$$N$G!”$“$k%9%l%C%I$,e(BBLOCKING\_REGION()e$B$KF~$C$F$$e(B  
| e$B$k\>l9g!”$=$N%9%l%C%I$re(BThread#kille$B$G=\*N;$5$l$k$3$H$,$G$-$^$;$s!#e(B

e$B$3$NLdBj$O2r7h$7$F$J$$$s$G$9$,!"e(B

| e$BNce(B:  
| require “socket”  
| s = TCPServer.new(0)  
| t = Thread.new{s.accept}  
| sleep 1  
| t.kill  
| t.join # \<= accepte$B$,e(BBLOCKING\_REGION()e$BFb$G=hM}$5$l$k$?$a!"e(B  
| # e$B$3$3$G1J5W$KBT$A\>uBV$H$J$ke(B

e$B$3$NNc$K8BDj$9$k$H!"0J2\<$N%Q%C%A$G2r7h$7$^$9!#e(B

# e$BNc$,e(Baccepte$B$J$N$Ge(Baccepte$B$@$1BP=h$7$F$$$^$9!#e(B

e$B;W$&$K!“e(Bsocket.soe$B$+$ie(Brb\_thread\_blocking\_region()e$B$r8F$S=P$9$he(B  
e$B$j!”$3$N%Q%C%A$N$h$&$K!“e(Bio.ce$B$G$d$C$F$k$N$HF1MM!”%V%m%C%/$7$&e(B  
e$B$k4X?t$N8F$S=P$7$NA0$KFI$\_=q$-2DG=$N%A%'%C%/$r9T$&$Y$-$G$O$Je(B  
e$B$$$G$7$g$&$+!#e(B

# Index: ext/socket/socket.c

— ext/socket/socket.c (revision 18034)  
+++ ext/socket/socket.c (working copy)  
@@ -1525,32 +1525,16 @@ s\_accept\_nonblock(VALUE klass, rb\_io\_t \*  
return init\_sock(rb\_obj\_alloc(klass), fd2);  
}

-struct accept\_arg {

- int fd;
- struct sockaddr \*sockaddr;
- socklen\_t \*len;  
-};
- 

-static VALUE  
-accept\_blocking(void \*data)  
-{

- struct accept\_arg \*arg = data;
- return (VALUE)accept(arg-\>fd, arg-\>sockaddr, arg-\>len);  
-}
- 

static VALUE  
s\_accept(VALUE klass, int fd, struct sockaddr \*sockaddr, socklen\_t  
\*len)  
{  
int fd2;  
int retry = 0;

- struct accept\_arg arg;

- arg.fd = fd;

- arg.sockaddr = sockaddr;

- arg.len = len;  
retry:

- fd2 = (int)BLOCKING\_REGION(accept\_blocking, &arg);

- rb\_thread\_wait\_fd(fd);
- fd2 = accept(fd, sockaddr, len);  
if (fd2 \< 0) {  
switch (errno) {  
case EMFILE:

# e$B0J2\<$O!"0J\>e$NOC$HD\>@\4X78$O$J$$$J$+$@$5$s08$N;d?.e(B:

# 

# 

e$B$@$$$VA0$K$A$i$C$HOC$7$?$3$H$,$"$k$h$&$K!"e(Bdefe$B%U%!%$%k$G8@$&e(B

# select@20=\_rb\_w32\_select@20

# e$B$\_$?$$$JE[$,3HD%%i%$%V%i%j$+$i@5$7$/;2\>H$5$l$:!"D\>@\e(Bws2\_32.dll

# e$B8~$-$K$J$C$F$7$^$&$3$H$,$"$k$h$&$G$9!#e(B

# 

msvcrt-ruby190.dlle$B$,99?7$5$l$:$Ke(Bsocket.soe$B$@$199?7$5$l$k$h$&e(B

# e$B$J%Q%?!\<%s$G:F8=$7$?$N$G$9$,!"M}M3$O$5$C$Q$j$o$+$j$^$;$se(B…

# e$B$J$s$+?4Ev$?$j$O$"$j$^$9$+e(B?

e$B$=$l$G$O!#e(B

---

<div class="post-metadata">

**Author:** ![U.Nakamura](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/u/b5ac83/32.png) [@U.Nakamura](https://www.ruby-forum.com/u/U.Nakamura)\
**Post date:** [July 15, 2008, 10:56am UTC](https://www.ruby-forum.com/t/bug-trunk-thread-kill-cannot-break-blocking-region-on-windows/142812/3 "2008-07-15T10:56:39Z")

</div>

e$B$3$s$K$A$O!"$J$+$`$ie(B(e$B$&e(B)e$B$G$9!#e(B

In message “[ruby-dev:35448] Re: [Bug:trunk] Thread#kill cannot break  
BLOCKING\_REGION() on windows”  
on Jul.12,2008 04:32:40, [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> e$B;W$&$K!“e(Bsocket.soe$B$+$ie(Brb\_thread\_blocking\_region()e$B$r8F$S=P$9$he(B  
> e$B$j!”$3$N%Q%C%A$N$h$&$K!“e(Bio.ce$B$G$d$C$F$k$N$HF1MM!”%V%m%C%/$7$&e(B  
> e$B$k4X?t$N8F$S=P$7$NA0$KFI$\_=q$-2DG=$N%A%'%C%/$r9T$&$Y$-$G$O$Je(B  
> e$B$$$G$7$g$&$+!#e(B

e$B$$$m$$$m9M$($k$K!“e(Bsende$B$de(Brecve$B$O$$$:$l$K$;$h%V%m%C%/$9$k2DG=@-e(B  
e$B$,$”$k$N$Ge(Brb\_thread\_blocking\_region()e$B$G$/$/$C$F$\*$/I,MW$O$“$ke(B  
e$B$N$G$O$J$$$+$H9M$(D\>$7$^$7$?!#e(B  
e$B$=$l$O$=$l$H$7$F;vA0$KFI$\_=q$-2DG=$N%A%'%C%/$r9T$&$N$K$O0UL#e(B  
e$B$O$”$k$H;W$&$N$G!"$=$&$$$C$?E@$rA4BN$KE,MQ$7$?%Q%C%A$r:n@.$7e(B  
e$B$^$7$?!#e(B

commite$B$7$A$c$$$?$$$N$G$9$,$I$&$G$7$g$&$+e(B?

# Index: ext/socket/socket.c

— ext/socket/socket.c (revision 18067)  
+++ ext/socket/socket.c (working copy)  
@@ -551,7 +551,8 @@ bsock\_send(int argc, VALUE \*argv, VALUE  
GetOpenFile(sock, fptr);  
arg.fd = fptr-\>fd;  
arg.flags = NUM2INT(flags);

- while ((n = (int)BLOCKING\_REGION(func, &arg)) \< 0) {

- while (rb\_thread\_fd\_writable(arg.fd),

- 

```
(n = (int)BLOCKING_REGION(func, &arg)) < 0) {

```

if (rb\_io\_wait\_writable(arg.fd)) {  
continue;  
}  
@@ -640,6 +641,7 @@ s\_recvfrom(VALUE sock, int argc, VALUE \*  
RBASIC(str)-\>klass = 0;

while (rb\_io\_check\_closed(fptr),

- 

```
rb_thread_wait_fd(arg.fd),
(slen = BLOCKING_REGION(recvfrom_blocking, &arg)) < 0) {

```

if (RBASIC(str)-\>klass || RSTRING\_LEN(str) != buflen) {  
rb\_raise(rb\_eRuntimeError, “buffer string modified”);  
@@ -1140,19 +1142,17 @@ struct connect\_arg {  
socklen\_t len;  
};

-static VALUE  
-connect\_blocking(void \*data)  
+static int  
+connect0(struct connect\_arg \*arg)  
{

- struct connect\_arg \*arg = data;
- return (VALUE)connect(arg-\>fd, arg-\>sockaddr, arg-\>len);

- return connect(arg-\>fd, arg-\>sockaddr, arg-\>len);  
}

#if defined(SOCKS) && !defined(SOCKS5)  
-static VALUE  
-socks\_connect\_blocking(void \*data)  
+static int  
+socks\_connect0(struct connect\_arg \*arg)  
{

- struct connect\_arg \*arg = data;
- return (VALUE)Rconnect(arg-\>fd, arg-\>sockaddr, arg-\>len);

- return Rconnect(arg-\>fd, arg-\>sockaddr, arg-\>len);  
}  
#endif

@@ -1160,7 +1160,7 @@ static int  
ruby\_connect(int fd, const struct sockaddr \*sockaddr, int len, int  
socks)  
{  
int status;

- rb\_blocking\_function\_t \*func = connect\_blocking;

- int (\*func)(struct connect\_arg \*) = connect0;  
struct connect\_arg arg;  
#if WAIT\_IN\_PROGRESS \> 0  
int wait\_in\_progress = -1;  
@@ -1172,10 +1172,11 @@ ruby\_connect(int fd, const struct sockad  
arg.sockaddr = sockaddr;  
arg.len = len;  
#if defined(SOCKS) && !defined(SOCKS5)

- if (socks) func = socks\_connect\_blocking;

- if (socks) func = socks\_connect0;  
#endif  
for (;😉 {

- status = (int)BLOCKING\_REGION(func, &arg);

- rb\_thread\_fd\_writable(fd);
- status = func(&arg);  
if (status \< 0) {  
switch (errno) {  
case EAGAIN:  
@@ -1525,32 +1526,16 @@ s\_accept\_nonblock(VALUE klass, rb\_io\_t \*  
return init\_sock(rb\_obj\_alloc(klass), fd2);  
}

-struct accept\_arg {

- int fd;
- struct sockaddr \*sockaddr;
- socklen\_t \*len;  
-};
- 

-static VALUE  
-accept\_blocking(void \*data)  
-{

- struct accept\_arg \*arg = data;
- return (VALUE)accept(arg-\>fd, arg-\>sockaddr, arg-\>len);  
-}
- 

static VALUE  
s\_accept(VALUE klass, int fd, struct sockaddr \*sockaddr, socklen\_t  
\*len)  
{  
int fd2;  
int retry = 0;

- struct accept\_arg arg;

- arg.fd = fd;

- arg.sockaddr = sockaddr;

- arg.len = len;  
retry:

- fd2 = (int)BLOCKING\_REGION(accept\_blocking, &arg);

- rb\_thread\_wait\_fd(fd);

- fd2 = accept(fd, sockaddr, len);  
if (fd2 \< 0) {  
switch (errno) {  
case EMFILE:  
@@ -1852,6 +1837,7 @@ udp\_send(int argc, VALUE \*argv, VALUE so  
retry:  
arg.to = res-\>ai\_addr;  
arg.tolen = res-\>ai\_addrlen;

- rb\_thread\_fd\_writable(arg.fd);  
n = (int)BLOCKING\_REGION(sendto\_blocking, &arg);  
if (n \>= 0) {  
freeaddrinfo(res0);  
@@ -2036,6 +2022,7 @@ unix\_send\_io(VALUE sock, VALUE val)  
#endif

- rb\_thread\_fd\_writable(arg.fd);  
if ((int)BLOCKING\_REGION(sendmsg\_blocking, &arg) == -1)  
rb\_sys\_fail(“sendmsg(2)”);

@@ -2102,6 +2089,7 @@ unix\_recv\_io(int argc, VALUE \*argv, VALU  
#endif

```
 arg.fd = fptr->fd;

```

- rb\_thread\_wait\_fd(arg.fd);  
if ((int)BLOCKING\_REGION(recvmsg\_blocking, &arg) == -1)  
rb\_sys\_fail(“recvmsg(2)”);

e$B$=$l$G$O!#e(B

---

<div class="post-metadata">

**Author:** ![U.Nakamura](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/u/b5ac83/32.png) [@U.Nakamura](https://www.ruby-forum.com/u/U.Nakamura)\
**Post date:** [July 15, 2008, 11:12am UTC](https://www.ruby-forum.com/t/bug-trunk-thread-kill-cannot-break-blocking-region-on-windows/142812/4 "2008-07-15T11:12:30Z")

</div>

e$B$^$D$b$He(B e$B$f$-$R$m$G$9e(B

In message “Re: [ruby-dev:35511] Re: [Bug:trunk] Thread#kill cannot  
break BLOCKING\_REGION() on windows”  
on Tue, 15 Jul 2008 17:51:36 +0900, “U.Nakamura”  
[removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) writes:

|e$B$$$m$$$m9M$($k$K!“e(Bsende$B$de(Brecve$B$O$$$:$l$K$;$h%V%m%C%/$9$k2DG=@-e(B  
|e$B$,$”$k$N$Ge(Brb\_thread\_blocking\_region()e$B$G$/$/$C$F$\*$/I,MW$O$“$ke(B  
|e$B$N$G$O$J$$$+$H9M$(D\>$7$^$7$?!#e(B  
|e$B$=$l$O$=$l$H$7$F;vA0$KFI$\_=q$-2DG=$N%A%'%C%/$r9T$&$N$K$O0UL#e(B  
|e$B$O$”$k$H;W$&$N$G!"$=$&$$$C$?E@$rA4BN$KE,MQ$7$?%Q%C%A$r:n@.$7e(B  
|e$B$^$7$?!#e(B  
|  
|commite$B$7$A$c$$$?$$$N$G$9$,$I$&$G$7$g$&$+e(B?

e$B$I$&$\>!#%@%a$@$C$?$i%j%P!\<%H$9$k$H$$$&$3$H$G!#e(B
