class Libev::Scheduler
Public Class Methods
new()
click to toggle source
static VALUE Scheduler_initialize(VALUE self) { Scheduler_t *scheduler; VALUE thread = rb_thread_current(); int is_main_thread = (thread == rb_thread_main()); GetScheduler(self, scheduler); scheduler->ev_loop = is_main_thread ? EV_DEFAULT : ev_loop_new(EVFLAG_NOSIGMASK); ev_async_init(&scheduler->break_async, break_async_callback); ev_async_start(scheduler->ev_loop, &scheduler->break_async); ev_unref(scheduler->ev_loop); // don't count the break_async watcher scheduler->pending_count = 0; scheduler->currently_polling = 0; scheduler->ready = rb_ary_new(); return Qnil; }
Public Instance Methods
block(*args)
click to toggle source
VALUE Scheduler_block(int argc, VALUE *argv, VALUE self) { VALUE timeout = (argc == 2) ? argv[1] : Qnil; if (timeout != Qnil) Scheduler_sleep(self, timeout); else Scheduler_pause(self); return Qtrue; }
close()
click to toggle source
VALUE Scheduler_close(VALUE self) { Scheduler_t *scheduler; GetScheduler(self, scheduler); Scheduler_run(self); ev_async_stop(scheduler->ev_loop, &scheduler->break_async); if (!ev_is_default_loop(scheduler->ev_loop)) ev_loop_destroy(scheduler->ev_loop); return self; }
fiber(&block)
click to toggle source
# File lib/libev_scheduler.rb, line 5 def fiber(&block) fiber = Fiber.new(blocking: false, &block) unblock(nil, fiber) # fiber.resume return fiber end
io_wait(p1, p2, p3)
click to toggle source
VALUE Scheduler_io_wait(VALUE self, VALUE io, VALUE events, VALUE timeout) { Scheduler_t *scheduler; struct libev_io io_watcher; struct libev_timer timeout_watcher; GetScheduler(self, scheduler); rb_io_t *fptr; VALUE underlying_io = rb_ivar_get(io, ID_ivar_io); if (underlying_io != Qnil) io = underlying_io; GetOpenFile(io, fptr); io_watcher.scheduler = scheduler; io_watcher.fiber = rb_fiber_current(); ev_io_init(&io_watcher.io, Scheduler_io_callback, fptr->fd, io_event_mask(events)); int use_timeout = timeout != Qnil; if (use_timeout) { timeout_watcher.scheduler = scheduler; timeout_watcher.fiber = rb_fiber_current(); ev_timer_init(&timeout_watcher.timer, Scheduler_timer_callback, NUM2DBL(timeout), 0.); ev_timer_start(scheduler->ev_loop, &timeout_watcher.timer); } ev_io_start(scheduler->ev_loop, &io_watcher.io); VALUE nil = Qnil; scheduler->pending_count++; rb_fiber_yield(1, &nil); scheduler->pending_count--; ev_io_stop(scheduler->ev_loop, &io_watcher.io); if (use_timeout) ev_timer_stop(scheduler->ev_loop, &timeout_watcher.timer); return self; }
kernel_sleep(duration = nil)
click to toggle source
# File lib/libev_scheduler.rb, line 12 def kernel_sleep(duration = nil) block(:sleep, duration) end
pending_count()
click to toggle source
VALUE Scheduler_pending_count(VALUE self) { Scheduler_t *scheduler; GetScheduler(self, scheduler); return INT2NUM(scheduler->pending_count); }
process_wait(p1, p2)
click to toggle source
VALUE Scheduler_process_wait(VALUE self, VALUE pid, VALUE flags) { Scheduler_t *scheduler; struct libev_child watcher; VALUE result = Qnil; GetScheduler(self, scheduler); watcher.scheduler = scheduler; watcher.fiber = rb_fiber_current(); watcher.status = Qnil; ev_child_init(&watcher.child, Scheduler_child_callback, NUM2INT(pid), 0); ev_child_start(scheduler->ev_loop, &watcher.child); VALUE nil = Qnil; scheduler->pending_count++; rb_fiber_yield(1, &nil); scheduler->pending_count--; ev_child_stop(scheduler->ev_loop, &watcher.child); RB_GC_GUARD(watcher.status); RB_GC_GUARD(result); return result; }
run()
click to toggle source
VALUE Scheduler_run(VALUE self) { Scheduler_t *scheduler; GetScheduler(self, scheduler); while (scheduler->pending_count > 0 || RARRAY_LEN(scheduler->ready) > 0) { Scheduler_poll(self); } return self; }
unblock(p1, p2)
click to toggle source
VALUE Scheduler_unblock(VALUE self, VALUE blocker, VALUE fiber) { Scheduler_t *scheduler; GetScheduler(self, scheduler); rb_ary_push(scheduler->ready, fiber); if (scheduler->currently_polling) ev_async_send(scheduler->ev_loop, &scheduler->break_async); return self; }