class Coolio::Loop
Constants
- EVBACKEND_EPOLL
- EVBACKEND_KQUEUE
- EVBACKEND_POLL
- EVBACKEND_PORT
- EVBACKEND_SELECT
- EVFLAG_FORKCHECK
- EVFLAG_NOENV
Public Class Methods
Retrieve the default event loop for the current thread
# File lib/cool.io/loop.rb, line 19 def self.default Thread.current._coolio_loop end
Create a new Coolio::Loop
Options:
:skip_environment (boolean)
Ignore the $LIBEV_FLAGS environment variable
:fork_check (boolean)
Enable autodetection of forks
:backend
Choose the default backend, one (or many in an array) of: :select (most platforms) :poll (most platforms except Windows) :epoll (Linux) :kqueue (BSD/Mac OS X) :port (Solaris 10)
# File lib/cool.io/loop.rb, line 41 def initialize(options = {}) @watchers = {} @active_watchers = 0 flags = 0 options.each do |option, value| case option when :skip_environment flags |= EVFLAG_NOEV if value when :fork_check flags |= EVFLAG_FORKCHECK if value when :backend value = [value] unless value.is_a? Array value.each do |backend| case backend when :select then flags |= EVBACKEND_SELECT when :poll then flags |= EVBACKEND_POLL when :epoll then flags |= EVBACKEND_EPOLL when :kqueue then flags |= EVBACKEND_KQUEUE when :port then flags |= EVBACKEND_PORT else raise ArgumentError, "no such backend: #{backend}" end end else raise ArgumentError, "no such option: #{option}" end end @loop = ev_loop_new(flags) end
Public Instance Methods
Attach a watcher to the loop
# File lib/cool.io/loop.rb, line 73 def attach(watcher) watcher.attach self end
Does the loop have any active watchers?
# File lib/cool.io/loop.rb, line 100 def has_active_watchers? @active_watchers > 0 end
Run the event loop and dispatch events back to Ruby. If there are no watchers associated with the event loop it will return immediately. Otherwise, run will continue blocking and making event callbacks to watchers until all watchers associated with the loop have been disabled or detached. The loop may be explicitly stopped by calling the stop method on the loop object.
# File lib/cool.io/loop.rb, line 83 def run(timeout = nil) raise RuntimeError, "no watchers for this loop" if @watchers.empty? @running = true while @running and not @active_watchers.zero? run_once(timeout) end @running = false end
Run the Coolio::Loop
once, but return immediately if there are no pending events.
static VALUE Coolio_Loop_run_nonblock(VALUE self) { struct Coolio_Loop *loop_data; VALUE nevents; Data_Get_Struct(self, struct Coolio_Loop, loop_data); assert(loop_data->ev_loop && !loop_data->events_received); RUN_LOOP(loop_data, EVLOOP_NONBLOCK); Coolio_Loop_dispatch_events(loop_data); nevents = INT2NUM(loop_data->events_received); loop_data->events_received = 0; return nevents; }
Run the Coolio::Loop
once, blocking until events are received.
static VALUE Coolio_Loop_run_once(int argc, VALUE *argv, VALUE self) { VALUE timeout; VALUE nevents; struct Coolio_Loop *loop_data; rb_scan_args(argc, argv, "01", &timeout); if (timeout != Qnil && NUM2DBL(timeout) < 0) { rb_raise(rb_eArgError, "time interval must be positive"); } Data_Get_Struct(self, struct Coolio_Loop, loop_data); assert(loop_data->ev_loop && !loop_data->events_received); /* Implement the optional timeout (if any) as a ev_timer */ /* Using the technique written at http://pod.tst.eu/http://cvs.schmorp.de/libev/ev.pod#code_ev_timer_code_relative_and_opti, the timer is not stopped/started everytime when timeout is specified, instead, the timer is stopped when timeout is not specified. */ if (timeout != Qnil) { /* It seems libev is not a fan of timers being zero, so fudge a little */ loop_data->timer.repeat = NUM2DBL(timeout) + 0.0001; ev_timer_again(loop_data->ev_loop, &loop_data->timer); } else { ev_timer_stop(loop_data->ev_loop, &loop_data->timer); } /* libev is patched to release the GIL when it makes its system call */ RUN_LOOP(loop_data, EVLOOP_ONESHOT); Coolio_Loop_dispatch_events(loop_data); nevents = INT2NUM(loop_data->events_received); loop_data->events_received = 0; return nevents; }
Stop the event loop if it's running
# File lib/cool.io/loop.rb, line 94 def stop raise RuntimeError, "loop not running" unless @running @running = false end
All watchers attached to the current loop
# File lib/cool.io/loop.rb, line 105 def watchers @watchers.keys end
Private Instance Methods
Wrapper for populating a Coolio_Loop struct with a new event loop
static VALUE Coolio_Loop_ev_loop_new(VALUE self, VALUE flags) { struct Coolio_Loop *loop_data; Data_Get_Struct(self, struct Coolio_Loop, loop_data); if(loop_data->ev_loop) rb_raise(rb_eRuntimeError, "loop already initialized"); loop_data->ev_loop = ev_loop_new(NUM2INT(flags)); return Qnil; }