[Bug:trunk] Thread#kill cannot break BLOCKING_REGION() on windows

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

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, [email protected] 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;

    rb_secure(3);

  • 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

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, [email protected] 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 (;:wink: {
  • 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;

    rb_secure(3);

  • 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

    arg.fd = fptr->fd;

  • 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

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”
[email protected] 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