about summary refs log tree commit homepage
diff options
context:
space:
mode:
authorEric Wong <e@yhbt.net>2011-01-17 08:02:27 +0000
committerEric Wong <e@yhbt.net>2011-01-17 08:02:27 +0000
commite6ad2154a726795fd246bede8341c4fcfe28e1a8 (patch)
tree9e48f1545d1690fa3a6b2bcf571c315ae1c324d6
parent108d72b69f59d1c373981149c2a259bba3ff9dce (diff)
downloadsleepy_penguin-e6ad2154a726795fd246bede8341c4fcfe28e1a8.tar.gz
Occasionally users may want a way to check if they
stored an IO object or not, this makes it easier.
-rw-r--r--ext/sleepy_penguin/epoll.c26
-rw-r--r--test/test_epoll.rb28
2 files changed, 54 insertions, 0 deletions
diff --git a/ext/sleepy_penguin/epoll.c b/ext/sleepy_penguin/epoll.c
index 2361e18..4db2179 100644
--- a/ext/sleepy_penguin/epoll.c
+++ b/ext/sleepy_penguin/epoll.c
@@ -220,6 +220,7 @@ static VALUE ctl(VALUE self, VALUE io, VALUE flags, int op)
                 break;
         case EPOLL_CTL_DEL:
                 rb_ary_store(ep->marks, fd, Qnil);
+                rb_ary_store(ep->flag_cache, fd, Qnil);
         }
 
         return INT2NUM(rv);
@@ -306,6 +307,7 @@ static VALUE delete(VALUE self, VALUE io)
                 }
         }
         rb_ary_store(ep->marks, fd, Qnil);
+        rb_ary_store(ep->flag_cache, fd, Qnil);
 
         return io;
 }
@@ -588,6 +590,27 @@ static VALUE init_copy(VALUE copy, VALUE orig)
         return copy;
 }
 
+static VALUE io_for(VALUE self, VALUE obj)
+{
+        struct rb_epoll *ep = ep_get(self);
+
+        return rb_ary_entry(ep->marks, my_fileno(obj));
+}
+
+static VALUE flags_for(VALUE self, VALUE obj)
+{
+        struct rb_epoll *ep = ep_get(self);
+
+        return rb_ary_entry(ep->flag_cache, my_fileno(obj));
+}
+
+static VALUE include_p(VALUE self, VALUE obj)
+{
+        struct rb_epoll *ep = ep_get(self);
+
+        return NIL_P(rb_ary_entry(ep->marks, my_fileno(obj))) ? Qfalse : Qtrue;
+}
+
 /*
  * we close (or lose to GC) epoll descriptors at fork to avoid leakage
  * and invalid objects being referenced later in the child
@@ -633,6 +656,9 @@ void sleepy_penguin_init_epoll(void)
         rb_define_method(cEpoll, "mod", mod, 2);
         rb_define_method(cEpoll, "del", del, 1);
         rb_define_method(cEpoll, "delete", delete, 1);
+        rb_define_method(cEpoll, "io_for", io_for, 1);
+        rb_define_method(cEpoll, "flags_for", flags_for, 1);
+        rb_define_method(cEpoll, "include?", include_p, 1);
         rb_define_method(cEpoll, "set", set, 2);
         rb_define_method(cEpoll, "wait", epwait, -1);
         rb_define_const(cEpoll, "CLOEXEC", INT2NUM(EPOLL_CLOEXEC));
diff --git a/test/test_epoll.rb b/test/test_epoll.rb
index b73cb02..6e1b768 100644
--- a/test/test_epoll.rb
+++ b/test/test_epoll.rb
@@ -323,4 +323,32 @@ class TestEpoll < Test::Unit::TestCase
     assert_equal @rd, @ep.delete(@rd)
     assert_nil @ep.delete(@rd)
   end
+
+  def test_io_for
+    @ep.add @rd, Epoll::IN
+    assert_equal @rd, @ep.io_for(@rd.fileno)
+    assert_equal @rd, @ep.io_for(@rd)
+    @ep.del @rd
+    assert_nil @ep.io_for(@rd.fileno)
+    assert_nil @ep.io_for(@rd)
+  end
+
+  def test_flags_for
+    @ep.add @rd, Epoll::IN
+    assert_equal Epoll::IN, @ep.flags_for(@rd.fileno)
+    assert_equal Epoll::IN, @ep.flags_for(@rd)
+
+    @ep.del @rd
+    assert_nil @ep.flags_for(@rd.fileno)
+    assert_nil @ep.flags_for(@rd)
+  end
+
+  def test_include?
+    assert ! @ep.include?(@rd)
+    @ep.add @rd, Epoll::IN
+    assert @ep.include?(@rd)
+    assert @ep.include?(@rd.fileno)
+    assert ! @ep.include?(@wr)
+    assert ! @ep.include?(@wr.fileno)
+  end
 end