зеркало из https://github.com/github/ruby.git
Deprecate and rework old (fd) centric functions.
This commit is contained in:
Родитель
3deb5d7113
Коммит
45e65f302b
|
@ -1,165 +0,0 @@
|
|||
# AUTOGENERATED DEPENDENCIES START
|
||||
wait_for_single_fd.o: $(RUBY_EXTCONF_H)
|
||||
wait_for_single_fd.o: $(arch_hdrdir)/ruby/config.h
|
||||
wait_for_single_fd.o: $(hdrdir)/ruby/internal/anyargs.h
|
||||
wait_for_single_fd.o: $(hdrdir)/ruby/internal/arithmetic.h
|
||||
wait_for_single_fd.o: $(hdrdir)/ruby/internal/arithmetic/char.h
|
||||
wait_for_single_fd.o: $(hdrdir)/ruby/internal/arithmetic/double.h
|
||||
wait_for_single_fd.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h
|
||||
wait_for_single_fd.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h
|
||||
wait_for_single_fd.o: $(hdrdir)/ruby/internal/arithmetic/int.h
|
||||
wait_for_single_fd.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h
|
||||
wait_for_single_fd.o: $(hdrdir)/ruby/internal/arithmetic/long.h
|
||||
wait_for_single_fd.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h
|
||||
wait_for_single_fd.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h
|
||||
wait_for_single_fd.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h
|
||||
wait_for_single_fd.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h
|
||||
wait_for_single_fd.o: $(hdrdir)/ruby/internal/arithmetic/short.h
|
||||
wait_for_single_fd.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h
|
||||
wait_for_single_fd.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h
|
||||
wait_for_single_fd.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h
|
||||
wait_for_single_fd.o: $(hdrdir)/ruby/internal/assume.h
|
||||
wait_for_single_fd.o: $(hdrdir)/ruby/internal/attr/alloc_size.h
|
||||
wait_for_single_fd.o: $(hdrdir)/ruby/internal/attr/artificial.h
|
||||
wait_for_single_fd.o: $(hdrdir)/ruby/internal/attr/cold.h
|
||||
wait_for_single_fd.o: $(hdrdir)/ruby/internal/attr/const.h
|
||||
wait_for_single_fd.o: $(hdrdir)/ruby/internal/attr/constexpr.h
|
||||
wait_for_single_fd.o: $(hdrdir)/ruby/internal/attr/deprecated.h
|
||||
wait_for_single_fd.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h
|
||||
wait_for_single_fd.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h
|
||||
wait_for_single_fd.o: $(hdrdir)/ruby/internal/attr/error.h
|
||||
wait_for_single_fd.o: $(hdrdir)/ruby/internal/attr/flag_enum.h
|
||||
wait_for_single_fd.o: $(hdrdir)/ruby/internal/attr/forceinline.h
|
||||
wait_for_single_fd.o: $(hdrdir)/ruby/internal/attr/format.h
|
||||
wait_for_single_fd.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h
|
||||
wait_for_single_fd.o: $(hdrdir)/ruby/internal/attr/noalias.h
|
||||
wait_for_single_fd.o: $(hdrdir)/ruby/internal/attr/nodiscard.h
|
||||
wait_for_single_fd.o: $(hdrdir)/ruby/internal/attr/noexcept.h
|
||||
wait_for_single_fd.o: $(hdrdir)/ruby/internal/attr/noinline.h
|
||||
wait_for_single_fd.o: $(hdrdir)/ruby/internal/attr/nonnull.h
|
||||
wait_for_single_fd.o: $(hdrdir)/ruby/internal/attr/noreturn.h
|
||||
wait_for_single_fd.o: $(hdrdir)/ruby/internal/attr/pure.h
|
||||
wait_for_single_fd.o: $(hdrdir)/ruby/internal/attr/restrict.h
|
||||
wait_for_single_fd.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
|
||||
wait_for_single_fd.o: $(hdrdir)/ruby/internal/attr/warning.h
|
||||
wait_for_single_fd.o: $(hdrdir)/ruby/internal/attr/weakref.h
|
||||
wait_for_single_fd.o: $(hdrdir)/ruby/internal/cast.h
|
||||
wait_for_single_fd.o: $(hdrdir)/ruby/internal/compiler_is.h
|
||||
wait_for_single_fd.o: $(hdrdir)/ruby/internal/compiler_is/apple.h
|
||||
wait_for_single_fd.o: $(hdrdir)/ruby/internal/compiler_is/clang.h
|
||||
wait_for_single_fd.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h
|
||||
wait_for_single_fd.o: $(hdrdir)/ruby/internal/compiler_is/intel.h
|
||||
wait_for_single_fd.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h
|
||||
wait_for_single_fd.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h
|
||||
wait_for_single_fd.o: $(hdrdir)/ruby/internal/compiler_since.h
|
||||
wait_for_single_fd.o: $(hdrdir)/ruby/internal/config.h
|
||||
wait_for_single_fd.o: $(hdrdir)/ruby/internal/constant_p.h
|
||||
wait_for_single_fd.o: $(hdrdir)/ruby/internal/core.h
|
||||
wait_for_single_fd.o: $(hdrdir)/ruby/internal/core/rarray.h
|
||||
wait_for_single_fd.o: $(hdrdir)/ruby/internal/core/rbasic.h
|
||||
wait_for_single_fd.o: $(hdrdir)/ruby/internal/core/rbignum.h
|
||||
wait_for_single_fd.o: $(hdrdir)/ruby/internal/core/rclass.h
|
||||
wait_for_single_fd.o: $(hdrdir)/ruby/internal/core/rdata.h
|
||||
wait_for_single_fd.o: $(hdrdir)/ruby/internal/core/rfile.h
|
||||
wait_for_single_fd.o: $(hdrdir)/ruby/internal/core/rhash.h
|
||||
wait_for_single_fd.o: $(hdrdir)/ruby/internal/core/robject.h
|
||||
wait_for_single_fd.o: $(hdrdir)/ruby/internal/core/rregexp.h
|
||||
wait_for_single_fd.o: $(hdrdir)/ruby/internal/core/rstring.h
|
||||
wait_for_single_fd.o: $(hdrdir)/ruby/internal/core/rstruct.h
|
||||
wait_for_single_fd.o: $(hdrdir)/ruby/internal/core/rtypeddata.h
|
||||
wait_for_single_fd.o: $(hdrdir)/ruby/internal/ctype.h
|
||||
wait_for_single_fd.o: $(hdrdir)/ruby/internal/dllexport.h
|
||||
wait_for_single_fd.o: $(hdrdir)/ruby/internal/dosish.h
|
||||
wait_for_single_fd.o: $(hdrdir)/ruby/internal/error.h
|
||||
wait_for_single_fd.o: $(hdrdir)/ruby/internal/eval.h
|
||||
wait_for_single_fd.o: $(hdrdir)/ruby/internal/event.h
|
||||
wait_for_single_fd.o: $(hdrdir)/ruby/internal/fl_type.h
|
||||
wait_for_single_fd.o: $(hdrdir)/ruby/internal/gc.h
|
||||
wait_for_single_fd.o: $(hdrdir)/ruby/internal/glob.h
|
||||
wait_for_single_fd.o: $(hdrdir)/ruby/internal/globals.h
|
||||
wait_for_single_fd.o: $(hdrdir)/ruby/internal/has/attribute.h
|
||||
wait_for_single_fd.o: $(hdrdir)/ruby/internal/has/builtin.h
|
||||
wait_for_single_fd.o: $(hdrdir)/ruby/internal/has/c_attribute.h
|
||||
wait_for_single_fd.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h
|
||||
wait_for_single_fd.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h
|
||||
wait_for_single_fd.o: $(hdrdir)/ruby/internal/has/extension.h
|
||||
wait_for_single_fd.o: $(hdrdir)/ruby/internal/has/feature.h
|
||||
wait_for_single_fd.o: $(hdrdir)/ruby/internal/has/warning.h
|
||||
wait_for_single_fd.o: $(hdrdir)/ruby/internal/intern/array.h
|
||||
wait_for_single_fd.o: $(hdrdir)/ruby/internal/intern/bignum.h
|
||||
wait_for_single_fd.o: $(hdrdir)/ruby/internal/intern/class.h
|
||||
wait_for_single_fd.o: $(hdrdir)/ruby/internal/intern/compar.h
|
||||
wait_for_single_fd.o: $(hdrdir)/ruby/internal/intern/complex.h
|
||||
wait_for_single_fd.o: $(hdrdir)/ruby/internal/intern/cont.h
|
||||
wait_for_single_fd.o: $(hdrdir)/ruby/internal/intern/dir.h
|
||||
wait_for_single_fd.o: $(hdrdir)/ruby/internal/intern/enum.h
|
||||
wait_for_single_fd.o: $(hdrdir)/ruby/internal/intern/enumerator.h
|
||||
wait_for_single_fd.o: $(hdrdir)/ruby/internal/intern/error.h
|
||||
wait_for_single_fd.o: $(hdrdir)/ruby/internal/intern/eval.h
|
||||
wait_for_single_fd.o: $(hdrdir)/ruby/internal/intern/file.h
|
||||
wait_for_single_fd.o: $(hdrdir)/ruby/internal/intern/gc.h
|
||||
wait_for_single_fd.o: $(hdrdir)/ruby/internal/intern/hash.h
|
||||
wait_for_single_fd.o: $(hdrdir)/ruby/internal/intern/io.h
|
||||
wait_for_single_fd.o: $(hdrdir)/ruby/internal/intern/load.h
|
||||
wait_for_single_fd.o: $(hdrdir)/ruby/internal/intern/marshal.h
|
||||
wait_for_single_fd.o: $(hdrdir)/ruby/internal/intern/numeric.h
|
||||
wait_for_single_fd.o: $(hdrdir)/ruby/internal/intern/object.h
|
||||
wait_for_single_fd.o: $(hdrdir)/ruby/internal/intern/parse.h
|
||||
wait_for_single_fd.o: $(hdrdir)/ruby/internal/intern/proc.h
|
||||
wait_for_single_fd.o: $(hdrdir)/ruby/internal/intern/process.h
|
||||
wait_for_single_fd.o: $(hdrdir)/ruby/internal/intern/random.h
|
||||
wait_for_single_fd.o: $(hdrdir)/ruby/internal/intern/range.h
|
||||
wait_for_single_fd.o: $(hdrdir)/ruby/internal/intern/rational.h
|
||||
wait_for_single_fd.o: $(hdrdir)/ruby/internal/intern/re.h
|
||||
wait_for_single_fd.o: $(hdrdir)/ruby/internal/intern/ruby.h
|
||||
wait_for_single_fd.o: $(hdrdir)/ruby/internal/intern/select.h
|
||||
wait_for_single_fd.o: $(hdrdir)/ruby/internal/intern/select/largesize.h
|
||||
wait_for_single_fd.o: $(hdrdir)/ruby/internal/intern/signal.h
|
||||
wait_for_single_fd.o: $(hdrdir)/ruby/internal/intern/sprintf.h
|
||||
wait_for_single_fd.o: $(hdrdir)/ruby/internal/intern/string.h
|
||||
wait_for_single_fd.o: $(hdrdir)/ruby/internal/intern/struct.h
|
||||
wait_for_single_fd.o: $(hdrdir)/ruby/internal/intern/thread.h
|
||||
wait_for_single_fd.o: $(hdrdir)/ruby/internal/intern/time.h
|
||||
wait_for_single_fd.o: $(hdrdir)/ruby/internal/intern/variable.h
|
||||
wait_for_single_fd.o: $(hdrdir)/ruby/internal/intern/vm.h
|
||||
wait_for_single_fd.o: $(hdrdir)/ruby/internal/interpreter.h
|
||||
wait_for_single_fd.o: $(hdrdir)/ruby/internal/iterator.h
|
||||
wait_for_single_fd.o: $(hdrdir)/ruby/internal/memory.h
|
||||
wait_for_single_fd.o: $(hdrdir)/ruby/internal/method.h
|
||||
wait_for_single_fd.o: $(hdrdir)/ruby/internal/module.h
|
||||
wait_for_single_fd.o: $(hdrdir)/ruby/internal/newobj.h
|
||||
wait_for_single_fd.o: $(hdrdir)/ruby/internal/rgengc.h
|
||||
wait_for_single_fd.o: $(hdrdir)/ruby/internal/scan_args.h
|
||||
wait_for_single_fd.o: $(hdrdir)/ruby/internal/special_consts.h
|
||||
wait_for_single_fd.o: $(hdrdir)/ruby/internal/static_assert.h
|
||||
wait_for_single_fd.o: $(hdrdir)/ruby/internal/stdalign.h
|
||||
wait_for_single_fd.o: $(hdrdir)/ruby/internal/stdbool.h
|
||||
wait_for_single_fd.o: $(hdrdir)/ruby/internal/symbol.h
|
||||
wait_for_single_fd.o: $(hdrdir)/ruby/internal/value.h
|
||||
wait_for_single_fd.o: $(hdrdir)/ruby/internal/value_type.h
|
||||
wait_for_single_fd.o: $(hdrdir)/ruby/internal/variable.h
|
||||
wait_for_single_fd.o: $(hdrdir)/ruby/internal/warning_push.h
|
||||
wait_for_single_fd.o: $(hdrdir)/ruby/internal/xmalloc.h
|
||||
wait_for_single_fd.o: $(hdrdir)/ruby/assert.h
|
||||
wait_for_single_fd.o: $(hdrdir)/ruby/backward.h
|
||||
wait_for_single_fd.o: $(hdrdir)/ruby/backward/2/assume.h
|
||||
wait_for_single_fd.o: $(hdrdir)/ruby/backward/2/attributes.h
|
||||
wait_for_single_fd.o: $(hdrdir)/ruby/backward/2/bool.h
|
||||
wait_for_single_fd.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h
|
||||
wait_for_single_fd.o: $(hdrdir)/ruby/backward/2/inttypes.h
|
||||
wait_for_single_fd.o: $(hdrdir)/ruby/backward/2/limits.h
|
||||
wait_for_single_fd.o: $(hdrdir)/ruby/backward/2/long_long.h
|
||||
wait_for_single_fd.o: $(hdrdir)/ruby/backward/2/stdalign.h
|
||||
wait_for_single_fd.o: $(hdrdir)/ruby/backward/2/stdarg.h
|
||||
wait_for_single_fd.o: $(hdrdir)/ruby/defines.h
|
||||
wait_for_single_fd.o: $(hdrdir)/ruby/encoding.h
|
||||
wait_for_single_fd.o: $(hdrdir)/ruby/intern.h
|
||||
wait_for_single_fd.o: $(hdrdir)/ruby/io.h
|
||||
wait_for_single_fd.o: $(hdrdir)/ruby/missing.h
|
||||
wait_for_single_fd.o: $(hdrdir)/ruby/onigmo.h
|
||||
wait_for_single_fd.o: $(hdrdir)/ruby/oniguruma.h
|
||||
wait_for_single_fd.o: $(hdrdir)/ruby/ruby.h
|
||||
wait_for_single_fd.o: $(hdrdir)/ruby/st.h
|
||||
wait_for_single_fd.o: $(hdrdir)/ruby/subst.h
|
||||
wait_for_single_fd.o: wait_for_single_fd.c
|
||||
# AUTOGENERATED DEPENDENCIES END
|
|
@ -1,8 +0,0 @@
|
|||
# frozen_string_literal: false
|
||||
case RUBY_PLATFORM when /mingw/ then
|
||||
# skip
|
||||
else
|
||||
headers = %w(sys/types.h sys/time.h sys/event.h).select { |h| have_header(h) }
|
||||
have_func('kqueue', headers)
|
||||
end
|
||||
create_makefile("-test-/wait_for_single_fd")
|
|
@ -1,94 +0,0 @@
|
|||
#include "ruby/ruby.h"
|
||||
#include "ruby/io.h"
|
||||
|
||||
static VALUE
|
||||
wait_for_single_fd(VALUE ign, VALUE fd, VALUE events, VALUE timeout)
|
||||
{
|
||||
struct timeval tv;
|
||||
struct timeval *tvp = NULL;
|
||||
int rc;
|
||||
|
||||
if (!NIL_P(timeout)) {
|
||||
tv = rb_time_timeval(timeout);
|
||||
tvp = &tv;
|
||||
}
|
||||
|
||||
rc = rb_wait_for_single_fd(NUM2INT(fd), NUM2INT(events), tvp);
|
||||
if (rc == -1)
|
||||
rb_sys_fail("rb_wait_for_single_fd");
|
||||
return INT2NUM(rc);
|
||||
}
|
||||
|
||||
#ifdef HAVE_KQUEUE
|
||||
/* ensure rb_wait_for_single_fd works on kqueue descriptors */
|
||||
#include <sys/types.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/event.h>
|
||||
static VALUE
|
||||
kqueue_test_wait(VALUE klass)
|
||||
{
|
||||
int kqfd = -1;
|
||||
int p[2] = { -1, -1 };
|
||||
struct timeval tv = { 0, 0 };
|
||||
const struct timespec ts = { 1, 0 };
|
||||
struct kevent kev;
|
||||
const char *msg;
|
||||
VALUE ret = Qfalse;
|
||||
int e = 0;
|
||||
int n;
|
||||
|
||||
msg = "pipe";
|
||||
if (rb_cloexec_pipe(p) < 0) goto err;
|
||||
|
||||
msg = "kqueue";
|
||||
kqfd = kqueue();
|
||||
if (kqfd < 0) goto err;
|
||||
|
||||
n = rb_wait_for_single_fd(kqfd, RB_WAITFD_IN, &tv);
|
||||
if (n != 0) {
|
||||
msg = "spurious wakeup";
|
||||
errno = 0;
|
||||
goto err;
|
||||
}
|
||||
|
||||
msg = "write";
|
||||
if (write(p[1], "", 1) < 0) goto err;
|
||||
|
||||
EV_SET(&kev, p[0], EVFILT_READ, EV_ADD, 0, 0, 0);
|
||||
|
||||
msg = "kevent";
|
||||
n = kevent(kqfd, &kev, 1, &kev, 1, &ts);
|
||||
if (n < 0) goto err;
|
||||
msg = NULL;
|
||||
if (n == 1) {
|
||||
n = rb_wait_for_single_fd(kqfd, RB_WAITFD_IN, &tv);
|
||||
ret = INT2NUM(n);
|
||||
}
|
||||
else {
|
||||
rb_warn("kevent did not return readiness");
|
||||
}
|
||||
err:
|
||||
if (msg) e = errno;
|
||||
if (p[0] >= 0) close(p[0]);
|
||||
if (p[1] >= 0) close(p[1]);
|
||||
if (kqfd >= 0) close(kqfd);
|
||||
if (msg) {
|
||||
if (e) rb_syserr_fail(e, msg);
|
||||
rb_raise(rb_eRuntimeError, "%s", msg);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
#endif /* HAVE_KQUEUE */
|
||||
|
||||
void
|
||||
Init_wait_for_single_fd(void)
|
||||
{
|
||||
rb_define_const(rb_cObject, "RB_WAITFD_IN", INT2NUM(RB_WAITFD_IN));
|
||||
rb_define_const(rb_cObject, "RB_WAITFD_OUT", INT2NUM(RB_WAITFD_OUT));
|
||||
rb_define_const(rb_cObject, "RB_WAITFD_PRI", INT2NUM(RB_WAITFD_PRI));
|
||||
rb_define_singleton_method(rb_cIO, "wait_for_single_fd",
|
||||
wait_for_single_fd, 3);
|
||||
#ifdef HAVE_KQUEUE
|
||||
rb_define_singleton_method(rb_cIO, "kqueue_test_wait", kqueue_test_wait, 0);
|
||||
#endif
|
||||
}
|
|
@ -1639,12 +1639,12 @@ ossl_start_ssl(VALUE self, int (*func)(), const char *funcname, VALUE opts)
|
|||
case SSL_ERROR_WANT_WRITE:
|
||||
if (no_exception_p(opts)) { return sym_wait_writable; }
|
||||
write_would_block(nonblock);
|
||||
rb_io_wait_writable(fptr->fd);
|
||||
rb_io_maybe_wait_writable(errno, fptr->self, Qnil);
|
||||
continue;
|
||||
case SSL_ERROR_WANT_READ:
|
||||
if (no_exception_p(opts)) { return sym_wait_readable; }
|
||||
read_would_block(nonblock);
|
||||
rb_io_wait_readable(fptr->fd);
|
||||
rb_io_maybe_wait_readable(errno, fptr->self, Qnil);
|
||||
continue;
|
||||
case SSL_ERROR_SYSCALL:
|
||||
#ifdef __APPLE__
|
||||
|
@ -1819,12 +1819,12 @@ ossl_ssl_read_internal(int argc, VALUE *argv, VALUE self, int nonblock)
|
|||
case SSL_ERROR_WANT_WRITE:
|
||||
if (no_exception_p(opts)) { return sym_wait_writable; }
|
||||
write_would_block(nonblock);
|
||||
rb_io_wait_writable(fptr->fd);
|
||||
rb_io_maybe_wait_writable(errno, fptr->self, Qnil);
|
||||
continue;
|
||||
case SSL_ERROR_WANT_READ:
|
||||
if (no_exception_p(opts)) { return sym_wait_readable; }
|
||||
read_would_block(nonblock);
|
||||
rb_io_wait_readable(fptr->fd);
|
||||
rb_io_maybe_wait_readable(errno, fptr->self, Qnil);
|
||||
continue;
|
||||
case SSL_ERROR_SYSCALL:
|
||||
if (!ERR_peek_error()) {
|
||||
|
@ -1935,12 +1935,12 @@ ossl_ssl_write_internal(VALUE self, VALUE str, VALUE opts)
|
|||
case SSL_ERROR_WANT_WRITE:
|
||||
if (no_exception_p(opts)) { return sym_wait_writable; }
|
||||
write_would_block(nonblock);
|
||||
rb_io_wait_writable(fptr->fd);
|
||||
rb_io_maybe_wait_writable(errno, fptr->self, Qnil);
|
||||
continue;
|
||||
case SSL_ERROR_WANT_READ:
|
||||
if (no_exception_p(opts)) { return sym_wait_readable; }
|
||||
read_would_block(nonblock);
|
||||
rb_io_wait_readable(fptr->fd);
|
||||
rb_io_maybe_wait_readable(errno, fptr->self, Qnil);
|
||||
continue;
|
||||
case SSL_ERROR_SYSCALL:
|
||||
#ifdef __APPLE__
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -31,8 +31,8 @@ struct timeval;
|
|||
|
||||
/* thread.c */
|
||||
void rb_thread_schedule(void);
|
||||
void rb_thread_wait_fd(int);
|
||||
int rb_thread_fd_writable(int);
|
||||
#define rb_thread_wait_fd(fd) rb_wait_for_single_fd((fd), RUBY_IO_READABLE, NULL)
|
||||
#define rb_thread_fd_writable(fd) rb_wait_for_single_fd((fd), RUBY_IO_WRITABLE, NULL)
|
||||
void rb_thread_fd_close(int);
|
||||
int rb_thread_alone(void);
|
||||
void rb_thread_sleep(int);
|
||||
|
|
|
@ -154,8 +154,13 @@ int rb_io_extract_encoding_option(VALUE opt, rb_encoding **enc_p, rb_encoding **
|
|||
void rb_io_extract_modeenc(VALUE *vmode_p, VALUE *vperm_p, VALUE opthash, int *oflags_p, int *fmode_p, rb_io_enc_t *convconfig_p);
|
||||
ssize_t rb_io_bufwrite(VALUE io, const void *buf, size_t size);
|
||||
|
||||
RBIMPL_ATTR_DEPRECATED(("use rb_io_maybe_wait_readable"))
|
||||
int rb_io_wait_readable(int fd);
|
||||
|
||||
RBIMPL_ATTR_DEPRECATED(("use rb_io_maybe_wait_writable"))
|
||||
int rb_io_wait_writable(int fd);
|
||||
|
||||
RBIMPL_ATTR_DEPRECATED(("use rb_io_wait"))
|
||||
int rb_wait_for_single_fd(int fd, int events, struct timeval *tv);
|
||||
|
||||
VALUE rb_io_wait(VALUE io, VALUE events, VALUE timeout);
|
||||
|
|
82
io.c
82
io.c
|
@ -492,7 +492,7 @@ rb_cloexec_fcntl_dupfd(int fd, int minfd)
|
|||
|
||||
#if defined(_WIN32)
|
||||
#define WAIT_FD_IN_WIN32(fptr) \
|
||||
(rb_w32_io_cancelable_p((fptr)->fd) ? 0 : rb_thread_wait_fd((fptr)->fd))
|
||||
(rb_w32_io_cancelable_p((fptr)->fd) ? 0 : RB_NUM2INT(rb_io_wait(fptr->self, RB_INT2NUM(RUBY_IO_READABLE), Qnil)))
|
||||
#else
|
||||
#define WAIT_FD_IN_WIN32(fptr)
|
||||
#endif
|
||||
|
@ -998,7 +998,7 @@ void
|
|||
rb_io_read_check(rb_io_t *fptr)
|
||||
{
|
||||
if (!READ_DATA_PENDING(fptr)) {
|
||||
rb_thread_wait_fd(fptr->fd);
|
||||
rb_io_wait(fptr->self, RB_INT2NUM(RUBY_IO_READABLE), Qnil);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
@ -1248,13 +1248,17 @@ static int
|
|||
io_fflush(rb_io_t *fptr)
|
||||
{
|
||||
rb_io_check_closed(fptr);
|
||||
|
||||
if (fptr->wbuf.len == 0)
|
||||
return 0;
|
||||
|
||||
while (fptr->wbuf.len > 0 && io_flush_buffer(fptr) != 0) {
|
||||
if (!rb_io_wait_writable(fptr->fd))
|
||||
return -1;
|
||||
if (!rb_io_maybe_wait_writable(errno, fptr->self, Qnil))
|
||||
return -1;
|
||||
|
||||
rb_io_check_closed(fptr);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1296,11 +1300,25 @@ rb_io_wait(VALUE io, VALUE events, VALUE timeout)
|
|||
}
|
||||
|
||||
static VALUE
|
||||
rb_io_from_fd(int fd)
|
||||
io_from_fd(int fd)
|
||||
{
|
||||
return prep_io(fd, FMODE_PREP, rb_cIO, NULL);
|
||||
}
|
||||
|
||||
static
|
||||
int io_wait_for_single_fd(int fd, int events, struct timeval *timeout)
|
||||
{
|
||||
VALUE scheduler = rb_fiber_scheduler_current();
|
||||
|
||||
if (scheduler != Qnil) {
|
||||
return RTEST(
|
||||
rb_fiber_scheduler_io_wait(scheduler, io_from_fd(fd), RB_INT2NUM(events), rb_fiber_scheduler_make_timeout(timeout))
|
||||
);
|
||||
}
|
||||
|
||||
return rb_thread_wait_for_single_fd(fd, events, timeout);
|
||||
}
|
||||
|
||||
int
|
||||
rb_io_wait_readable(int f)
|
||||
{
|
||||
|
@ -1322,11 +1340,11 @@ rb_io_wait_readable(int f)
|
|||
#endif
|
||||
if (scheduler != Qnil) {
|
||||
return RTEST(
|
||||
rb_fiber_scheduler_io_wait_readable(scheduler, rb_io_from_fd(f))
|
||||
rb_fiber_scheduler_io_wait_readable(scheduler, io_from_fd(f))
|
||||
);
|
||||
}
|
||||
else {
|
||||
rb_thread_wait_fd(f);
|
||||
io_wait_for_single_fd(f, RUBY_IO_READABLE, NULL);
|
||||
}
|
||||
return TRUE;
|
||||
|
||||
|
@ -1365,11 +1383,11 @@ rb_io_wait_writable(int f)
|
|||
#endif
|
||||
if (scheduler != Qnil) {
|
||||
return RTEST(
|
||||
rb_fiber_scheduler_io_wait_writable(scheduler, rb_io_from_fd(f))
|
||||
rb_fiber_scheduler_io_wait_writable(scheduler, io_from_fd(f))
|
||||
);
|
||||
}
|
||||
else {
|
||||
rb_thread_fd_writable(f);
|
||||
io_wait_for_single_fd(f, RUBY_IO_WRITABLE, NULL);
|
||||
}
|
||||
return TRUE;
|
||||
|
||||
|
@ -1381,20 +1399,19 @@ rb_io_wait_writable(int f)
|
|||
int
|
||||
rb_wait_for_single_fd(int fd, int events, struct timeval *timeout)
|
||||
{
|
||||
VALUE scheduler = rb_fiber_scheduler_current();
|
||||
|
||||
if (scheduler != Qnil) {
|
||||
return RTEST(
|
||||
rb_fiber_scheduler_io_wait(scheduler, rb_io_from_fd(fd), RB_INT2NUM(events), rb_fiber_scheduler_make_timeout(timeout))
|
||||
);
|
||||
}
|
||||
|
||||
return rb_thread_wait_for_single_fd(fd, events, timeout);
|
||||
return io_wait_for_single_fd(fd, events, timeout);
|
||||
}
|
||||
|
||||
VALUE rb_io_maybe_wait(int error, VALUE io, VALUE events, VALUE timeout)
|
||||
{
|
||||
switch (error) {
|
||||
// In old Linux, several special files under /proc and /sys don't handle
|
||||
// select properly. Thus we need avoid to call if don't use O_NONBLOCK.
|
||||
// Otherwise, we face nasty hang up. Sigh.
|
||||
// e.g. http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=31b07093c44a7a442394d44423e21d783f5523b8
|
||||
// http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=31b07093c44a7a442394d44423e21d783f5523b8
|
||||
// In EINTR case, we only need to call RUBY_VM_CHECK_INTS_BLOCKING().
|
||||
// Then rb_thread_check_ints() is enough.
|
||||
case EINTR:
|
||||
#if defined(ERESTART)
|
||||
case ERESTART:
|
||||
|
@ -1561,9 +1578,6 @@ io_binwrite_string(VALUE arg)
|
|||
return len;
|
||||
}
|
||||
|
||||
if (fptr->stdio_file != stderr && !rb_thread_fd_writable(fptr->fd))
|
||||
rb_io_check_closed(fptr);
|
||||
|
||||
return rb_write_internal(p->fptr->fd, p->ptr, p->length);
|
||||
}
|
||||
#endif
|
||||
|
@ -1623,7 +1637,7 @@ io_binwrite(VALUE str, const char *ptr, long len, rb_io_t *fptr, int nosync)
|
|||
}
|
||||
if (r == -2L)
|
||||
return -1L;
|
||||
if (rb_io_wait_writable(fptr->fd)) {
|
||||
if (rb_io_maybe_wait_writable(errno, fptr->self, Qnil)) {
|
||||
rb_io_check_closed(fptr);
|
||||
if (offset < len)
|
||||
goto retry;
|
||||
|
@ -1861,7 +1875,7 @@ io_binwritev(struct iovec *iov, int iovcnt, rb_io_t *fptr)
|
|||
|
||||
errno = EAGAIN;
|
||||
}
|
||||
if (rb_io_wait_writable(fptr->fd)) {
|
||||
if (rb_io_maybe_wait_writable(errno, fptr->self, Qnil)) {
|
||||
rb_io_check_closed(fptr);
|
||||
goto retry;
|
||||
}
|
||||
|
@ -2250,7 +2264,7 @@ rb_io_rewind(VALUE io)
|
|||
static int
|
||||
fptr_wait_readable(rb_io_t *fptr)
|
||||
{
|
||||
int ret = rb_io_wait_readable(fptr->fd);
|
||||
int ret = rb_io_maybe_wait_readable(errno, fptr->self, Qnil);
|
||||
|
||||
if (ret)
|
||||
rb_io_check_closed(fptr);
|
||||
|
@ -4689,7 +4703,7 @@ finish_writeconv(rb_io_t *fptr, int noalloc)
|
|||
if (0 <= r) {
|
||||
ds += r;
|
||||
}
|
||||
if (rb_io_wait_writable(fptr->fd)) {
|
||||
if (rb_io_maybe_wait_writable(errno, fptr->self, Qnil)) {
|
||||
if (fptr->fd < 0)
|
||||
return noalloc ? Qtrue : rb_exc_new3(rb_eIOError, rb_str_new_cstr(closed_stream));
|
||||
goto retry;
|
||||
|
@ -5332,7 +5346,7 @@ rb_io_sysread(int argc, VALUE *argv, VALUE io)
|
|||
rb_io_check_byte_readable(fptr);
|
||||
|
||||
if (READ_DATA_BUFFERED(fptr)) {
|
||||
rb_raise(rb_eIOError, "sysread for buffered IO");
|
||||
rb_raise(rb_eIOError, "sysread for buffered IO");
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -5342,7 +5356,7 @@ rb_io_sysread(int argc, VALUE *argv, VALUE io)
|
|||
* the IO after we return from rb_thread_wait_fd() but before
|
||||
* we call read()
|
||||
*/
|
||||
rb_thread_wait_fd(fptr->fd);
|
||||
rb_io_wait(fptr->self, RB_INT2NUM(RUBY_IO_READABLE), Qnil);
|
||||
|
||||
rb_io_check_closed(fptr);
|
||||
|
||||
|
@ -11104,7 +11118,7 @@ rb_thread_fiber_scheduler_wait_for_single_fd(void * _args)
|
|||
{
|
||||
struct wait_for_single_fd *args = (struct wait_for_single_fd *)_args;
|
||||
|
||||
args->result = rb_fiber_scheduler_io_wait(args->scheduler, rb_io_from_fd(args->fd), INT2NUM(args->events), Qnil);
|
||||
args->result = rb_fiber_scheduler_io_wait(args->scheduler, io_from_fd(args->fd), INT2NUM(args->events), Qnil);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
@ -11170,12 +11184,12 @@ maygvl_copy_stream_wait_read(int has_gvl, struct copy_stream_struct *stp)
|
|||
int ret;
|
||||
|
||||
do {
|
||||
if (has_gvl) {
|
||||
ret = rb_wait_for_single_fd(stp->src_fd, RB_WAITFD_IN, NULL);
|
||||
}
|
||||
else {
|
||||
ret = nogvl_wait_for_single_fd(stp->th, stp->src_fd, RB_WAITFD_IN);
|
||||
}
|
||||
if (has_gvl) {
|
||||
ret = RB_NUM2INT(rb_io_wait(stp->src, RB_INT2NUM(RUBY_IO_READABLE), Qnil));
|
||||
}
|
||||
else {
|
||||
ret = nogvl_wait_for_single_fd(stp->th, stp->src_fd, RB_WAITFD_IN);
|
||||
}
|
||||
} while (ret < 0 && maygvl_copy_stream_continue_p(has_gvl, stp));
|
||||
|
||||
if (ret < 0) {
|
||||
|
|
2
ruby.c
2
ruby.c
|
@ -2305,7 +2305,7 @@ open_load_file(VALUE fname_v, int *xflag)
|
|||
We need to wait if FIFO is empty. It's FIFO's semantics.
|
||||
rb_thread_wait_fd() release GVL. So, it's safe.
|
||||
*/
|
||||
rb_thread_wait_fd(fd);
|
||||
rb_io_wait(f, RB_INT2NUM(RUBY_IO_READABLE), Qnil);
|
||||
}
|
||||
}
|
||||
return f;
|
||||
|
|
33
thread.c
33
thread.c
|
@ -4296,39 +4296,6 @@ do_select(VALUE p)
|
|||
return (VALUE)result;
|
||||
}
|
||||
|
||||
static void
|
||||
rb_thread_wait_fd_rw(int fd, int read)
|
||||
{
|
||||
int result = 0;
|
||||
int events = read ? RB_WAITFD_IN : RB_WAITFD_OUT;
|
||||
|
||||
thread_debug("rb_thread_wait_fd_rw(%d, %s)\n", fd, read ? "read" : "write");
|
||||
|
||||
if (fd < 0) {
|
||||
rb_raise(rb_eIOError, "closed stream");
|
||||
}
|
||||
|
||||
result = rb_wait_for_single_fd(fd, events, NULL);
|
||||
if (result < 0) {
|
||||
rb_sys_fail(0);
|
||||
}
|
||||
|
||||
thread_debug("rb_thread_wait_fd_rw(%d, %s): done\n", fd, read ? "read" : "write");
|
||||
}
|
||||
|
||||
void
|
||||
rb_thread_wait_fd(int fd)
|
||||
{
|
||||
rb_thread_wait_fd_rw(fd, 1);
|
||||
}
|
||||
|
||||
int
|
||||
rb_thread_fd_writable(int fd)
|
||||
{
|
||||
rb_thread_wait_fd_rw(fd, 0);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static rb_fdset_t *
|
||||
init_set_fd(int fd, rb_fdset_t *fds)
|
||||
{
|
||||
|
|
Загрузка…
Ссылка в новой задаче