Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
home:michals
ruby2.7
0010-select_with_poll-do-not-reaise-exception-o...
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File 0010-select_with_poll-do-not-reaise-exception-on-bad-fd.patch of Package ruby2.7
From 3db7e065d72b443d8fe5a18e6a08f9f8c277cf1e Mon Sep 17 00:00:00 2001 From: Michal Suchanek <msuchanek@suse.de> Date: Wed, 4 Mar 2020 23:34:09 +0100 Subject: [PATCH 10/12] select_with_poll: do not reaise exception on bad fd. poll() returns an error for each bad descriptor rather than one global error. FOrward the information to user. Signed-off-by: Michal Suchanek <msuchanek@suse.de> --- include/ruby/intern.h | 8 ++++---- include/ruby/io.h | 2 +- internal.h | 2 +- io.c | 26 ++++++++++++++------------ thread.c | 20 +++++++++++++------- thread_pthread.c | 4 ++-- thread_win32.c | 3 ++- 7 files changed, 37 insertions(+), 28 deletions(-) diff --git a/include/ruby/intern.h b/include/ruby/intern.h index 6bb4fa03a21b..874c13a3e8d9 100644 --- a/include/ruby/intern.h +++ b/include/ruby/intern.h @@ -362,7 +362,7 @@ void rb_fd_copy(rb_fdset_t *, const fd_set *, int); void rb_fd_dup(rb_fdset_t *dst, const rb_fdset_t *src); struct timeval; -int rb_fd_select(int, rb_fdset_t *, 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 *, _Bool); #define rb_fd_ptr(f) ((f)->fdset) #define rb_fd_max(f) ((f)->maxfd) @@ -385,7 +385,7 @@ void rb_w32_fd_copy(rb_fdset_t *, const fd_set *, int); #define rb_fd_dup(d, s) rb_w32_fd_dup((d), (s)) void rb_w32_fd_dup(rb_fdset_t *dst, const rb_fdset_t *src); static inline int -rb_fd_select(int n, rb_fdset_t *rfds, rb_fdset_t *wfds, rb_fdset_t *efds, rb_fdset_t *errfds, 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, _Bool select_iface) { return rb_w32_select(n, rfds ? rfds->fdset : NULL, @@ -413,7 +413,7 @@ typedef fd_set rb_fdset_t; #define rb_fd_init_copy(d, s) (*(d) = *(s)) #define rb_fd_term(f) ((void)(f)) #define rb_fd_max(f) FD_SETSIZE -#define rb_fd_select(n, rfds, wfds, efds, errfds, timeout) select((n), (rfds), (wfds), (efds), (timeout)) +#define rb_fd_select(n, rfds, wfds, efds, errfds, timeout, select_iface) select((n), (rfds), (wfds), (efds), (timeout)) #endif @@ -499,7 +499,7 @@ VALUE rb_thread_wakeup_alive(VALUE); VALUE rb_thread_run(VALUE); VALUE rb_thread_kill(VALUE); VALUE rb_thread_create(VALUE (*)(void *), void*); -int rb_thread_fd_select(int, rb_fdset_t *, rb_fdset_t *, rb_fdset_t *, rb_fdset_t *, struct timeval *); +int rb_thread_fd_select(int, rb_fdset_t *, rb_fdset_t *, rb_fdset_t *, rb_fdset_t *, struct timeval *, _Bool); void rb_thread_wait_for(struct timeval); VALUE rb_thread_current(void); VALUE rb_thread_main(void); diff --git a/include/ruby/io.h b/include/ruby/io.h index 978fec62c011..111614bc101b 100644 --- a/include/ruby/io.h +++ b/include/ruby/io.h @@ -47,7 +47,7 @@ extern "C" { # define RB_WAITFD_IN POLLIN # define RB_WAITFD_PRI POLLPRI # define RB_WAITFD_OUT POLLOUT -# define RB_WAITFD_ERR (POLLHUP|POLLERR) +# define RB_WAITFD_ERR (POLLHUP|POLLERR|POLLNVAL) #else # define RB_WAITFD_IN 0x001 # define RB_WAITFD_PRI 0x002 diff --git a/internal.h b/internal.h index fff0a7a0d03d..f433a40dc5d8 100644 --- a/internal.h +++ b/internal.h @@ -141,7 +141,7 @@ extern "C" { #define POLLIN_SET (POLLRDNORM | POLLRDBAND | POLLIN) #define POLLOUT_SET (POLLWRBAND | POLLWRNORM | POLLOUT) #define POLLEX_SET (POLLPRI) -#define POLLERR_SET (POLLHUP | POLLERR) +#define POLLERR_SET (POLLHUP | POLLERR | POLLNVAL) #endif /*! diff --git a/io.c b/io.c index 9f1e72a1a2f2..bee9e9b92af9 100644 --- a/io.c +++ b/io.c @@ -9080,7 +9080,7 @@ rb_f_backquote(VALUE obj, VALUE str) #endif static VALUE -select_internal(VALUE read, VALUE write, VALUE except, VALUE error, struct timeval *tp, rb_fdset_t *fds) +select_internal(VALUE read, VALUE write, VALUE except, VALUE error, struct timeval *tp, bool select_iface, rb_fdset_t *fds) { VALUE res, list; rb_fdset_t *rp, *wp, *ep, *erp; @@ -9143,7 +9143,7 @@ select_internal(VALUE read, VALUE write, VALUE except, VALUE error, struct timev ep = 0; } - if (!NIL_P(error)) { + if (!NIL_P(error) && !select_iface) { Check_Type(error, T_ARRAY); for (i=0; i<RARRAY_LEN(error); i++) { VALUE io = rb_io_get_io(RARRAY_AREF(error, i)); @@ -9165,7 +9165,7 @@ select_internal(VALUE read, VALUE write, VALUE except, VALUE error, struct timev max++; - n = rb_thread_fd_select(max, rp, wp, ep, erp, tp); + n = rb_thread_fd_select(max, rp, wp, ep, erp, tp, select_iface); if (n < 0) { rb_sys_fail(0); } @@ -9175,7 +9175,8 @@ select_internal(VALUE read, VALUE write, VALUE except, VALUE error, struct timev rb_ary_push(res, rp?rb_ary_new():rb_ary_new2(0)); rb_ary_push(res, wp?rb_ary_new():rb_ary_new2(0)); rb_ary_push(res, ep?rb_ary_new():rb_ary_new2(0)); - rb_ary_push(res, erp?rb_ary_new():rb_ary_new2(0)); + if (!select_iface) + rb_ary_push(res, erp?rb_ary_new():rb_ary_new2(0)); if (rp) { list = RARRAY_AREF(res, 0); @@ -9247,6 +9248,7 @@ select_internal(VALUE read, VALUE write, VALUE except, VALUE error, struct timev struct select_args { VALUE read, write, except, error; struct timeval *timeout; + bool select_iface; rb_fdset_t fdsets[5]; }; @@ -9255,7 +9257,7 @@ select_call(VALUE arg) { struct select_args *p = (struct select_args *)arg; - return select_internal(p->read, p->write, p->except, p->error, p->timeout, p->fdsets); + return select_internal(p->read, p->write, p->except, p->error, p->timeout, p->select_iface, p->fdsets); } static VALUE @@ -9463,8 +9465,9 @@ rb_io_advise(int argc, VALUE *argv, VALUE io) * * On systems that support poll(2) system call IO.select_with_poll is provided * which takes and returns extra array of descriptors. Descriptors in this - * extra array and all other arrays are checked for error conditions - - * typically the other side closing the pipe or socket. + * extra array are checked for error conditions - typically the other side + * closing the pipe or socket. Descriptors returned in fourth array instead of + * raising Errno::EBADF. * * IO.select peeks the buffer of IO objects for testing readability. * If the IO buffer is not empty, IO.select immediately notifies @@ -9603,21 +9606,20 @@ rb_f_select_with_poll(int argc, VALUE *argv, VALUE obj) struct select_args args; rb_scan_args(argc, argv, "14", &args.read, &args.write, &args.except, &args.error, &timeout); + args.select_iface = false; return do_rb_f_select(&args, timeout); } #endif static VALUE rb_f_select(int argc, VALUE *argv, VALUE obj) { - VALUE timeout, rv; + VALUE timeout; struct select_args args; rb_scan_args(argc, argv, "13", &args.read, &args.write, &args.except, &timeout); args.error = Qnil; - rv = do_rb_f_select(&args, timeout); - if (RB_TYPE_P(rv, T_ARRAY)) - rb_ary_pop(rv); - return rv; + args.select_iface = true; + return do_rb_f_select(&args, timeout); } static VALUE diff --git a/thread.c b/thread.c index 5f8d1f9800d2..6e819ce1720a 100644 --- a/thread.c +++ b/thread.c @@ -3859,7 +3859,7 @@ pollfdset_extract(struct rb_pollfdset *pollfdset, rb_fdset_t *fds, int flags) rb_fd_zero(fds); for (i = 0; i < pollfdset->n_fds; i++) - if (pollfdset->fds[i].revents & (flags | POLLERR_SET)) + if (pollfdset->fds[i].revents & flags) rb_fd_set(pollfdset->fds[i].fd, fds); } @@ -3876,11 +3876,12 @@ pollfdset_badfd(struct rb_pollfdset *pollfdset) } int -rb_fd_select(int n, rb_fdset_t *readfds, rb_fdset_t *writefds, rb_fdset_t *exceptfds, rb_fdset_t *errorfds, 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, bool select_iface) { struct rb_pollfdset pollfdset; int timeout_ms = timeout ? timeout->tv_sec * 1000 + timeout->tv_usec / 1000 : -1; - bool badfd; + bool badfd = false; int ret; pollfdset_init(&pollfdset); @@ -3889,14 +3890,16 @@ rb_fd_select(int n, rb_fdset_t *readfds, rb_fdset_t *writefds, rb_fdset_t *excep if (exceptfds) pollfdset_add(&pollfdset, exceptfds, POLLEX_SET); if (errorfds) pollfdset_add(&pollfdset, errorfds, POLLERR_SET); ret = poll(pollfdset.fds, pollfdset.n_fds, timeout_ms); - badfd = pollfdset_badfd(&pollfdset); + if (select_iface) + badfd = pollfdset_badfd(&pollfdset); if (badfd) { if (readfds) rb_fd_zero(readfds); if (writefds) rb_fd_zero(writefds); if (exceptfds) rb_fd_zero(exceptfds); if (errorfds) rb_fd_zero(errorfds); } else { - if (readfds) pollfdset_extract(&pollfdset, readfds, POLLIN_SET); + if (readfds) pollfdset_extract(&pollfdset, readfds, POLLIN_SET | + (select_iface ? POLLERR_SET : 0)); if (writefds) pollfdset_extract(&pollfdset, writefds, POLLOUT_SET); if (exceptfds) pollfdset_extract(&pollfdset, exceptfds, POLLEX_SET); if (errorfds) pollfdset_extract(&pollfdset, errorfds, POLLERR_SET); @@ -4047,6 +4050,7 @@ struct select_set { rb_fdset_t orig_eset; rb_fdset_t orig_errset; struct timeval *timeout; + _Bool select_iface; }; static VALUE @@ -4112,7 +4116,8 @@ do_select(VALUE p) if (!RUBY_VM_INTERRUPTED(set->th->ec)) { result = native_fd_select(set->max, set->rset, set->wset, set->eset, set->errset, - rb_hrtime2timeval(&tv, sto), set->th); + rb_hrtime2timeval(&tv, sto), + set->select_iface, set->th); if (result < 0) lerrno = errno; } }, set->sigwait_fd >= 0 ? ubf_sigwait : ubf_select, set->th, TRUE); @@ -4183,7 +4188,7 @@ init_set_fd(int fd, rb_fdset_t *fds) int rb_thread_fd_select(int max, rb_fdset_t * read, rb_fdset_t * write, rb_fdset_t * except, - rb_fdset_t * error, struct timeval *timeout) + rb_fdset_t * error, struct timeval *timeout, _Bool select_iface) { struct select_set set; @@ -4195,6 +4200,7 @@ rb_thread_fd_select(int max, rb_fdset_t * read, rb_fdset_t * write, rb_fdset_t * set.eset = except; set.errset = error; set.timeout = timeout; + set.select_iface = select_iface; if (!set.rset && !set.wset && !set.eset && !set.errset) { if (!timeout) { diff --git a/thread_pthread.c b/thread_pthread.c index 02b03cdb45b8..fb03f1307f6f 100644 --- a/thread_pthread.c +++ b/thread_pthread.c @@ -1153,9 +1153,9 @@ native_thread_apply_priority(rb_thread_t *th) #endif /* USE_NATIVE_THREAD_PRIORITY */ static int -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) +native_fd_select(int n, rb_fdset_t *readfds, rb_fdset_t *writefds, rb_fdset_t *exceptfds, rb_fdset_t *errorfds, struct timeval *timeout, _Bool select_iface, rb_thread_t *th) { - return rb_fd_select(n, readfds, writefds, exceptfds, errorfds, timeout); + return rb_fd_select(n, readfds, writefds, exceptfds, errorfds, timeout, select_iface); } static void diff --git a/thread_win32.c b/thread_win32.c index d8eb2b1ee6c9..6ca95edf2278 100644 --- a/thread_win32.c +++ b/thread_win32.c @@ -640,7 +640,8 @@ native_thread_apply_priority(rb_thread_t *th) int rb_w32_select_with_thread(int, fd_set *, fd_set *, fd_set *, struct timeval *, void *); /* @internal */ 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, + struct timeval *timeout, _Bool select_iface, rb_thread_t *th) { fd_set *r = NULL, *w = NULL, *e = NULL; if (readfds) { -- 2.26.2
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor