[#3228] Core support for Gems, and namespace — "Luke A. Kanies" <luke@...>

Hi all,

21 messages 2004/07/27
[#3230] Re: Core support for Gems, and namespace — Austin Ziegler <halostatue@...> 2004/07/27

On Tue, 27 Jul 2004 11:39:08 +0900, Luke A. Kanies <luke@madstop.com> wrote:

[#3234] Re: Core support for Gems, and namespace — "Luke A. Kanies" <luke@...> 2004/07/27

On Tue, 27 Jul 2004, Austin Ziegler wrote:

[#3238] Re: Core support for Gems, and namespace — Austin Ziegler <halostatue@...> 2004/07/27

On Wed, 28 Jul 2004 00:14:29 +0900, Luke A. Kanies <luke@madstop.com> wrote:

Re: UPDATE - [PATCH] Nonblocking socket connect - Win32 - 181

From: "U.Nakamura" <usa@...>
Date: 2004-07-08 06:05:18 UTC
List: ruby-core #3157
Hello,

In message "Re: UPDATE - [PATCH] Nonblocking socket connect - Win32 - 181"
    on Jul.08,2004 11:33:13, <jean-francois.nadeau@sympatico.ca> wrote:
| I now call rb_thread_select in a loop and when the "except" fd is set, I
| check for a socket error using getsockopt. If I get no error, I loop back on
| rb_thread_select. At the end of the process, I finally get an error code
| from getsockopt and then, I return the error to ruby.
| 
| If you have an explanation for this behavior, please tell me, I am very
| interested to know the answer.

Thank you!

I've modified the patch for CVS HEAD, with nobu's help.
On this new patch, all platforms use wait_connectable() -- derived
from thread_w32_connect_select() -- instead of thread_write_select().
Can I commit this patch, Matz?


Regards,
-- 
U.Nakamura <usa@garbagecollect.jp>

Attachments (1)

nonblocking_connect.diff (4.62 KB, text/x-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

In This Thread