File 0009-io-add-additional-argument-to-fd_select-calls.patch of Package ruby2.5
From f873f9d18b74b71c3853ee89273a1da5f496324d Mon Sep 17 00:00:00 2001
From: Michal Suchanek <msuchanek@suse.de>
Date: Mon, 3 Feb 2020 18:42:18 +0100
Subject: [PATCH 09/19] io: add additional argument to *fd_select calls
This extra argument will be used to support poll() error fd list.
Signed-off-by: Michal Suchanek <msuchanek@suse.de>
---
include/ruby/intern.h | 8 ++++----
io.c | 21 ++++++++++++---------
thread.c | 27 +++++++++++++++++++--------
thread_pthread.c | 4 ++--
4 files changed, 37 insertions(+), 23 deletions(-)
diff --git a/include/ruby/intern.h b/include/ruby/intern.h
index a711b861159f..ac1b0345afa9 100644
--- a/include/ruby/intern.h
+++ b/include/ruby/intern.h
@@ -313,7 +313,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 *, struct timeval *);
+int rb_fd_select(int, rb_fdset_t *, rb_fdset_t *, rb_fdset_t *, rb_fdset_t *, struct timeval *);
#define rb_fd_ptr(f) ((f)->fdset)
#define rb_fd_max(f) ((f)->maxfd)
@@ -335,7 +335,7 @@ void rb_fd_set(int, rb_fdset_t *);
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);
-#define rb_fd_select(n, rfds, wfds, efds, timeout) rb_w32_select((n), (rfds) ? ((rb_fdset_t*)(rfds))->fdset : NULL, (wfds) ? ((rb_fdset_t*)(wfds))->fdset : NULL, (efds) ? ((rb_fdset_t*)(efds))->fdset: NULL, (timeout))
+#define rb_fd_select(n, rfds, wfds, efds, errfds, timeout) rb_w32_select((n), (rfds) ? ((rb_fdset_t*)(rfds))->fdset : NULL, (wfds) ? ((rb_fdset_t*)(wfds))->fdset : NULL, (efds) ? ((rb_fdset_t*)(efds))->fdset: NULL, (errfds) ? ((rb_fdset_t*)(errfds))->fdset: NULL, (timeout))
#define rb_fd_resize(n, f) ((void)(f))
#define rb_fd_ptr(f) ((f)->fdset)
@@ -356,7 +356,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, timeout) select((n), (rfds), (wfds), (efds), (timeout))
+#define rb_fd_select(n, rfds, wfds, efds, errfds, timeout) select((n), (rfds), (wfds), (efds), (timeout))
#endif
@@ -435,7 +435,7 @@ VALUE rb_thread_wakeup_alive(VALUE);
VALUE rb_thread_run(VALUE);
VALUE rb_thread_kill(VALUE);
VALUE rb_thread_create(VALUE (*)(ANYARGS), void*);
-int rb_thread_fd_select(int, 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 *);
void rb_thread_wait_for(struct timeval);
VALUE rb_thread_current(void);
VALUE rb_thread_main(void);
diff --git a/io.c b/io.c
index 178ec14b589f..f514f7822541 100644
--- a/io.c
+++ b/io.c
@@ -8909,7 +8909,7 @@ static VALUE
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;
@@ -8969,9 +8969,11 @@ select_internal(VALUE read, VALUE write, VALUE except, struct timeval *tp, rb_fd
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);
}
@@ -9031,9 +9033,9 @@ select_internal(VALUE read, VALUE write, VALUE except, struct timeval *tp, rb_fd
}
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
@@ -9379,6 +9381,7 @@ rb_f_select(int argc, VALUE *argv, VALUE obj)
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;
}
@@ -10665,12 +10668,12 @@ maygvl_copy_stream_wait_read(int has_gvl, struct copy_stream_struct *stp)
}
#else /* !USE_POLL */
static int
-maygvl_select(int has_gvl, int n, rb_fdset_t *rfds, rb_fdset_t *wfds, rb_fdset_t *efds, struct timeval *timeout)
+maygvl_select(int has_gvl, int n, rb_fdset_t *rfds, rb_fdset_t *wfds, rb_fdset_t *efds, rb_fdset_t *errfds, struct timeval *timeout)
{
if (has_gvl)
- return rb_thread_fd_select(n, rfds, wfds, efds, timeout);
+ return rb_thread_fd_select(n, rfds, wfds, efds, errfds, timeout);
else
- return rb_fd_select(n, rfds, wfds, efds, timeout);
+ return rb_fd_select(n, rfds, wfds, efds, errfds, timeout);
}
static int
@@ -10681,7 +10684,7 @@ maygvl_copy_stream_wait_read(int has_gvl, struct copy_stream_struct *stp)
do {
rb_fd_zero(&stp->fds);
rb_fd_set(stp->src_fd, &stp->fds);
- ret = maygvl_select(has_gvl, rb_fd_max(&stp->fds), &stp->fds, NULL, NULL, NULL);
+ ret = maygvl_select(has_gvl, rb_fd_max(&stp->fds), &stp->fds, NULL, NULL, NULL, NULL);
} while (ret == -1 && maygvl_copy_stream_continue_p(has_gvl, stp));
if (ret == -1) {
@@ -10704,7 +10707,7 @@ nogvl_copy_stream_wait_write(struct copy_stream_struct *stp)
#else
rb_fd_zero(&stp->fds);
rb_fd_set(stp->dst_fd, &stp->fds);
- ret = rb_fd_select(rb_fd_max(&stp->fds), NULL, &stp->fds, NULL, NULL);
+ ret = rb_fd_select(rb_fd_max(&stp->fds), NULL, &stp->fds, NULL, NULL, NULL);
#endif
} while (ret == -1 && maygvl_copy_stream_continue_p(0, stp));
diff --git a/thread.c b/thread.c
index afbddc563cd0..7d74f0a060f0 100644
--- a/thread.c
+++ b/thread.c
@@ -3631,7 +3631,7 @@ rb_fd_dup(rb_fdset_t *dst, const rb_fdset_t *src)
}
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) {
@@ -3646,6 +3646,8 @@ rb_fd_select(int n, rb_fdset_t *readfds, rb_fdset_t *writefds, rb_fdset_t *excep
rb_fd_resize(n - 1, exceptfds);
e = rb_fd_ptr(exceptfds);
}
+ if (errorfds)
+ rb_fd_zero(errorfds);
return select(n, r, w, e, timeout);
}
@@ -3752,6 +3754,7 @@ struct select_set {
rb_fdset_t read;
rb_fdset_t write;
rb_fdset_t except;
+ rb_fdset_t error;
};
static size_t
@@ -3768,6 +3771,7 @@ select_set_free(void *p)
rb_fd_term(&orig->read);
rb_fd_term(&orig->write);
rb_fd_term(&orig->except);
+ rb_fd_term(&orig->error);
xfree(orig);
}
@@ -3779,7 +3783,7 @@ static const rb_data_type_t select_set_type = {
static int
do_select(int n, rb_fdset_t *const readfds, rb_fdset_t *const writefds,
- rb_fdset_t *const exceptfds, struct timeval *timeout)
+ rb_fdset_t *const exceptfds, rb_fdset_t *const errorfds, struct timeval *timeout)
{
int MAYBE_UNUSED(result);
int lerrno;
@@ -3795,6 +3799,7 @@ do_select(int n, rb_fdset_t *const readfds, rb_fdset_t *const writefds,
(restore_fdset(readfds, &orig->read), \
restore_fdset(writefds, &orig->write), \
restore_fdset(exceptfds, &orig->except), \
+ restore_fdset(errorfds, &orig->error), \
update_timeval(timeout, limit), \
TRUE)
@@ -3810,13 +3815,14 @@ do_select(int n, rb_fdset_t *const readfds, rb_fdset_t *const writefds,
fd_init_copy(read);
fd_init_copy(write);
fd_init_copy(except);
+ fd_init_copy(error);
#undef fd_init_copy
do {
lerrno = 0;
BLOCKING_REGION({
- result = native_fd_select(n, readfds, writefds, exceptfds,
+ result = native_fd_select(n, readfds, writefds, exceptfds, errorfds,
timeout, th);
if (result < 0) lerrno = errno;
}, ubf_select, th, FALSE);
@@ -3867,9 +3873,9 @@ rb_thread_fd_writable(int fd)
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)
{
- if (!read && !write && !except) {
+ if (!read && !write && !except && !error) {
if (!timeout) {
rb_thread_sleep_forever();
return 0;
@@ -3887,7 +3893,7 @@ rb_thread_fd_select(int max, rb_fdset_t * read, rb_fdset_t * write, rb_fdset_t *
if (except) {
rb_fd_resize(max - 1, except);
}
- return do_select(max, read, write, except, timeout);
+ return do_select(max, read, write, except, error, timeout);
}
#if USE_POLL
@@ -4013,6 +4019,7 @@ struct select_args {
rb_fdset_t *read;
rb_fdset_t *write;
rb_fdset_t *except;
+ rb_fdset_t *error;
struct timeval *tv;
};
@@ -4023,7 +4030,7 @@ select_single(VALUE ptr)
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) {
@@ -4034,6 +4041,8 @@ select_single(VALUE ptr)
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;
}
@@ -4046,6 +4055,7 @@ select_single_cleanup(VALUE ptr)
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;
}
@@ -4053,7 +4063,7 @@ select_single_cleanup(VALUE ptr)
int
rb_wait_for_single_fd(int fd, int events, struct timeval *tv)
{
- rb_fdset_t rfds, wfds, efds;
+ rb_fdset_t rfds, wfds, efds, errfds;
struct select_args args;
int r;
VALUE ptr = (VALUE)&args;
@@ -4062,6 +4072,7 @@ rb_wait_for_single_fd(int fd, int events, struct timeval *tv)
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 = tv;
r = (int)rb_ensure(select_single, ptr, select_single_cleanup, ptr);
diff --git a/thread_pthread.c b/thread_pthread.c
index 686c219ecbf1..b98e8bb73831 100644
--- a/thread_pthread.c
+++ b/thread_pthread.c
@@ -1084,9 +1084,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, 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
--
2.26.2