diff options
author | normal <normal@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2015-06-15 19:38:49 +0000 |
---|---|---|
committer | normal <normal@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2015-06-15 19:38:49 +0000 |
commit | b9a91334c50e5a0b8ea0a4b571cd3011228cba6c (patch) | |
tree | 2c2943128de42db8c8eba898a1c402c7d8bf8ca1 /ext/socket/init.c | |
parent | 91af3e00d1bdf7aab0d8f413ebbc5494d017f08c (diff) | |
download | ruby-b9a91334c50e5a0b8ea0a4b571cd3011228cba6c.tar.gz |
socket: allow exception-free nonblocking sendmsg/recvmsg
As documented before, exceptions are expensive and IO::Wait*able are too
common in socket applications to be the exceptional case. Datagram
sockets deserve the same API which stream sockets are allowed with
read_nonblock and write_nonblock.
Note: this does not offer a performance advantage under optimal
conditions when both ends are equally matched in speed, but it it
does make debug output cleaner by avoiding exceptions whenever
the receiver slows down.
* ext/socket/ancdata.c (bsock_sendmsg_internal, bsock_recvmsg_internal):
support "exception: false" kwarg
* ext/socket/init.c (rsock_s_recvfrom_nonblock):
ditto
* ext/socket/init.c (rsock_s_recvfrom_nonblock): use rsock_opt_false_p
* ext/socket/socket.c (sock_connect_nonblock): ditto
* ext/socket/rubysocket.h (rsock_opt_false_p): new function
* ext/socket/basicsocket.c (bsock_recv_nonblock): update rdoc
* ext/socket/udpsocket.c (udp_recvfrom_nonblock): ditto
* test/socket/test_nonblock.rb: new tests
[ruby-core:69542] [Feature #11229]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@50910 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'ext/socket/init.c')
-rw-r--r-- | ext/socket/init.c | 11 |
1 files changed, 5 insertions, 6 deletions
diff --git a/ext/socket/init.c b/ext/socket/init.c index 455652d082..5f0d445c70 100644 --- a/ext/socket/init.c +++ b/ext/socket/init.c @@ -188,9 +188,10 @@ rsock_s_recvfrom_nonblock(VALUE sock, int argc, VALUE *argv, enum sock_recv_type long slen; int fd, flags; VALUE addr = Qnil; + VALUE opts = Qnil; socklen_t len0; - rb_scan_args(argc, argv, "11", &len, &flg); + rb_scan_args(argc, argv, "11:", &len, &flg, &opts); if (flg == Qnil) flags = 0; else flags = NUM2INT(flg); @@ -226,6 +227,8 @@ rsock_s_recvfrom_nonblock(VALUE sock, int argc, VALUE *argv, enum sock_recv_type #if defined(EWOULDBLOCK) && EWOULDBLOCK != EAGAIN case EWOULDBLOCK: #endif + if (rsock_opt_false_p(opts, sym_exception)) + return sym_wait_readable; rb_readwrite_sys_fail(RB_IO_WAIT_READABLE, "recvfrom(2) would block"); } rb_sys_fail("recvfrom(2)"); @@ -528,14 +531,10 @@ rsock_s_accept_nonblock(int argc, VALUE *argv, VALUE klass, rb_io_t *fptr, struct sockaddr *sockaddr, socklen_t *len) { int fd2; - int ex = 1; VALUE opts = Qnil; rb_scan_args(argc, argv, "0:", &opts); - if (!NIL_P(opts) && Qfalse == rb_hash_lookup2(opts, sym_exception, Qundef)) - ex = 0; - rb_secure(3); rb_io_set_nonblock(fptr); fd2 = cloexec_accept(fptr->fd, (struct sockaddr*)sockaddr, len, 1); @@ -549,7 +548,7 @@ rsock_s_accept_nonblock(int argc, VALUE *argv, VALUE klass, rb_io_t *fptr, #if defined EPROTO case EPROTO: #endif - if (!ex) + if (rsock_opt_false_p(opts, sym_exception)) return sym_wait_readable; rb_readwrite_sys_fail(RB_IO_WAIT_READABLE, "accept(2) would block"); } |