0
@@ -55,22 +55,30 @@ module RubyKQueue
0
VALUE c_handle_events() {
0
int nevents, i, num_to_fetch;
0
+ struct timespec timeout;
0
- // Don't actually run this method until we've got an event
0
- rb_thread_select(kq + 1, &read_set, NULL, NULL, NULL);
0
events = (struct kevent*)malloc(MAX_EVENTS * sizeof(struct kevent));
0
+ bzero(&timeout, sizeof(struct timespec));
0
rb_raise(rb_eStandardError, strerror(errno));
0
- nevents = kevent(kq, NULL, 0, events, MAX_EVENTS, NULL);
0
+ // Don't actually run this method until we've got an event
0
+ if (rb_thread_select(kq + 1, &read_set, NULL, NULL, NULL) <= 0) {
0
+ rb_raise(rb_eStandardError, strerror(errno));
0
+ // In testing kevent has been blocking, even though select continues
0
+ // so set a tiny timeout just in case. It _should_ execute immediately
0
+ nevents = kevent(kq, NULL, 0, events, MAX_EVENTS, &timeout);
0
rb_raise(rb_eStandardError, strerror(errno));
0
@@ -81,7 +89,7 @@ module RubyKQueue
0
return INT2FIX(nevents);
0
@@ -91,9 +99,13 @@ module RubyKQueue
0
# TODO: Allow a lower level interface for direct manipulation
0
# of registration flags (EV_ONESHOT and the like)
0
- def self.register(ident, filter_class, *flags, &block)
0
- ident = filter_class.normalize_ident(ident)
0
- filter = filter_class::FILTER
0
+ def self.register(ident, filter_or_filter_class, *flags, &block)
0
+ if filter_or_filter_class.is_a? Class
0
+ ident = filter_or_filter_class.normalize_ident(ident)
0
+ filter = filter_or_filter_class::FILTER
0
+ filter = filter_or_filter_class
0
@@registry[filter] ||= {}
0
@@registry[filter][ident] ||= {}
0
@@ -107,12 +119,34 @@ module RubyKQueue
0
c_register(ident, EV_ADD | EV_ENABLE, filter, mask)
0
+ def self.deregister(ident, filter_or_filter_class, *flags)
0
+ # puts "Calling deregister"
0
+ # puts "Registry like: #{@@registry.inspect}"
0
+ if filter_or_filter_class.is_a? Class
0
+ ident = filter_or_filter_class.normalize_ident(ident)
0
+ filter = filter_or_filter_class::FILTER
0
+ filter = filter_or_filter_class
0
+ @@registry[filter][ident].delete(flag) rescue nil
0
+ # puts "Now registry like: #{@@registry.inspect}"
0
+ mask = flags.inject {|msk, flg| msk | flg }
0
+ # puts "Calling c_register"
0
+ c_register(ident, EV_DELETE, filter, mask)
0
def self.trigger(id, filter, flag)
0
Event.new(id, filter, flag).trigger
0
+
@@handler_thread ||= Thread.new { loop { c_handle_events } }0
@@ -158,6 +192,14 @@ module RubyKQueue
0
# TODO: ignore or raise?
0
+ self.class.register(self.id, self.filter, self.flag)
0
+ self.class.deregister(self.id, self.filter, self.flag)
0
\ No newline at end of file
Comments
No one has commented yet.