librelist archives

« back to archive

[PATCH] do not propagate Errno::EINTR into Ruby

[PATCH] do not propagate Errno::EINTR into Ruby

From:
Eric Wong
Date:
2013-05-02 @ 22:38
To be consistent with I/O wrappers in Ruby, Ruby-land should
never see EINTR from kevent or epoll_wait.  We will just return
zero events if our timeout expired soon after we got signaled.
---
 ext/sleepy_penguin/epoll.c  | 8 ++++++--
 ext/sleepy_penguin/kqueue.c | 8 ++++++--
 2 files changed, 12 insertions(+), 4 deletions(-)

diff --git a/ext/sleepy_penguin/epoll.c b/ext/sleepy_penguin/epoll.c
index 90ecc2c..9010e2d 100644
--- a/ext/sleepy_penguin/epoll.c
+++ b/ext/sleepy_penguin/epoll.c
@@ -147,8 +147,12 @@ static VALUE epwait_result(struct ep_per_thread *ept, int n)
 	struct epoll_event *epoll_event = ept->events;
 	VALUE obj_events, obj;
 
-	if (n < 0)
-		rb_sys_fail("epoll_wait");
+	if (n < 0) {
+		if (errno == EINTR)
+			n = 0;
+		else
+			rb_sys_fail("epoll_wait");
+	}
 
 	for (i = n; --i >= 0; epoll_event++) {
 		obj_events = UINT2NUM(epoll_event->events);
diff --git a/ext/sleepy_penguin/kqueue.c b/ext/sleepy_penguin/kqueue.c
index 155204b..4d5785f 100644
--- a/ext/sleepy_penguin/kqueue.c
+++ b/ext/sleepy_penguin/kqueue.c
@@ -158,8 +158,12 @@ static VALUE kevent_result(struct kq_per_thread *kpt,
int nevents)
 	int i;
 	struct kevent *event = kpt->events;
 
-	if (nevents < 0)
-		rb_sys_fail("kevent");
+	if (nevents < 0) {
+		if (errno == EINTR)
+			nevents = 0;
+		else
+			rb_sys_fail("kevent");
+	}
 
 	for (i = nevents; --i >= 0; event++)
 		yield_kevent(event);
-- 
Eric Wong