diff options
author | normal <normal@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2015-11-16 23:40:15 +0000 |
---|---|---|
committer | normal <normal@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2015-11-16 23:40:15 +0000 |
commit | f335eab8c71614d764e4ce499ea82e1046b50db4 (patch) | |
tree | 8624f2be2e0563b09f36016bc3a60be51849200a /ext/socket/socket.c | |
parent | 38340a5a34fa98a39b3946414e8ffe2f5e91dfab (diff) | |
download | ruby-f335eab8c71614d764e4ce499ea82e1046b50db4.tar.gz |
socket: avoid arg parsing in rsock_s_accept_nonblock
* ext/socket/init.c (rsock_s_accept_nonblock): avoid parsing args
[ruby-core:71439] [Feature #11339]
* ext/socket/rubysocket.h: adjust prototype
* ext/socket/socket.c (sock_accept_nonblock): make private
* ext/socket/tcpserver.c (tcp_accept_nonblock): ditto
* ext/socket/unixserver.c (unix_accept_nonblock): ditto
* ext/socket/lib/socket.rb (Socket#accept_nonblock):
implement as wrapper, move RDoc
(TCPServer#accept_nonblock): ditto
(UNIXServer#accept_nonblock): ditto
target 0: a (ruby 2.3.0dev (2015-11-12 trunk 52550) [x86_64-linux])
target 1: b (ruby 2.3.0dev (2015-11-12 avoid-kwarg-capi 52550) [x86_64-linux]
-----------------------------------------------------------
accept_nonblock
require 'tempfile'
require 'socket'
require 'io/wait'
nr = 500000
Tempfile.create(%w(accept_nonblock .sock)) do |tmp|
path = tmp.path
File.unlink(path)
s = UNIXServer.new(path)
addr = Socket.sockaddr_un(path).freeze
nr.times do
s.accept_nonblock(exception: false)
c = UNIXSocket.new(path)
s.wait_readable
s.accept_nonblock(exception: false).close
c.close
end
end
-----------------------------------------------------------
raw data:
[["accept_nonblock",
[[4.807877402752638,
4.930681671947241,
4.738454818725586,
4.69268161803484,
4.684675686061382],
[4.253904823213816,
4.255124930292368,
4.295955188572407,
4.248479191213846,
4.213303029537201]]]]
Elapsed time: 45.123040065 (sec)
-----------------------------------------------------------
benchmark results:
minimum results in each 5 measurements.
Execution time (sec)
name a b
accept_nonblock 4.685 4.213
Speedup ratio: compare with the result of `a' (greater is better)
name b
accept_nonblock 1.112
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@52601 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'ext/socket/socket.c')
-rw-r--r-- | ext/socket/socket.c | 66 |
1 files changed, 8 insertions, 58 deletions
diff --git a/ext/socket/socket.c b/ext/socket/socket.c index a410625537..cc5cbe10d5 100644 --- a/ext/socket/socket.c +++ b/ext/socket/socket.c @@ -800,63 +800,9 @@ sock_accept(VALUE sock) return rb_assoc_new(sock2, rsock_io_socket_addrinfo(sock2, &buf.addr, len)); } -/* - * call-seq: - * socket.accept_nonblock([options]) => [client_socket, client_addrinfo] - * - * Accepts an incoming connection using accept(2) after - * O_NONBLOCK is set for the underlying file descriptor. - * It returns an array containing the accepted socket - * for the incoming connection, _client_socket_, - * and an Addrinfo, _client_addrinfo_. - * - * === Example - * # In one script, start this first - * require 'socket' - * include Socket::Constants - * socket = Socket.new(AF_INET, SOCK_STREAM, 0) - * sockaddr = Socket.sockaddr_in(2200, 'localhost') - * socket.bind(sockaddr) - * socket.listen(5) - * begin # emulate blocking accept - * client_socket, client_addrinfo = socket.accept_nonblock - * rescue IO::WaitReadable, Errno::EINTR - * IO.select([socket]) - * retry - * end - * puts "The client said, '#{client_socket.readline.chomp}'" - * client_socket.puts "Hello from script one!" - * socket.close - * - * # In another script, start this second - * require 'socket' - * include Socket::Constants - * socket = Socket.new(AF_INET, SOCK_STREAM, 0) - * sockaddr = Socket.sockaddr_in(2200, 'localhost') - * socket.connect(sockaddr) - * socket.puts "Hello from script 2." - * puts "The server said, '#{socket.readline.chomp}'" - * socket.close - * - * Refer to Socket#accept for the exceptions that may be thrown if the call - * to _accept_nonblock_ fails. - * - * Socket#accept_nonblock may raise any error corresponding to accept(2) failure, - * including Errno::EWOULDBLOCK. - * - * If the exception is Errno::EWOULDBLOCK, Errno::EAGAIN, Errno::ECONNABORTED or Errno::EPROTO, - * it is extended by IO::WaitReadable. - * So IO::WaitReadable can be used to rescue the exceptions for retrying accept_nonblock. - * - * By specifying `exception: false`, the options hash allows you to indicate - * that accept_nonblock should not raise an IO::WaitReadable exception, but - * return the symbol :wait_readable instead. - * - * === See - * * Socket#accept - */ +/* :nodoc: */ static VALUE -sock_accept_nonblock(int argc, VALUE *argv, VALUE sock) +sock_accept_nonblock(VALUE sock, VALUE ex) { rb_io_t *fptr; VALUE sock2; @@ -865,7 +811,7 @@ sock_accept_nonblock(int argc, VALUE *argv, VALUE sock) socklen_t len = (socklen_t)sizeof buf; GetOpenFile(sock, fptr); - sock2 = rsock_s_accept_nonblock(argc, argv, rb_cSocket, fptr, addr, &len); + sock2 = rsock_s_accept_nonblock(rb_cSocket, ex, fptr, addr, &len); if (SYMBOL_P(sock2)) /* :wait_readable */ return sock2; @@ -2073,7 +2019,11 @@ Init_socket(void) 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); - rb_define_method(rb_cSocket, "accept_nonblock", sock_accept_nonblock, -1); + + /* for ext/socket/lib/socket.rb use only: */ + rb_define_private_method(rb_cSocket, + "__accept_nonblock", sock_accept_nonblock, 1); + rb_define_method(rb_cSocket, "sysaccept", sock_sysaccept, 0); rb_define_method(rb_cSocket, "recvfrom", sock_recvfrom, -1); |