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

ruby-changes:40031

From: nobu <ko1@a...>
Date: Mon, 12 Oct 2015 09:12:02 +0900 (JST)
Subject: [ruby-changes:40031] nobu:r52112 (trunk): udpsocket.c: free addrinfo

nobu	2015-10-12 09:11:54 +0900 (Mon, 12 Oct 2015)

  New Revision: 52112

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

  Log:
    udpsocket.c: free addrinfo
    
    * ext/socket/udpsocket.c (udp_send): ensure addrinfo gets freed.

  Modified files:
    trunk/ext/socket/udpsocket.c
Index: ext/socket/udpsocket.c
===================================================================
--- ext/socket/udpsocket.c	(revision 52111)
+++ ext/socket/udpsocket.c	(revision 52112)
@@ -138,6 +138,37 @@ udp_bind(VALUE sock, VALUE host, VALUE p https://github.com/ruby/ruby/blob/trunk/ext/socket/udpsocket.c#L138
     return INT2FIX(0);
 }
 
+struct udp_send_arg {
+    struct rb_addrinfo *res;
+    rb_io_t *fptr;
+    struct rsock_send_arg sarg;
+};
+
+static VALUE
+udp_send_internal(struct udp_send_arg *arg)
+{
+    rb_io_t *fptr;
+    int n;
+    struct addrinfo *res;
+
+    rb_io_check_closed(fptr = arg->fptr);
+    for (res = arg->res->ai; res; res = res->ai_next) {
+      retry:
+	arg->sarg.fd = fptr->fd;
+	arg->sarg.to = res->ai_addr;
+	arg->sarg.tolen = res->ai_addrlen;
+	rsock_maybe_fd_writable(arg->sarg.fd);
+	n = (int)BLOCKING_REGION_FD(rsock_sendto_blocking, &arg->sarg);
+	if (n >= 0) {
+	    return INT2FIX(n);
+	}
+	if (rb_io_wait_writable(fptr->fd)) {
+	    goto retry;
+	}
+    }
+    return Qfalse;
+}
+
 /*
  * call-seq:
  *   udpsocket.send(mesg, flags, host, port)  => numbytes_sent
@@ -164,39 +195,23 @@ static VALUE https://github.com/ruby/ruby/blob/trunk/ext/socket/udpsocket.c#L195
 udp_send(int argc, VALUE *argv, VALUE sock)
 {
     VALUE flags, host, port;
-    rb_io_t *fptr;
-    int n;
-    struct rb_addrinfo *res0;
-    struct addrinfo *res;
-    struct rsock_send_arg arg;
+    struct udp_send_arg arg;
+    VALUE ret;
 
     if (argc == 2 || argc == 3) {
 	return rsock_bsock_send(argc, argv, sock);
     }
-    rb_scan_args(argc, argv, "4", &arg.mesg, &flags, &host, &port);
+    rb_scan_args(argc, argv, "4", &arg.sarg.mesg, &flags, &host, &port);
 
-    StringValue(arg.mesg);
-    GetOpenFile(sock, fptr);
-    res0 = rsock_addrinfo(host, port, SOCK_DGRAM, 0);
-    arg.fd = fptr->fd;
-    arg.flags = NUM2INT(flags);
-    for (res = res0->ai; res; res = res->ai_next) {
-      retry:
-	arg.to = res->ai_addr;
-	arg.tolen = res->ai_addrlen;
-	rsock_maybe_fd_writable(arg.fd);
-	n = (int)BLOCKING_REGION_FD(rsock_sendto_blocking, &arg);
-	if (n >= 0) {
-	    rb_freeaddrinfo(res0);
-	    return INT2FIX(n);
-	}
-	if (rb_io_wait_writable(fptr->fd)) {
-	    goto retry;
-	}
-    }
-    rb_freeaddrinfo(res0);
-    rsock_sys_fail_host_port("sendto(2)", host, port);
-    return INT2FIX(n);
+    StringValue(arg.sarg.mesg);
+    GetOpenFile(sock, arg.fptr);
+    arg.sarg.fd = arg.fptr->fd;
+    arg.sarg.flags = NUM2INT(flags);
+    arg.res = rsock_addrinfo(host, port, SOCK_DGRAM, 0);
+    ret = rb_ensure(udp_send_internal, (VALUE)&arg,
+		    rsock_freeaddrinfo, (VALUE)arg.res);
+    if (!ret) rsock_sys_fail_host_port("sendto(2)", host, port);
+    return ret;
 }
 
 /*

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

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