ext/kgio/wait.c in kgio-1.3.1 vs ext/kgio/wait.c in kgio-2.0.0pre1
- old
+ new
@@ -1,117 +1,81 @@
#include "kgio.h"
-static ID io_wait_rd, io_wait_wr;
+static ID id_wait_rd, id_wait_wr;
-void kgio_wait_readable(VALUE io, int fd)
-{
- if (io_wait_rd) {
- (void)rb_funcall(io, io_wait_rd, 0, 0);
- } else {
- if (!rb_io_wait_readable(fd))
- rb_sys_fail("wait readable");
- }
-}
+/*
+ * 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 assigning EAGAIN is
+ * probably safe...
+ */
-void kgio_wait_writable(VALUE io, int fd)
-{
- if (io_wait_wr) {
- (void)rb_funcall(io, io_wait_wr, 0, 0);
- } else {
- if (!rb_io_wait_writable(fd))
- rb_sys_fail("wait writable");
- }
-}
/*
- * call-seq:
+ * Blocks the running Thread indefinitely until +self+ IO object is writable.
+ * This method is automatically called by default whenever kgio_read needs
+ * to block on input.
*
- * Kgio.wait_readable = :method_name
- * Kgio.wait_readable = nil
- *
- * Sets a method for kgio_read to call when a read would block.
- * This is useful for non-blocking frameworks that use Fibers,
- * as the method referred to this may cause the current Fiber
- * to yield execution.
- *
- * A special value of nil will cause Ruby to wait using the
- * rb_io_wait_readable() function.
+ * Users of alternative threading/fiber libraries are
+ * encouraged to override this method in their subclasses or modules to
+ * work with their threading/blocking methods.
*/
-static VALUE set_wait_rd(VALUE mod, VALUE sym)
+static VALUE kgio_wait_readable(VALUE self)
{
- switch (TYPE(sym)) {
- case T_SYMBOL:
- io_wait_rd = SYM2ID(sym);
- return sym;
- case T_NIL:
- io_wait_rd = 0;
- return sym;
- }
- rb_raise(rb_eTypeError, "must be a symbol or nil");
- return sym;
+ errno = EAGAIN;
+ if (!rb_io_wait_readable(my_fileno(self)))
+ rb_sys_fail("kgio_wait_readable");
+
+ return self;
}
/*
- * call-seq:
- *
- * Kgio.wait_writable = :method_name
- * Kgio.wait_writable = nil
- *
- * Sets a method for kgio_write to call when a read would block.
- * This is useful for non-blocking frameworks that use Fibers,
- * as the method referred to this may cause the current Fiber
- * to yield execution.
- *
- * A special value of nil will cause Ruby to wait using the
- * rb_io_wait_writable() function.
+ * blocks the running Thread indefinitely until +self+ IO object is writable
+ * This method is automatically called whenever kgio_write needs to
+ * block on output.
+ * Users of alternative threading/fiber libraries are
+ * encouraged to override this method in their subclasses or modules to
+ * work with their threading/blocking methods.
*/
-static VALUE set_wait_wr(VALUE mod, VALUE sym)
+static VALUE kgio_wait_writable(VALUE self)
{
- switch (TYPE(sym)) {
- case T_SYMBOL:
- io_wait_wr = SYM2ID(sym);
- return sym;
- case T_NIL:
- io_wait_wr = 0;
- return sym;
- }
- rb_raise(rb_eTypeError, "must be a symbol or nil");
- return sym;
+ errno = EAGAIN;
+ if (!rb_io_wait_writable(my_fileno(self)))
+ rb_sys_fail("kgio_wait_writable");
+
+ return self;
}
-/*
- * call-seq:
- *
- * Kgio.wait_writable -> Symbol or nil
- *
- * Returns the symbolic method name of the method assigned to
- * call when EAGAIN is occurs on a Kgio::PipeMethods#kgio_write
- * or Kgio::SocketMethods#kgio_write call
- */
-static VALUE wait_wr(VALUE mod)
+VALUE kgio_call_wait_writable(VALUE io)
{
- return io_wait_wr ? ID2SYM(io_wait_wr) : Qnil;
+ return rb_funcall(io, id_wait_wr, 0, 0);
}
-/*
- * call-seq:
- *
- * Kgio.wait_readable -> Symbol or nil
- *
- * Returns the symbolic method name of the method assigned to
- * call when EAGAIN is occurs on a Kgio::PipeMethods#kgio_read
- * or Kgio::SocketMethods#kgio_read call.
- */
-static VALUE wait_rd(VALUE mod)
+VALUE kgio_call_wait_readable(VALUE io)
{
- return io_wait_rd ? ID2SYM(io_wait_rd) : Qnil;
+ return rb_funcall(io, id_wait_rd, 0, 0);
}
void init_kgio_wait(void)
{
VALUE mKgio = rb_define_module("Kgio");
- rb_define_singleton_method(mKgio, "wait_readable=", set_wait_rd, 1);
- rb_define_singleton_method(mKgio, "wait_writable=", set_wait_wr, 1);
- rb_define_singleton_method(mKgio, "wait_readable", wait_rd, 0);
- rb_define_singleton_method(mKgio, "wait_writable", wait_wr, 0);
+ /*
+ * Document-module: Kgio::DefaultWaiters
+ *
+ * This module contains default kgio_wait_readable and
+ * kgio_wait_writable methods that block indefinitely (in a
+ * thread-safe manner) until an IO object is read or writable.
+ * This module is included in the Kgio::PipeMethods and
+ * Kgio::SocketMethods modules used by all bundled IO-derived
+ * objects.
+ */
+ VALUE mWaiters = rb_define_module_under(mKgio, "DefaultWaiters");
+
+ id_wait_rd = rb_intern("kgio_wait_readable");
+ id_wait_wr = rb_intern("kgio_wait_writable");
+
+ rb_define_method(mWaiters, "kgio_wait_readable",
+ kgio_wait_readable, 0);
+ rb_define_method(mWaiters, "kgio_wait_writable",
+ kgio_wait_writable, 0);
}