From: nobu.nakada@... Date: 2002-09-12T14:37:14+09:00 Subject: [ruby-dev:18272] Re: thread failure after trap なかだです。 At Wed, 11 Sep 2002 23:22:14 +0900, Yukihiro Matsumoto wrote: > |[ruby-talk:40337]と[ruby-core:00019]の、trapでthreadがブロック > |してしまうという件ですが、どうすべきでしょうか。 > | > |とりあえず、[ruby-core:00023]+[ruby-core:00026]をCVS HEAD用にし > |たパッチです。 > | > | * eval.c (rb_trap_eval): preserve thread status and so on. > > どうしようかなあ、と思っていたところです。まあ、悪い影響があ > るものでもないと思いますのでコミットしてくださいませんか? socketを忘れてました。たぶん、こんなところではないかと。 Index: io.c =================================================================== RCS file: /cvs/ruby/src/ruby/io.c,v retrieving revision 1.157 diff -u -2 -p -w -r1.157 io.c --- io.c 11 Sep 2002 01:09:04 -0000 1.157 +++ io.c 12 Sep 2002 04:41:47 -0000 @@ -262,22 +262,58 @@ io_fflush(f, fptr) } -void +int rb_io_wait_readable(f) int f; { fd_set rfds; + + switch (errno) { + case EINTR: +#if defined(ERESTART) + case ERESTART: +#endif + rb_thread_wait_fd(f); + return Qtrue; + + case EAGAIN: +#if defined(EWOULDBLOCK) && EWOULDBLOCK != EAGAIN + case EWOULDBLOCK: +#endif FD_ZERO(&rfds); FD_SET(f, &rfds); rb_thread_select(f + 1, &rfds, NULL, NULL, NULL); + return Qtrue; + + default: + return Qfalse; + } } -void +int rb_io_wait_writable(f) int f; { fd_set wfds; + + switch (errno) { + case EINTR: +#if defined(ERESTART) + case ERESTART: +#endif + rb_thread_fd_writable(f); + return Qtrue; + + case EAGAIN: +#if defined(EWOULDBLOCK) && EWOULDBLOCK != EAGAIN + case EWOULDBLOCK: +#endif FD_ZERO(&wfds); FD_SET(f, &wfds); rb_thread_select(f + 1, NULL, &wfds, NULL, NULL); + return Qtrue; + + default: + return Qfalse; + } } @@ -320,17 +356,6 @@ io_write(io, str) n -= r; if (ferror(f)) { - switch (errno) { - case EINTR: -#if defined(ERESTART) - case ERESTART: -#endif - clearerr(f); - continue; - case EAGAIN: -#if defined(EWOULDBLOCK) && EWOULDBLOCK != EAGAIN - case EWOULDBLOCK: -#endif + if (rb_io_wait_writable(fileno(f))) { clearerr(f); - rb_io_wait_writable(fileno(f)); continue; } @@ -583,29 +608,4 @@ rb_io_to_io(io) /* reading functions */ -static void -io_read_retryable(f, path) - FILE *f; - const char *path; -{ - switch (errno) { - case EINTR: -#if defined(ERESTART) - case ERESTART: -#endif - clearerr(f); - break; - case EAGAIN: -#if defined(EWOULDBLOCK) && EWOULDBLOCK != EAGAIN - case EWOULDBLOCK: -#endif - clearerr(f); - rb_io_wait_readable(fileno(f)); - break; - default: - rb_sys_fail(path); - break; - } -} - long rb_io_fread(ptr, len, f) @@ -831,5 +831,7 @@ appendline(fptr, delim, strp) if (c == EOF) { if (ferror(f)) { - io_read_retryable(f, fptr->path); + if (!rb_io_wait_readable(fileno(f))) + rb_sys_fail(fptr->path); + clearerr(f); continue; } @@ -1144,5 +1146,7 @@ rb_io_each_byte(io) if (c == EOF) { if (ferror(f)) { - io_read_retryable(f, fptr->path); + if (!rb_io_wait_readable(fileno(f))) + rb_sys_fail(fptr->path); + clearerr(f); continue; } @@ -1175,5 +1179,7 @@ rb_io_getc(io) if (c == EOF) { if (ferror(f)) { - io_read_retryable(f, fptr->path); + if (!rb_io_wait_readable(fileno(f))) + rb_sys_fail(fptr->path); + clearerr(f); goto retry; } Index: rubyio.h =================================================================== RCS file: /cvs/ruby/src/ruby/rubyio.h,v retrieving revision 1.18 diff -u -2 -p -w -r1.18 rubyio.h --- rubyio.h 16 Aug 2002 02:52:25 -0000 1.18 +++ rubyio.h 12 Sep 2002 04:40:21 -0000 @@ -65,4 +65,6 @@ void rb_io_fptr_finalize _((OpenFile*)); void rb_io_synchronized _((OpenFile*)); void rb_io_check_closed _((OpenFile*)); +int rb_io_wait_readable _((int)); +int rb_io_wait_writable _((int)); VALUE rb_io_taint_check _((VALUE)); Index: ext/socket/socket.c =================================================================== RCS file: /cvs/ruby/src/ruby/ext/socket/socket.c,v retrieving revision 1.84 diff -u -2 -p -w -r1.84 socket.c --- ext/socket/socket.c 30 Aug 2002 14:34:57 -0000 1.84 +++ ext/socket/socket.c 12 Sep 2002 04:36:29 -0000 @@ -389,7 +389,7 @@ bsock_send(argc, argv, sock) f = GetWriteFile(fptr); fd = fileno(f); - retry: rb_thread_fd_writable(fd); StringValue(mesg); + retry: if (!NIL_P(to)) { StringValue(to); @@ -401,7 +401,5 @@ bsock_send(argc, argv, sock) } if (n < 0) { - switch (errno) { - case EINTR: - rb_thread_schedule(); + if (rb_io_wait_writable(fd)) { goto retry; } @@ -459,7 +457,5 @@ s_recvfrom(sock, argc, argv, from) if (slen < 0) { - switch (errno) { - case EINTR: - rb_thread_schedule(); + if (rb_io_wait_readable(fd)) { goto retry; } @@ -1187,6 +1183,6 @@ s_accept(klass, fd, sockaddr, len) retry = 1; goto retry; - case EINTR: - rb_thread_schedule(); + } + if (rb_io_wait_readable(fd)) { goto retry; } @@ -1452,7 +1448,5 @@ udp_send(argc, argv, sock) return INT2FIX(n); } - switch (errno) { - case EINTR: - rb_thread_schedule(); + if (rb_io_wait_writable(fileno(f))) { goto retry; } -- --- 僕の前にBugはない。 --- 僕の後ろにBugはできる。 中田 伸悦