summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndy Wingo <wingo@pobox.com>2017-02-08 15:16:48 +0100
committerAndy Wingo <wingo@pobox.com>2017-02-08 15:16:48 +0100
commitdceaa2f92dcdf007b238d713581f3e26c3bbad73 (patch)
tree38733e3b7206bb8a0ddba6bed7e367081797dd4b
parentBetter exception handling (diff)
downloadguile-fibers-dceaa2f92dcdf007b238d713581f3e26c3bbad73.tar.gz
Prevent GC from waking up epoll
* epoll.c (do_epoll_wait): Leave Guile to do the epoll, preventing libgc from having to interrupt us for GC.
-rw-r--r--epoll.c34
1 files changed, 27 insertions, 7 deletions
diff --git a/epoll.c b/epoll.c
index 8e1f9c5..dd6fa6b 100644
--- a/epoll.c
+++ b/epoll.c
@@ -111,6 +111,25 @@ scm_primitive_epoll_ctl (SCM epfd, SCM op, SCM fd, SCM events)
}
#undef FUNC_NAME
+struct epoll_wait_data {
+ int fd;
+ struct epoll_event *events;
+ int maxevents;
+ int timeout;
+ int rv;
+ int err;
+};
+
+static void*
+do_epoll_wait (void *p)
+{
+ struct epoll_wait_data *data = p;
+ data->rv = epoll_wait (data->fd, data->events, data->maxevents,
+ data->timeout);
+ data->err = errno;
+ return NULL;
+}
+
/* Wait on the files whose descriptors were registered on EPFD, and
write the resulting events in EVENTSV, a bytevector. Returns the
number of struct epoll_event values that were written to EVENTSV,
@@ -140,18 +159,19 @@ scm_primitive_epoll_wait (SCM epfd, SCM wakefd, SCM wokefd,
rv = 0;
else
{
- int err;
- rv = epoll_wait (c_epfd, events, maxevents, c_timeout);
- if (rv < 0)
- err = errno;
+ struct epoll_wait_data data = { c_epfd, events, maxevents, c_timeout };
+ scm_without_guile (do_epoll_wait, &data);
+ rv = data.rv;
scm_c_wait_finished ();
if (rv < 0)
{
- errno = err;
- if (err == EINTR)
+ if (data.err == EINTR)
rv = 0;
else
- SCM_SYSERROR;
+ {
+ errno = data.err;
+ SCM_SYSERROR;
+ }
}
else
{