class NIO::Selector

Selectors monitor IO objects for events of interest

Public Class Methods

new() click to toggle source

Create a new selector. This is more or less the pure Ruby version translated into an MRI cext

static VALUE NIO_Selector_initialize(VALUE self)
{
    VALUE lock;

    rb_ivar_set(self, rb_intern("selectables"), rb_hash_new());
    rb_ivar_set(self, rb_intern("lock_holder"), Qnil);

    lock = rb_class_new_instance(0, 0, rb_const_get(rb_cObject, rb_intern("Mutex")));
    rb_ivar_set(self, rb_intern("lock"), lock);
    rb_ivar_set(self, rb_intern("lock_holder"), Qnil);

    return Qnil;
}
new() click to toggle source

Create a new NIO::Selector

# File lib/nio/selector.rb, line 7
def initialize
  @selectables = {}
  @lock = Mutex.new

  # Other threads can wake up a selector
  @wakeup, @waker = IO.pipe
  @closed = false
end

Public Instance Methods

close() click to toggle source

Close the selector and free system resources

static VALUE NIO_Selector_close(VALUE self)
{
    VALUE args[1] = {self};
    return NIO_Selector_synchronize(self, NIO_Selector_close_synchronized, args);
}
closed?() click to toggle source

Is the selector closed?

static VALUE NIO_Selector_closed(VALUE self)
{
    VALUE args[1] = {self};
    return NIO_Selector_synchronize(self, NIO_Selector_closed_synchronized, args);
}
deregister(p1) click to toggle source

Deregister an IO object from the selector

static VALUE NIO_Selector_deregister(VALUE self, VALUE io)
{
    VALUE args[2] = {self, io};
    return NIO_Selector_synchronize(self, NIO_Selector_deregister_synchronized, args);
}
empty?() click to toggle source

True if there are monitors on the loop

static VALUE NIO_Selector_is_empty(VALUE self)
{
    VALUE selectables = rb_ivar_get(self, rb_intern("selectables"));

    return rb_funcall(selectables, rb_intern("empty?"), 0) == Qtrue ? Qtrue : Qfalse;
}
register(p1, p2) click to toggle source

Register an IO object with the selector for the given interests

static VALUE NIO_Selector_register(VALUE self, VALUE io, VALUE interests)
{
    VALUE args[3] = {self, io, interests};
    return NIO_Selector_synchronize(self, NIO_Selector_register_synchronized, args);
}
registered?(p1) click to toggle source

Is the given IO object registered with the selector

static VALUE NIO_Selector_is_registered(VALUE self, VALUE io)
{
    VALUE selectables = rb_ivar_get(self, rb_intern("selectables"));

    /* Perhaps this should be holding the mutex? */
    return rb_funcall(selectables, rb_intern("has_key?"), 1, io);
}
select(p1 = v1) click to toggle source

Select from all registered IO objects

static VALUE NIO_Selector_select(int argc, VALUE *argv, VALUE self)
{
    VALUE timeout;
    VALUE args[2];

    rb_scan_args(argc, argv, "01", &timeout);

    if(timeout != Qnil && NUM2DBL(timeout) < 0) {
        rb_raise(rb_eArgError, "time interval must be positive");
    }

    args[0] = self;
    args[1] = timeout;

    return NIO_Selector_synchronize(self, NIO_Selector_select_synchronized, args);
}
wakeup() click to toggle source

Wake the selector up from another thread

static VALUE NIO_Selector_wakeup(VALUE self)
{
    struct NIO_Selector *selector;
    Data_Get_Struct(self, struct NIO_Selector, selector);

    if(selector->closed) {
        rb_raise(rb_eIOError, "selector is closed");
    }

    write(selector->wakeup_writer, "\0", 1);
    return Qnil;
}