[前][次][番号順一覧][スレッド一覧]

ruby-changes:6557

From: usa <ko1@a...>
Date: Tue, 15 Jul 2008 21:35:24 +0900 (JST)
Subject: [ruby-changes:6557] Ruby:r18073 (trunk): * ext/socket/socket.c (ruby_connect, s_accept): came back blocking

usa	2008-07-15 21:34:58 +0900 (Tue, 15 Jul 2008)

  New Revision: 18073

  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=18073

  Log:
    * ext/socket/socket.c (ruby_connect, s_accept): came back blocking
      region because other thread/process maybe read/write the socket
      between select() and connect()/accept().

  Modified files:
    trunk/ext/socket/socket.c

Index: ext/socket/socket.c
===================================================================
--- ext/socket/socket.c	(revision 18072)
+++ ext/socket/socket.c	(revision 18073)
@@ -1142,16 +1142,18 @@
     socklen_t len;
 };
 
-static int
-connect0(struct connect_arg *arg)
+static VALUE
+connect_blocking(void *data)
 {
+    struct connect_arg *arg = data;
     return connect(arg->fd, arg->sockaddr, arg->len);
 }
 
 #if defined(SOCKS) && !defined(SOCKS5)
-static int
-socks_connect0(struct connect_arg *arg)
+static VALUE
+socks_connect_blocking(void *data)
 {
+    struct connect_arg *arg = data;
     return Rconnect(arg->fd, arg->sockaddr, arg->len);
 }
 #endif
@@ -1160,7 +1162,7 @@
 ruby_connect(int fd, const struct sockaddr *sockaddr, int len, int socks)
 {
     int status;
-    int (*func)(struct connect_arg *) = connect0;
+    rb_blocking_function_t *func = connect_blocking;
     struct connect_arg arg;
 #if WAIT_IN_PROGRESS > 0
     int wait_in_progress = -1;
@@ -1172,11 +1174,11 @@
     arg.sockaddr = sockaddr;
     arg.len = len;
 #if defined(SOCKS) && !defined(SOCKS5)
-    if (socks) func = socks_connect0;
+    if (socks) func = socks_connect_blocking;
 #endif
     for (;;) {
 	rb_thread_fd_writable(fd);
-	status = func(&arg);
+	status = BLOCKING_REGION(func, &arg);
 	if (status < 0) {
 	    switch (errno) {
 	      case EAGAIN:
@@ -1526,16 +1528,33 @@
     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:
     rb_thread_wait_fd(fd);
-    fd2 = accept(fd, sockaddr, len);
+    fd2 = BLOCKING_REGION(accept_blocking, &arg);
     if (fd2 < 0) {
 	switch (errno) {
 	  case EMFILE:

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]