class Coolio::Watcher
Public Class Methods
new()
click to toggle source
static VALUE Coolio_Watcher_initialize(VALUE self)
{
rb_raise(rb_eRuntimeError, "watcher base class should not be initialized directly");
}
Public Instance Methods
Coolio::Watcher.attach(loop) → Coolio::Watcher
click to toggle source
Attach the watcher to the given Coolio::Loop. If the watcher is already attached to a loop, detach it from the old one and attach it to the new one.
static VALUE Coolio_Watcher_attach(VALUE self, VALUE loop)
{
VALUE loop_watchers, active_watchers;
struct Coolio_Watcher *watcher_data;
Data_Get_Struct(self, struct Coolio_Watcher, watcher_data);
watcher_data->enabled = 1;
loop_watchers = rb_iv_get(loop, "@watchers");
if(loop_watchers == Qnil) {
/* we should never get here */
loop_watchers = rb_hash_new();
rb_iv_set(loop, "@watchers", loop_watchers);
}
/* Add us to the loop's array of active watchers. This is mainly done
* to keep the VM from garbage collecting watchers that are associated
* with a loop (and also lets you see within Ruby which watchers are
* associated with a given loop), but isn't really necessary for any
* other reason */
rb_hash_aset(loop_watchers, self, Qtrue);
active_watchers = rb_iv_get(loop, "@active_watchers");
if(active_watchers == Qnil)
active_watchers = INT2NUM(1);
else
active_watchers = INT2NUM(NUM2INT(active_watchers) + 1);
rb_iv_set(loop, "@active_watchers", active_watchers);
return self;
}
Coolio::Watcher.attached? → Boolean
click to toggle source
Is the watcher currently attached to an event loop?
static VALUE Coolio_Watcher_attached(VALUE self)
{
return Coolio_Watcher_evloop(self) != Qnil;
}
Coolio::Watcher.detach → Coolio::Watcher
click to toggle source
Detach the watcher from its current Coolio::Loop.
static VALUE Coolio_Watcher_detach(VALUE self)
{
struct Coolio_Watcher *watcher_data;
struct Coolio_Loop *loop_data;
VALUE loop_watchers;
int i;
Data_Get_Struct(self, struct Coolio_Watcher, watcher_data);
if(watcher_data->loop == Qnil)
rb_raise(rb_eRuntimeError, "not attached to a loop");
loop_watchers = rb_iv_get(watcher_data->loop, "@watchers");
/* Remove us from the loop's array of active watchers. This likely
* has negative performance and scalability characteristics as this
* isn't an O(1) operation. Hopefully there's a better way...
* Trying a hash for now... */
rb_hash_delete(loop_watchers, self);
if(watcher_data->enabled) {
rb_iv_set(
watcher_data->loop,
"@active_watchers",
INT2NUM(NUM2INT(rb_iv_get(watcher_data->loop, "@active_watchers")) - 1)
);
}
watcher_data->enabled = 0;
Data_Get_Struct(watcher_data->loop, struct Coolio_Loop, loop_data);
/* Iterate through the events in the loop's event buffer. If there
* are any pending events from this watcher, mark them NULL. The
* dispatch loop will skip them. This prevents watchers earlier
* in the event buffer from detaching others which may have pending
* events in the buffer but get garbage collected in the meantime */
for(i = 0; i < loop_data->events_received; i++) {
if(loop_data->eventbuf[i].watcher == self)
loop_data->eventbuf[i].watcher = Qnil;
}
watcher_data->loop = Qnil;
return self;
}
Coolio::Watcher.disable → Coolio::Watcher
click to toggle source
Temporarily disable an event watcher which is attached to a loop.
This is useful if you wish to toggle event monitoring on and off.
static VALUE Coolio_Watcher_disable(VALUE self)
{
struct Coolio_Watcher *watcher_data;
Data_Get_Struct(self, struct Coolio_Watcher, watcher_data);
if(!watcher_data->enabled)
rb_raise(rb_eRuntimeError, "already disabled");
watcher_data->enabled = 0;
rb_iv_set(
watcher_data->loop,
"@active_watchers",
INT2NUM(NUM2INT(rb_iv_get(watcher_data->loop, "@active_watchers")) - 1)
);
return self;
}
Coolio::Watcher.enable → Coolio::Watcher
click to toggle source
Re-enable a watcher which has been temporarily disabled. See the disable method for a more thorough explanation.
static VALUE Coolio_Watcher_enable(VALUE self)
{
struct Coolio_Watcher *watcher_data;
Data_Get_Struct(self, struct Coolio_Watcher, watcher_data);
if(watcher_data->enabled)
rb_raise(rb_eRuntimeError, "already enabled");
watcher_data->enabled = 1;
rb_iv_set(
watcher_data->loop,
"@active_watchers",
INT2NUM(NUM2INT(rb_iv_get(watcher_data->loop, "@active_watchers")) + 1)
);
return self;
}
Coolio::Watcher.enabled? → Boolean
click to toggle source
Is the watcher currently enabled?
static VALUE Coolio_Watcher_enabled(VALUE self)
{
struct Coolio_Watcher *watcher_data;
Data_Get_Struct(self, struct Coolio_Watcher, watcher_data);
return watcher_data->enabled ? Qtrue : Qfalse;
}
Coolio::Watcher.evloop → Coolio::Loop
click to toggle source
Return the loop to which we're currently attached
static VALUE Coolio_Watcher_evloop(VALUE self)
{
struct Coolio_Watcher *watcher_data;
Data_Get_Struct(self, struct Coolio_Watcher, watcher_data);
return watcher_data->loop;
}