[ruby-list:39995] Re: TCPSocket.new でスレッドが止まる。
From:
nobu@...
Date:
2004-09-02 05:58:59 UTC
List:
ruby-list #39995
なかだです。
At Thu, 2 Sep 2004 14:07:33 +0900,
take_tk wrote in [ruby-list:39993]:
> http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-core/3157
>
> とほほ、base64 で暗号になっている……。
http://rrr.jin.gr.jp/~usa/ruby/nonblocking_connect.diff
はちょっと古いやつですねぇ。
Index: bcc32/Makefile.sub
===================================================================
RCS file: /home/cvs/ruby/bcc32/Makefile.sub,v
retrieving revision 1.64
diff -u -1 -p -w -r1.64 Makefile.sub
--- bcc32/Makefile.sub 22 Apr 2004 01:08:23 -0000 1.64
+++ bcc32/Makefile.sub 8 Jul 2004 06:02:23 -0000
@@ -254,2 +254,3 @@ config.h:
\#define HAVE_TIMES 1
+\#define HAVE_FCNTL 1
\#define HAVE_LINK 1
Index: ext/socket/socket.c
===================================================================
RCS file: /home/cvs/ruby/ext/socket/socket.c,v
retrieving revision 1.126
diff -u -1 -p -w -r1.126 socket.c
--- ext/socket/socket.c 24 Jun 2004 23:10:54 -0000 1.126
+++ ext/socket/socket.c 8 Jul 2004 06:02:24 -0000
@@ -54,6 +54,12 @@
#endif
+#ifdef HAVE_SYS_TYPES_H
#include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_TIME_H
#include <sys/time.h>
+#endif
+#ifdef HAVE_FCNTL_H
#include <fcntl.h>
#endif
+#endif
#ifndef EWOULDBLOCK
@@ -796,11 +802,32 @@ ruby_socket(domain, type, proto)
-static void
-thread_write_select(fd)
+static int
+wait_connectable(fd)
int fd;
{
- fd_set fds;
+ int sockerr, sockerrlen;
+ fd_set fds_w;
+ fd_set fds_e;
- FD_ZERO(&fds);
- FD_SET(fd, &fds);
- rb_thread_select(fd+1, 0, &fds, 0, 0);
+ for (;;) {
+ FD_ZERO(&fds_w);
+ FD_ZERO(&fds_e);
+
+ FD_SET(fd, &fds_w);
+ FD_SET(fd, &fds_e);
+
+ rb_thread_select(fd+1, 0, &fds_w, &fds_e, 0);
+
+ if (FD_ISSET(fd, &fds_w)) {
+ return 0;
+ }
+ else if (FD_ISSET(fd, &fds_e)) {
+ sockerrlen = sizeof(sockerr);
+ if (getsockopt(fd, SOL_SOCKET, SO_ERROR, (void *)&sockerr,
+ &sockerrlen))
+ errno = sockerr;
+ return -1;
+ }
+ }
+
+ return 0;
}
@@ -837,3 +864,7 @@ ruby_connect(fd, sockaddr, len, socks)
#if defined(HAVE_FCNTL)
+# if defined(F_GETFL)
mode = fcntl(fd, F_GETFL, 0);
+# else
+ mode = 0;
+# endif
@@ -886,3 +917,7 @@ ruby_connect(fd, sockaddr, len, socks)
#endif
- thread_write_select(fd);
+ status = wait_connectable(fd);
+ if (status) {
+ break;
+ }
+ errno = 0;
continue;
Index: win32/Makefile.sub
===================================================================
RCS file: /home/cvs/ruby/win32/Makefile.sub,v
retrieving revision 1.81
diff -u -1 -p -w -r1.81 Makefile.sub
--- win32/Makefile.sub 22 Apr 2004 01:08:23 -0000 1.81
+++ win32/Makefile.sub 8 Jul 2004 06:02:29 -0000
@@ -245,2 +245,3 @@ config.h:
#define HAVE_TIMES 1
+#define HAVE_FCNTL 1
#define HAVE_LINK 1
Index: win32/win32.c
===================================================================
RCS file: /home/cvs/ruby/win32/win32.c,v
retrieving revision 1.117
diff -u -1 -p -w -r1.117 win32.c
--- win32/win32.c 21 Jun 2004 00:27:39 -0000 1.117
+++ win32/win32.c 8 Jul 2004 06:02:29 -0000
@@ -1992,4 +1992,12 @@ rb_w32_connect(int s, struct sockaddr *a
r = connect(TO_SOCKET(s), addr, addrlen);
- if (r == SOCKET_ERROR)
- errno = map_errno(WSAGetLastError());
+ if (r == SOCKET_ERROR) {
+ r = WSAGetLastError();
+ if (r != WSAEWOULDBLOCK) {
+ errno = map_errno(r);
+ }
+ else {
+ errno = EINPROGRESS;
+ r = -1;
+ }
+ }
});
@@ -2356,2 +2364,39 @@ void setservent (int stayopen) {}
+int
+fcntl(int fd, int cmd, ...)
+{
+ SOCKET sock = TO_SOCKET(fd);
+ va_list va;
+ int arg;
+ int ret;
+ u_long ioctlArg;
+
+ if (!is_socket(sock)) {
+ errno = EBADF;
+ return -1;
+ }
+ if (cmd != F_SETFL) {
+ errno = EINVAL;
+ return -1;
+ }
+
+ va_start(va, cmd);
+ arg = va_arg(va, int);
+ va_end(va);
+ if (arg & O_NONBLOCK) {
+ ioctlArg = 1;
+ }
+ else {
+ ioctlArg = 0;
+ }
+ RUBY_CRITICAL({
+ ret = ioctlsocket(sock, FIONBIO, &ioctlArg);
+ if (ret == -1) {
+ errno = map_errno(WSAGetLastError());
+ }
+ });
+
+ return ret;
+}
+
#ifndef WNOHANG
Index: win32/win32.h
===================================================================
RCS file: /home/cvs/ruby/win32/win32.h,v
retrieving revision 1.51
diff -u -1 -p -w -r1.51 win32.h
--- win32/win32.h 19 Feb 2004 09:08:23 -0000 1.51
+++ win32/win32.h 8 Jul 2004 06:02:29 -0000
@@ -179,2 +179,3 @@ extern int rb_w32_aspawn(int, const char
extern int kill(int, int);
+extern int fcntl(int, int, ...);
extern pid_t rb_w32_getpid(void);
@@ -313,2 +314,5 @@ extern char *rb_w32_strerror(int);
+#define F_SETFL 1
+#define O_NONBLOCK 1
+
#ifdef accept
Index: wince/Makefile.sub
===================================================================
RCS file: /home/cvs/ruby/wince/Makefile.sub,v
retrieving revision 1.28
diff -u -1 -p -w -r1.28 Makefile.sub
--- wince/Makefile.sub 22 Apr 2004 01:08:23 -0000 1.28
+++ wince/Makefile.sub 8 Jul 2004 06:02:29 -0000
@@ -249,2 +249,3 @@ config.h:
#define HAVE_TIMES 1
+#define HAVE_FCNTL 1
#define HAVE_TELLDIR 1
--
--- 僕の前にBugはない。
--- 僕の後ろにBugはできる。
中田 伸悦