Feature #16597 » 0002-io-add-additional-argument-to-fd_select-calls.patch
| include/ruby/internal/intern/select/largesize.h | ||
|---|---|---|
|
int rb_fd_isset(int, const rb_fdset_t *);
|
||
|
void rb_fd_copy(rb_fdset_t *, const fd_set *, int);
|
||
|
void rb_fd_dup(rb_fdset_t *dst, const rb_fdset_t *src);
|
||
|
int rb_fd_select(int, rb_fdset_t *, rb_fdset_t *, rb_fdset_t *, struct timeval *);
|
||
|
int rb_fd_select(int, rb_fdset_t *, rb_fdset_t *, rb_fdset_t *, rb_fdset_t *, struct timeval *);
|
||
|
RBIMPL_SYMBOL_EXPORT_END()
|
||
|
RBIMPL_ATTR_NONNULL(())
|
||
| include/ruby/internal/intern/select/win32.h | ||
|---|---|---|
|
}
|
||
|
static inline int
|
||
|
rb_fd_select(int n, rb_fdset_t *rfds, rb_fdset_t *wfds, rb_fdset_t *efds, struct timeval *timeout)
|
||
|
rb_fd_select(int n, rb_fdset_t *rfds, rb_fdset_t *wfds, rb_fdset_t *efds, rb_fdset_t *errfds, struct timeval *timeout)
|
||
|
{
|
||
|
return rb_w32_select(
|
||
|
n,
|
||
| io.c | ||
|---|---|---|
|
select_internal(VALUE read, VALUE write, VALUE except, struct timeval *tp, rb_fdset_t *fds)
|
||
|
{
|
||
|
VALUE res, list;
|
||
|
rb_fdset_t *rp, *wp, *ep;
|
||
|
rb_fdset_t *rp, *wp, *ep, *erp;
|
||
|
rb_io_t *fptr;
|
||
|
long i;
|
||
|
int max = 0, n;
|
||
| ... | ... | |
|
ep = 0;
|
||
|
}
|
||
|
erp = 0;
|
||
|
max++;
|
||
|
n = rb_thread_fd_select(max, rp, wp, ep, tp);
|
||
|
n = rb_thread_fd_select(max, rp, wp, ep, erp, tp);
|
||
|
if (n < 0) {
|
||
|
rb_sys_fail(0);
|
||
|
}
|
||
| ... | ... | |
|
}
|
||
|
struct select_args {
|
||
|
VALUE read, write, except;
|
||
|
VALUE read, write, except, error;
|
||
|
struct timeval *timeout;
|
||
|
rb_fdset_t fdsets[4];
|
||
|
rb_fdset_t fdsets[5];
|
||
|
};
|
||
|
static VALUE
|
||
| ... | ... | |
|
int i;
|
||
|
rb_scan_args(argc, argv, "13", &args.read, &args.write, &args.except, &timeout);
|
||
|
args.error = Qnil;
|
||
|
if (NIL_P(timeout)) {
|
||
|
args.timeout = 0;
|
||
|
}
|
||
| ... | ... | |
|
switch (events) {
|
||
|
case RB_WAITFD_IN:
|
||
|
ret = rb_fd_select(fd + 1, &fds, 0, 0, 0);
|
||
|
ret = rb_fd_select(fd + 1, &fds, 0, 0, 0, 0);
|
||
|
break;
|
||
|
case RB_WAITFD_OUT:
|
||
|
ret = rb_fd_select(fd + 1, 0, &fds, 0, 0);
|
||
|
ret = rb_fd_select(fd + 1, 0, &fds, 0, 0, 0);
|
||
|
break;
|
||
|
default:
|
||
|
VM_UNREACHABLE(nogvl_wait_for_single_fd);
|
||
| thread.c | ||
|---|---|---|
|
}
|
||
|
int
|
||
|
rb_fd_select(int n, rb_fdset_t *readfds, rb_fdset_t *writefds, rb_fdset_t *exceptfds, struct timeval *timeout)
|
||
|
rb_fd_select(int n, rb_fdset_t *readfds, rb_fdset_t *writefds, rb_fdset_t *exceptfds, rb_fdset_t *errorfds, struct timeval *timeout)
|
||
|
{
|
||
|
fd_set *r = NULL, *w = NULL, *e = NULL;
|
||
|
if (readfds) {
|
||
| ... | ... | |
|
rb_fd_resize(n - 1, exceptfds);
|
||
|
e = rb_fd_ptr(exceptfds);
|
||
|
}
|
||
|
if (errorfds)
|
||
|
rb_fd_zero(errorfds);
|
||
|
return select(n, r, w, e, timeout);
|
||
|
}
|
||
| ... | ... | |
|
rb_fdset_t *rset;
|
||
|
rb_fdset_t *wset;
|
||
|
rb_fdset_t *eset;
|
||
|
rb_fdset_t *errset;
|
||
|
rb_fdset_t orig_rset;
|
||
|
rb_fdset_t orig_wset;
|
||
|
rb_fdset_t orig_eset;
|
||
|
rb_fdset_t orig_errset;
|
||
|
struct timeval *timeout;
|
||
|
};
|
||
| ... | ... | |
|
rb_fd_term(&set->orig_rset);
|
||
|
rb_fd_term(&set->orig_wset);
|
||
|
rb_fd_term(&set->orig_eset);
|
||
|
rb_fd_term(&set->orig_errset);
|
||
|
return Qfalse;
|
||
|
}
|
||
| ... | ... | |
|
(restore_fdset(set->rset, &set->orig_rset), \
|
||
|
restore_fdset(set->wset, &set->orig_wset), \
|
||
|
restore_fdset(set->eset, &set->orig_eset), \
|
||
|
restore_fdset(set->errset, &set->orig_errset), \
|
||
|
TRUE)
|
||
|
do {
|
||
| ... | ... | |
|
sto = sigwait_timeout(set->th, set->sigwait_fd, to, &drained);
|
||
|
if (!RUBY_VM_INTERRUPTED(set->th->ec)) {
|
||
|
result = native_fd_select(set->max, set->rset, set->wset,
|
||
|
set->eset,
|
||
|
set->eset, set->errset,
|
||
|
rb_hrtime2timeval(&tv, sto), set->th);
|
||
|
if (result < 0) lerrno = errno;
|
||
|
}
|
||
| ... | ... | |
|
int
|
||
|
rb_thread_fd_select(int max, rb_fdset_t * read, rb_fdset_t * write, rb_fdset_t * except,
|
||
|
struct timeval *timeout)
|
||
|
rb_fdset_t * error, struct timeval *timeout)
|
||
|
{
|
||
|
struct select_set set;
|
||
| ... | ... | |
|
set.rset = read;
|
||
|
set.wset = write;
|
||
|
set.eset = except;
|
||
|
set.errset = error;
|
||
|
set.timeout = timeout;
|
||
|
if (!set.rset && !set.wset && !set.eset) {
|
||
|
if (!set.rset && !set.wset && !set.eset && !set.errset) {
|
||
|
if (!timeout) {
|
||
|
rb_thread_sleep_forever();
|
||
|
return 0;
|
||
| ... | ... | |
|
fd_init_copy(rset);
|
||
|
fd_init_copy(wset);
|
||
|
fd_init_copy(eset);
|
||
|
fd_init_copy(errset);
|
||
|
#undef fd_init_copy
|
||
|
return (int)rb_ensure(do_select, (VALUE)&set, select_set_free, (VALUE)&set);
|
||
| ... | ... | |
|
rb_fdset_t *read;
|
||
|
rb_fdset_t *write;
|
||
|
rb_fdset_t *except;
|
||
|
rb_fdset_t *error;
|
||
|
struct waiting_fd wfd;
|
||
|
struct timeval *tv;
|
||
|
};
|
||
| ... | ... | |
|
int r;
|
||
|
r = rb_thread_fd_select(args->as.fd + 1,
|
||
|
args->read, args->write, args->except, args->tv);
|
||
|
args->read, args->write, args->except, args->error, args->tv);
|
||
|
if (r == -1)
|
||
|
args->as.error = errno;
|
||
|
if (r > 0) {
|
||
| ... | ... | |
|
r |= RB_WAITFD_OUT;
|
||
|
if (args->except && rb_fd_isset(args->as.fd, args->except))
|
||
|
r |= RB_WAITFD_PRI;
|
||
|
if (args->error && rb_fd_isset(args->as.fd, args->error))
|
||
|
r |= RB_WAITFD_ERR;
|
||
|
}
|
||
|
return (VALUE)r;
|
||
|
}
|
||
| ... | ... | |
|
if (args->read) rb_fd_term(args->read);
|
||
|
if (args->write) rb_fd_term(args->write);
|
||
|
if (args->except) rb_fd_term(args->except);
|
||
|
if (args->error) rb_fd_term(args->error);
|
||
|
return (VALUE)-1;
|
||
|
}
|
||
| ... | ... | |
|
return RTEST(result);
|
||
|
}
|
||
|
rb_fdset_t rfds, wfds, efds;
|
||
|
rb_fdset_t rfds, wfds, efds, errfds;
|
||
|
struct select_args args;
|
||
|
int r;
|
||
|
VALUE ptr = (VALUE)&args;
|
||
| ... | ... | |
|
args.read = (events & RB_WAITFD_IN) ? init_set_fd(fd, &rfds) : NULL;
|
||
|
args.write = (events & RB_WAITFD_OUT) ? init_set_fd(fd, &wfds) : NULL;
|
||
|
args.except = (events & RB_WAITFD_PRI) ? init_set_fd(fd, &efds) : NULL;
|
||
|
args.error = (events & RB_WAITFD_ERR) ? init_set_fd(fd, &errfds) : NULL;
|
||
|
args.tv = timeout;
|
||
|
args.wfd.fd = fd;
|
||
|
args.wfd.th = GET_THREAD();
|
||
| thread_pthread.c | ||
|---|---|---|
|
#endif /* USE_NATIVE_THREAD_PRIORITY */
|
||
|
static int
|
||
|
native_fd_select(int n, rb_fdset_t *readfds, rb_fdset_t *writefds, rb_fdset_t *exceptfds, struct timeval *timeout, rb_thread_t *th)
|
||
|
native_fd_select(int n, rb_fdset_t *readfds, rb_fdset_t *writefds, rb_fdset_t *exceptfds, rb_fdset_t *errorfds, struct timeval *timeout, rb_thread_t *th)
|
||
|
{
|
||
|
return rb_fd_select(n, readfds, writefds, exceptfds, timeout);
|
||
|
return rb_fd_select(n, readfds, writefds, exceptfds, errorfds, timeout);
|
||
|
}
|
||
|
static void
|
||