dumping ground for random patches and texts
 help / color / mirror / Atom feed
* [PATCH] socket: Socket#connect_nonblock avoids get_kwarg
@ 2015-11-12  9:03 Eric Wong
  0 siblings, 0 replies; only message in thread
From: Eric Wong @ 2015-11-12  9:03 UTC (permalink / raw)
  To: spew

Note: this is difficult to benchmark since kernel socket
allocations are non-deterministic.
---
 ext/socket/lib/socket.rb | 48 ++++++++++++++++++++++++++++++++++++-
 ext/socket/socket.c      | 61 +++++++-----------------------------------------
 2 files changed, 55 insertions(+), 54 deletions(-)

diff --git a/ext/socket/lib/socket.rb b/ext/socket/lib/socket.rb
index 7c66e8f..cd2ba45 100644
--- a/ext/socket/lib/socket.rb
+++ b/ext/socket/lib/socket.rb
@@ -864,5 +864,51 @@ class Socket < BasicSocket
     }
   end
 
+  # call-seq:
+  #   socket.connect_nonblock(remote_sockaddr, [options]) => 0
+  #
+  # Requests a connection to be made on the given +remote_sockaddr+ after
+  # O_NONBLOCK is set for the underlying file descriptor.
+  # Returns 0 if successful, otherwise an exception is raised.
+  #
+  # === Parameter
+  #  # +remote_sockaddr+ - the +struct+ sockaddr contained in a string or Addrinfo object
+  #
+  # === Example:
+  #   # Pull down Google's web page
+  #   require 'socket'
+  #   include Socket::Constants
+  #   socket = Socket.new(AF_INET, SOCK_STREAM, 0)
+  #   sockaddr = Socket.sockaddr_in(80, 'www.google.com')
+  #   begin # emulate blocking connect
+  #     socket.connect_nonblock(sockaddr)
+  #   rescue IO::WaitWritable
+  #     IO.select(nil, [socket]) # wait 3-way handshake completion
+  #     begin
+  #       socket.connect_nonblock(sockaddr) # check connection failure
+  #     rescue Errno::EISCONN
+  #     end
+  #   end
+  #   socket.write("GET / HTTP/1.0\r\n\r\n")
+  #   results = socket.read
+  #
+  # Refer to Socket#connect for the exceptions that may be thrown if the call
+  # to _connect_nonblock_ fails.
+  #
+  # Socket#connect_nonblock may raise any error corresponding to connect(2) failure,
+  # including Errno::EINPROGRESS.
+  #
+  # If the exception is Errno::EINPROGRESS,
+  # it is extended by IO::WaitWritable.
+  # So IO::WaitWritable can be used to rescue the exceptions for retrying connect_nonblock.
+  #
+  # By specifying `exception: false`, the options hash allows you to indicate
+  # that connect_nonblock should not raise an IO::WaitWritable exception, but
+  # return the symbol :wait_writable instead.
+  #
+  # === See
+  #  # Socket#connect
+  def connect_nonblock(addr, exception: true)
+    __connect_nonblock(addr, exception)
+  end
 end
-
diff --git a/ext/socket/socket.c b/ext/socket/socket.c
index 779398c..b75ba95 100644
--- a/ext/socket/socket.c
+++ b/ext/socket/socket.c
@@ -439,62 +439,14 @@ sock_connect(VALUE sock, VALUE addr)
     return INT2FIX(n);
 }
 
-/*
- * call-seq:
- *   socket.connect_nonblock(remote_sockaddr, [options]) => 0
- *
- * Requests a connection to be made on the given +remote_sockaddr+ after
- * O_NONBLOCK is set for the underlying file descriptor.
- * Returns 0 if successful, otherwise an exception is raised.
- *
- * === Parameter
- * * +remote_sockaddr+ - the +struct+ sockaddr contained in a string or Addrinfo object
- *
- * === Example:
- *   # Pull down Google's web page
- *   require 'socket'
- *   include Socket::Constants
- *   socket = Socket.new(AF_INET, SOCK_STREAM, 0)
- *   sockaddr = Socket.sockaddr_in(80, 'www.google.com')
- *   begin # emulate blocking connect
- *     socket.connect_nonblock(sockaddr)
- *   rescue IO::WaitWritable
- *     IO.select(nil, [socket]) # wait 3-way handshake completion
- *     begin
- *       socket.connect_nonblock(sockaddr) # check connection failure
- *     rescue Errno::EISCONN
- *     end
- *   end
- *   socket.write("GET / HTTP/1.0\r\n\r\n")
- *   results = socket.read
- *
- * Refer to Socket#connect for the exceptions that may be thrown if the call
- * to _connect_nonblock_ fails.
- *
- * Socket#connect_nonblock may raise any error corresponding to connect(2) failure,
- * including Errno::EINPROGRESS.
- *
- * If the exception is Errno::EINPROGRESS,
- * it is extended by IO::WaitWritable.
- * So IO::WaitWritable can be used to rescue the exceptions for retrying connect_nonblock.
- *
- * By specifying `exception: false`, the options hash allows you to indicate
- * that connect_nonblock should not raise an IO::WaitWritable exception, but
- * return the symbol :wait_writable instead.
- *
- * === See
- * * Socket#connect
- */
+/* :nodoc: */
 static VALUE
-sock_connect_nonblock(int argc, VALUE *argv, VALUE sock)
+connect_nb(VALUE sock, VALUE addr, VALUE ex)
 {
-    VALUE addr;
-    VALUE opts = Qnil;
     VALUE rai;
     rb_io_t *fptr;
     int n;
 
-    rb_scan_args(argc, argv, "1:", &addr, &opts);
     SockAddrStringValueWithAddrinfo(addr, rai);
     addr = rb_str_new4(addr);
     GetOpenFile(sock, fptr);
@@ -502,13 +454,13 @@ sock_connect_nonblock(int argc, VALUE *argv, VALUE sock)
     n = connect(fptr->fd, (struct sockaddr*)RSTRING_PTR(addr), RSTRING_SOCKLEN(addr));
     if (n < 0) {
         if (errno == EINPROGRESS) {
-           if (rsock_opt_false_p(opts, sym_exception)) {
+            if (ex == Qfalse) {
                 return sym_wait_writable;
             }
             rb_readwrite_sys_fail(RB_IO_WAIT_WRITABLE, "connect(2) would block");
 	}
 	if (errno == EISCONN) {
-           if (rsock_opt_false_p(opts, sym_exception)) {
+            if (ex == Qfalse) {
                 return INT2FIX(0);
             }
 	}
@@ -2174,7 +2126,10 @@ Init_socket(void)
 
     rb_define_method(rb_cSocket, "initialize", sock_initialize, -1);
     rb_define_method(rb_cSocket, "connect", sock_connect, 1);
-    rb_define_method(rb_cSocket, "connect_nonblock", sock_connect_nonblock, -1);
+
+    /* for ext/socket/lib/socket.rb use only: */
+    rb_define_private_method(rb_cSocket, "__connect_nonblock", connect_nb, 2);
+
     rb_define_method(rb_cSocket, "bind", sock_bind, 1);
     rb_define_method(rb_cSocket, "listen", rsock_sock_listen, 1);
     rb_define_method(rb_cSocket, "accept", sock_accept, 0);
-- 
EW


^ permalink raw reply related	[flat|nested] only message in thread

only message in thread, other threads:[~2015-11-12  9:03 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-11-12  9:03 [PATCH] socket: Socket#connect_nonblock avoids get_kwarg Eric Wong

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).