diff options
author | Samuel Williams <samuel.williams@oriontransfer.co.nz> | 2021-06-19 13:47:16 +1200 |
---|---|---|
committer | Samuel Williams <samuel.williams@oriontransfer.co.nz> | 2021-06-22 22:48:57 +1200 |
commit | 45e65f302b663b2c6ab69df06d3b6f219c1797b2 (patch) | |
tree | adf0ed3b3b9c92626f2c21a320ecdf66998b4c27 /ext/socket | |
parent | 3deb5d7113e1fd6e4b468e09464d524d390d811e (diff) | |
download | ruby-45e65f302b663b2c6ab69df06d3b6f219c1797b2.tar.gz |
Deprecate and rework old (fd) centric functions.
Diffstat (limited to 'ext/socket')
-rw-r--r-- | ext/socket/ancdata.c | 4 | ||||
-rw-r--r-- | ext/socket/basicsocket.c | 45 | ||||
-rw-r--r-- | ext/socket/init.c | 13 | ||||
-rw-r--r-- | ext/socket/rubysocket.h | 23 | ||||
-rw-r--r-- | ext/socket/udpsocket.c | 27 |
5 files changed, 58 insertions, 54 deletions
diff --git a/ext/socket/ancdata.c b/ext/socket/ancdata.c index 546a971760..4ec3f3d0a8 100644 --- a/ext/socket/ancdata.c +++ b/ext/socket/ancdata.c @@ -1279,7 +1279,7 @@ bsock_sendmsg_internal(VALUE sock, VALUE data, VALUE vflags, if (ss == -1) { int e; - if (!nonblock && rb_io_wait_writable(fptr->fd)) { + if (!nonblock && rb_io_maybe_wait_writable(errno, fptr->self, Qnil)) { rb_io_check_closed(fptr); goto retry; } @@ -1551,7 +1551,7 @@ bsock_recvmsg_internal(VALUE sock, if (ss == -1) { int e; - if (!nonblock && rb_io_wait_readable(fptr->fd)) { + if (!nonblock && rb_io_maybe_wait_readable(errno, fptr->self, Qnil)) { rb_io_check_closed(fptr); goto retry; } diff --git a/ext/socket/basicsocket.c b/ext/socket/basicsocket.c index 6168698df1..05172100c8 100644 --- a/ext/socket/basicsocket.c +++ b/ext/socket/basicsocket.c @@ -537,12 +537,11 @@ bsock_remote_address(VALUE sock) * } */ VALUE -rsock_bsock_send(int argc, VALUE *argv, VALUE sock) +rsock_bsock_send(int argc, VALUE *argv, VALUE socket) { struct rsock_send_arg arg; VALUE flags, to; rb_io_t *fptr; - ssize_t n; rb_blocking_function_t *func; const char *funcname; @@ -550,28 +549,38 @@ rsock_bsock_send(int argc, VALUE *argv, VALUE sock) StringValue(arg.mesg); if (!NIL_P(to)) { - SockAddrStringValue(to); - to = rb_str_new4(to); - arg.to = (struct sockaddr *)RSTRING_PTR(to); - arg.tolen = RSTRING_SOCKLEN(to); - func = rsock_sendto_blocking; - funcname = "sendto(2)"; + SockAddrStringValue(to); + to = rb_str_new4(to); + arg.to = (struct sockaddr *)RSTRING_PTR(to); + arg.tolen = RSTRING_SOCKLEN(to); + func = rsock_sendto_blocking; + funcname = "sendto(2)"; } else { - func = rsock_send_blocking; - funcname = "send(2)"; + func = rsock_send_blocking; + funcname = "send(2)"; } - GetOpenFile(sock, fptr); + + RB_IO_POINTER(socket, fptr); + arg.fd = fptr->fd; arg.flags = NUM2INT(flags); - while (rsock_maybe_fd_writable(arg.fd), - (n = (ssize_t)BLOCKING_REGION_FD(func, &arg)) < 0) { - if (rb_io_maybe_wait_writable(errno, sock, Qnil)) { - continue; - } - rb_sys_fail(funcname); + + while (true) { +#ifdef RSOCK_WAIT_BEFORE_BLOCKING + rb_io_wait(socket, RB_INT2NUM(RUBY_IO_WRITABLE), Qnil); +#endif + + ssize_t n = (ssize_t)BLOCKING_REGION_FD(func, &arg); + + if (n >= 0) return SSIZET2NUM(n); + + if (rb_io_maybe_wait_writable(errno, socket, Qnil)) { + continue; + } + + rb_sys_fail(funcname); } - return SSIZET2NUM(n); } /* diff --git a/ext/socket/init.c b/ext/socket/init.c index 8eb8c8e901..5859c33e29 100644 --- a/ext/socket/init.c +++ b/ext/socket/init.c @@ -198,7 +198,10 @@ rsock_s_recvfrom(VALUE socket, int argc, VALUE *argv, enum sock_recv_type from) while (true) { rb_io_check_closed(fptr); - rsock_maybe_wait_fd(arg.fd); + +#ifdef RSOCK_WAIT_BEFORE_BLOCKING + rb_io_wait(fptr->self, RB_INT2NUM(RUBY_IO_READABLE), Qnil); +#endif slen = (long)rb_str_locktmp_ensure(str, recvfrom_locktmp, (VALUE)&arg); @@ -701,11 +704,13 @@ rsock_s_accept(VALUE klass, VALUE io, struct sockaddr *sockaddr, socklen_t *len) .len = len }; - int retry = 0; + int retry = 0, peer; retry: - rsock_maybe_wait_fd(accept_arg.fd); - int peer = (int)BLOCKING_REGION_FD(accept_blocking, &accept_arg); +#ifdef RSOCK_WAIT_BEFORE_BLOCKING + rb_io_wait(fptr->self, RB_INT2NUM(RUBY_IO_READABLE), Qnil); +#endif + peer = (int)BLOCKING_REGION_FD(accept_blocking, &accept_arg); if (peer < 0) { int error = errno; diff --git a/ext/socket/rubysocket.h b/ext/socket/rubysocket.h index a7755660e9..c0d40addca 100644 --- a/ext/socket/rubysocket.h +++ b/ext/socket/rubysocket.h @@ -432,30 +432,17 @@ NORETURN(void rsock_sys_fail_sockaddr(const char *, struct sockaddr *addr, sockl NORETURN(void rsock_sys_fail_raddrinfo(const char *, VALUE rai)); NORETURN(void rsock_sys_fail_raddrinfo_or_sockaddr(const char *, VALUE addr, VALUE rai)); -/* - * It is safe on Linux to attempt using a socket without waiting on it in - * all cases. For some syscalls (e.g. accept/accept4), blocking on the - * syscall instead of relying on select/poll allows the kernel to use - * "wake-one" behavior and avoid the thundering herd problem. - * This is likely safe on all other *nix-like systems, so this safe list - * can be expanded by interested parties. - */ -#if defined(__linux__) -static inline int rsock_maybe_fd_writable(int fd) { return 1; } -static inline void rsock_maybe_wait_fd(int fd) { } -# ifdef MSG_DONTWAIT -# define MSG_DONTWAIT_RELIABLE 1 -# endif -#else /* some systems (mswin/mingw) need these. ref: r36946 */ -# define rsock_maybe_fd_writable(fd) rb_thread_fd_writable((fd)) -# define rsock_maybe_wait_fd(fd) rb_thread_wait_fd((fd)) +#if defined(__MINGW32__) || defined(_WIN32) +#define RSOCK_WAIT_BEFORE_BLOCKING #endif /* * some OSes may support MSG_DONTWAIT inconsistently depending on socket * type, we only expect Linux to support it consistently for all socket types. */ -#ifndef MSG_DONTWAIT_RELIABLE +#if defined(MSG_DONTWAIT) && defined(__linux__) +# define MSG_DONTWAIT_RELIABLE 1 +#else # define MSG_DONTWAIT_RELIABLE 0 #endif diff --git a/ext/socket/udpsocket.c b/ext/socket/udpsocket.c index 593f05522d..94ea19c224 100644 --- a/ext/socket/udpsocket.c +++ b/ext/socket/udpsocket.c @@ -153,23 +153,26 @@ udp_send_internal(VALUE v) { struct udp_send_arg *arg = (void *)v; 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; - } + arg->sarg.fd = fptr->fd; + arg->sarg.to = res->ai_addr; + arg->sarg.tolen = res->ai_addrlen; + +#ifdef RSOCK_WAIT_BEFORE_BLOCKING + rb_io_wait(fptr->self, RB_INT2NUM(RUBY_IO_WRITABLE), Qnil); +#endif + + ssize_t n = (ssize_t)BLOCKING_REGION_FD(rsock_sendto_blocking, &arg->sarg); + + if (n >= 0) return RB_INT2NUM(n); + + if (rb_io_maybe_wait_writable(errno, fptr->self, Qnil)) { + goto retry; + } } return Qfalse; } |