about summary refs log tree commit homepage
path: root/ext/kgio/wait.c
diff options
context:
space:
mode:
Diffstat (limited to 'ext/kgio/wait.c')
-rw-r--r--ext/kgio/wait.c41
1 files changed, 39 insertions, 2 deletions
diff --git a/ext/kgio/wait.c b/ext/kgio/wait.c
index d9266eb..9cfcbdb 100644
--- a/ext/kgio/wait.c
+++ b/ext/kgio/wait.c
@@ -2,8 +2,35 @@
 
 static ID io_wait_rd, io_wait_wr;
 
-void kgio_wait_readable(VALUE io, int fd)
+/*
+ * avoiding rb_thread_select() or similar since rb_io_wait_*able can be
+ * made to use poll() later on.  It's highly unlikely Ruby will move to
+ * use an edge-triggered event notification, so assign EAGAIN is safe...
+ */
+static VALUE force_wait_readable(VALUE self)
+{
+        errno = EAGAIN;
+        if (!rb_io_wait_readable(my_fileno(self)))
+                rb_sys_fail("wait readable");
+
+        return self;
+}
+
+static VALUE force_wait_writable(VALUE self)
 {
+        errno = EAGAIN;
+        if (!rb_io_wait_writable(my_fileno(self)))
+                rb_sys_fail("wait writable");
+
+        return self;
+}
+
+void kgio_call_wait_readable(VALUE io, int fd)
+{
+        /*
+         * we _NEVER_ set errno = EAGAIN here by default so we can work
+         * (or fail hard) with edge-triggered epoll()
+         */
         if (io_wait_rd) {
                 (void)rb_funcall(io, io_wait_rd, 0, 0);
         } else {
@@ -12,8 +39,12 @@ void kgio_wait_readable(VALUE io, int fd)
         }
 }
 
-void kgio_wait_writable(VALUE io, int fd)
+void kgio_call_wait_writable(VALUE io, int fd)
 {
+        /*
+         * we _NEVER_ set errno = EAGAIN here by default so we can work
+         * (or fail hard) with edge-triggered epoll()
+         */
         if (io_wait_wr) {
                 (void)rb_funcall(io, io_wait_wr, 0, 0);
         } else {
@@ -109,6 +140,12 @@ static VALUE wait_rd(VALUE mod)
 void init_kgio_wait(void)
 {
         VALUE mKgio = rb_define_module("Kgio");
+        VALUE mWaiters = rb_define_module_under(mKgio, "DefaultWaiters");
+
+        rb_define_method(mWaiters, "kgio_wait_readable",
+                         force_wait_readable, 0);
+        rb_define_method(mWaiters, "kgio_wait_writable",
+                         force_wait_writable, 0);
 
         rb_define_singleton_method(mKgio, "wait_readable=", set_wait_rd, 1);
         rb_define_singleton_method(mKgio, "wait_writable=", set_wait_wr, 1);