[#39989] TCPSocket.new でスレッドが止まる。 — take_tk <ggb03124@...>

たけ(tk)です。

15 messages 2004/09/02

[#40018] yaml.rbとdate.rbを組み合わせて使った際の問題 — "Keisuke Minami" <keisuke@...>

こんにちは。三並と申します。

14 messages 2004/09/07
[#40020] Re: yaml.rbとdate.rbを組み合わせて使った際の問題 — IWATSUKI Hiroyuki <don@...> 2004/09/07

岩月と申します。

[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はできる。
    中田 伸悦

In This Thread