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 8 def initialize @selectables = {} @lock = Mutex.new # Other threads can wake up a selector @wakeup, @waker = IO.pipe @closed = false end
Public Instance Methods
backend()
click to toggle source
static VALUE NIO_Selector_backend(VALUE self) {
struct NIO_Selector *selector;
Data_Get_Struct(self, struct NIO_Selector, selector);
if(selector->closed) {
rb_raise(rb_eIOError, "selector is closed");
}
switch (ev_backend(selector->ev_loop)) {
case EVBACKEND_EPOLL:
return ID2SYM(rb_intern("epoll"));
case EVBACKEND_POLL:
return ID2SYM(rb_intern("poll"));
case EVBACKEND_KQUEUE:
return ID2SYM(rb_intern("kqueue"));
case EVBACKEND_SELECT:
return ID2SYM(rb_intern("select"));
case EVBACKEND_PORT:
return ID2SYM(rb_intern("port"));
}
return ID2SYM(rb_intern("unknown"));
}
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");
}
selector->wakeup_fired = 1;
write(selector->wakeup_writer, "\0", 1);
return Qnil;
}