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

openSUSE Build Service is sponsored by