about summary refs log tree commit homepage
diff options
context:
space:
mode:
authorEric Wong <normalperson@yhbt.net>2010-09-25 20:08:18 +0000
committerEric Wong <normalperson@yhbt.net>2010-09-25 20:14:30 +0000
commitbc4aaf4afdfb42ad5cc5e0729f816fbefb3d338e (patch)
tree30f241886ba47767e5a40a8e76c85443a4d5dcdc
parent6296604742ed27ede171dad28f7d2bec2092d122 (diff)
downloadsleepy_penguin-bc4aaf4afdfb42ad5cc5e0729f816fbefb3d338e.tar.gz
Storing Ruby object values in the kernel means
they won't be visible to the GC, but for the
most part it's safe.
-rw-r--r--ext/sleepy_penguin/epoll.c16
1 files changed, 13 insertions, 3 deletions
diff --git a/ext/sleepy_penguin/epoll.c b/ext/sleepy_penguin/epoll.c
index 89fc123..da96bd7 100644
--- a/ext/sleepy_penguin/epoll.c
+++ b/ext/sleepy_penguin/epoll.c
@@ -9,6 +9,16 @@ static const int step = 64; /* unlikely to grow unless you're huge */
 static VALUE cEpoll_IO;
 static ID id_for_fd;
 
+static void pack_event_data(struct epoll_event *event, VALUE obj)
+{
+        event->data.ptr = (void *)obj;
+}
+
+static VALUE unpack_event_data(struct epoll_event *event)
+{
+        return (VALUE)event->data.ptr;
+}
+
 struct rb_epoll {
         int fd;
         int timeout;
@@ -142,7 +152,7 @@ static VALUE ctl(VALUE self, VALUE io, VALUE flags, int op)
         int rv;
 
         event.events = NUM2UINT(flags);
-        event.data.ptr = (void *)io;
+        pack_event_data(&event, io);
 
         rv = epoll_ctl(ep->fd, op, fd, &event);
         if (rv == -1) {
@@ -167,7 +177,7 @@ static VALUE set(VALUE self, VALUE io, VALUE flags)
         int rv;
 
         event.events = NUM2UINT(flags);
-        event.data.ptr = (void *)io;
+        pack_event_data(&event, io);
 
         rv = epoll_ctl(ep->fd, EPOLL_CTL_MOD, fd, &event);
         if (rv == -1) {
@@ -194,7 +204,7 @@ static VALUE epwait_result(struct rb_epoll *ep, int n)
 
         for (i = n; --i >= 0; epoll_event++) {
                 obj_events = UINT2NUM(epoll_event->events);
-                obj = (VALUE)(epoll_event->data.ptr);
+                obj = unpack_event_data(epoll_event);
                 rb_yield_values(2, obj_events, obj);
         }