[macruby-changes] [3152] MacRuby/trunk

source_changes at macosforge.org source_changes at macosforge.org
Tue Dec 22 16:25:36 PST 2009


Revision: 3152
          http://trac.macosforge.org/projects/ruby/changeset/3152
Author:   ernest.prabhakar at gmail.com
Date:     2009-12-22 16:25:33 -0800 (Tue, 22 Dec 2009)
Log Message:
-----------
Added new initalizer for Dispatch::Timer

Modified Paths:
--------------
    MacRuby/trunk/gcd.c
    MacRuby/trunk/spec/macruby/core/gcd/source_spec.rb

Modified: MacRuby/trunk/gcd.c
===================================================================
--- MacRuby/trunk/gcd.c	2009-12-22 23:07:31 UTC (rev 3151)
+++ MacRuby/trunk/gcd.c	2009-12-23 00:25:33 UTC (rev 3152)
@@ -13,6 +13,7 @@
 #define GCD_BLOCKS_COPY_DVARS 1
 
 #include <dispatch/dispatch.h>
+#include <unistd.h>
 #include "ruby/intern.h"
 #include "ruby/node.h"
 #include "ruby/io.h"
@@ -105,6 +106,7 @@
 
 static VALUE cGroup;
 static VALUE cSource;
+static VALUE cTimer;
 static VALUE cSemaphore;
 
 static inline rb_vm_block_t *
@@ -692,15 +694,44 @@
         case SOURCE_TYPE_VNODE: return DISPATCH_SOURCE_TYPE_VNODE;
         case SOURCE_TYPE_WRITE: return DISPATCH_SOURCE_TYPE_WRITE;
         default: rb_raise(rb_eArgError, 
-                          "Unknown dispatch source type [%d]", value);
+                          "Unknown dispatch source type `%d'", value);
     }
     return NULL;
 }
 
+static inline BOOL
+rb_is_file_source_type(VALUE num)
+{
+    enum SOURCE_TYPE_ENUM value = NUM2LONG(num);
+    if (value == SOURCE_TYPE_READ || value == SOURCE_TYPE_VNODE 
+        || value == SOURCE_TYPE_WRITE) {
+        return YES;
+    }
+    return NO;
+}
 
+static inline BOOL
+rb_is_timer_source_type(VALUE num)
+{
+    return (NUM2LONG(num) == SOURCE_TYPE_TIMER) ? YES : NO;
+}
+
+
 static VALUE rb_source_on_event(VALUE self, SEL sel);
-static void rb_source_event_handler(void* sourceptr);
+//static void rb_source_event_handler(void* sourceptr);
 
+static void
+rb_source_close_file(void *source)
+{
+    assert(source != NULL);
+    uintptr_t handle = dispatch_source_get_handle(RSource(source)->source);
+    int filedes = (int)handle;
+    if (close(filedes) != 0) {
+    	rb_raise(rb_eIOError, "Closing descriptor `%d' fails with error: %d",
+    	    filedes, errno);
+	}
+}
+
 static VALUE
 rb_source_alloc(VALUE klass, SEL sel)
 {
@@ -715,20 +746,54 @@
 rb_source_init(VALUE self, SEL sel,
     VALUE type, VALUE handle, VALUE mask, VALUE queue)
 {
-    rb_source_t *src = RSource(self);
     Check_Queue(queue);
-    
+    rb_source_t *src = RSource(self);    
     src->type = rb_num2source_type(type);
     src->source = dispatch_source_create(src->type,
         NUM2UINT(handle), NUM2LONG(mask), RQueue(queue)->queue);
 
     if (rb_block_given_p()) {
         rb_source_on_event(self, 0);
+    } else {
+        rb_raise(rb_eArgError, "No event handler for Dispatch::Source.");
     }
 
+    if (rb_is_file_source_type(type)) {
+        dispatch_set_context(src->source, (void*)self); // retain this?
+        dispatch_source_set_cancel_handler_f(src->source, rb_source_close_file);
+    }
+
+    rb_dispatch_resume(self, 0); // Does this work okay for timers?
     return self;
 }
 
+static VALUE
+rb_timer_init(VALUE self, SEL sel, int argc, VALUE* argv)
+{
+    dispatch_time_t start_time;
+    rb_source_t *src = RSource(self);
+    VALUE queue = Qnil, interval = Qnil, delay = Qnil, leeway = Qnil;
+    rb_scan_args(argc, argv, "31", &queue, &delay, &interval, &leeway);
+    Check_Queue(queue);
+    
+    rb_source_init(self, sel, INT2FIX(SOURCE_TYPE_TIMER),
+	    INT2FIX(0), INT2FIX(0), queue);
+
+    if (NIL_P(leeway)) {
+        leeway = INT2FIX(0);
+    }
+    if (NIL_P(delay)) {
+        start_time = DISPATCH_TIME_NOW;
+    }
+    else {
+        start_time = rb_num2timeout(delay);
+    }
+
+    dispatch_source_set_timer(src->source, start_time,
+	    rb_num2nsec(interval), rb_num2nsec(leeway));
+    return self;
+}
+
 static void
 rb_source_event_handler(void* sourceptr)
 {
@@ -750,26 +815,7 @@
     return Qnil;
 }
 
-static void
-rb_source_cancel_handler(void *source)
-{
-    assert(source != NULL);
-    rb_vm_block_t *the_block = RSource(source)->cancel_handler;
-    rb_vm_block_eval(the_block, 0, NULL);
-}
-
 static VALUE
-rb_source_on_cancellation(VALUE self, SEL sel)
-{
-    rb_source_t *src = RSource(self);
-    rb_vm_block_t *block = given_block();
-    GC_WB(&src->cancel_handler, block);
-    dispatch_set_context(src->source, (void*)self); // retain this?
-    dispatch_source_set_cancel_handler_f(src->source, rb_source_cancel_handler);
-    return Qnil;
-}
-
-static VALUE
 rb_source_cancel(VALUE self, SEL sel)
 {
     dispatch_source_cancel(RSource(self)->source);
@@ -926,19 +972,19 @@
     rb_define_const(cSource, "PROC", INT2NUM(SOURCE_TYPE_PROC));
     rb_define_const(cSource, "READ", INT2NUM(SOURCE_TYPE_READ));
     rb_define_const(cSource, "SIGNAL", INT2NUM(SOURCE_TYPE_SIGNAL));
-    rb_define_const(cSource, "TIMER", INT2NUM(SOURCE_TYPE_TIMER));
     rb_define_const(cSource, "VNODE", INT2NUM(SOURCE_TYPE_VNODE));
     rb_define_const(cSource, "WRITE", INT2NUM(SOURCE_TYPE_WRITE));
     rb_objc_define_method(*(VALUE *)cSource, "alloc", rb_source_alloc, 0);
     rb_objc_define_method(cSource, "initialize", rb_source_init, 4);
-    rb_objc_define_method(cSource, "on_event", rb_source_on_event, 0);
-    rb_objc_define_method(cSource, "on_cancel", rb_source_on_cancellation, 0);
     rb_objc_define_method(cSource, "cancelled?", rb_source_cancelled_p, 0);
     rb_objc_define_method(cSource, "cancel!", rb_source_cancel, 0);
     rb_objc_define_method(cSource, "resume!", rb_dispatch_resume, 0);
     rb_objc_define_method(cSource, "suspend!", rb_dispatch_suspend, 0);
     rb_objc_define_method(cSource, "suspended?", rb_dispatch_suspended_p, 0);
 
+    cTimer = rb_define_class_under(mDispatch, "Timer", cSource);
+    rb_objc_define_method(cTimer, "initialize", rb_timer_init, -1);
+
     cSemaphore = rb_define_class_under(mDispatch, "Semaphore", rb_cObject);
     rb_objc_define_method(*(VALUE *)cSemaphore, "alloc", rb_semaphore_alloc, 0);
     rb_objc_define_method(cSemaphore, "initialize", rb_semaphore_init, 1);

Modified: MacRuby/trunk/spec/macruby/core/gcd/source_spec.rb
===================================================================
--- MacRuby/trunk/spec/macruby/core/gcd/source_spec.rb	2009-12-22 23:07:31 UTC (rev 3151)
+++ MacRuby/trunk/spec/macruby/core/gcd/source_spec.rb	2009-12-23 00:25:33 UTC (rev 3152)
@@ -21,8 +21,8 @@
         Dispatch::Source.const_defined?(:WRITE).should == true
       end
 
-      it "for timer source" do
-        Dispatch::Source.const_defined?(:TIMER).should == true
+      it "NOT for timer source" do
+        Dispatch::Source.const_defined?(:TIMER).should == false
       end
 
       it "NOT for mach sources" do
@@ -36,12 +36,28 @@
         @q = Dispatch::Queue.concurrent
       end
 
-      it "creates a custom Source" do
-        Dispatch::Source.new(Dispatch::Source::DATA_ADD, 0,  0, @q).should
+      it "can create a custom Source" do
+        Dispatch::Source.new(Dispatch::Source::DATA_ADD, 0,  0, @q) {}.should
           be_kind_of(Dispatch::Source)
-        Dispatch::Source.new(Dispatch::Source::DATA_OR, 0,  0, @q).should
+        Dispatch::Source.new(Dispatch::Source::DATA_OR, 0,  0, @q) {}.should
           be_kind_of(Dispatch::Source)
       end    
+
+      it "can create a process Source" do
+        Dispatch::Source.new(Dispatch::Source::PROC, 0,  0, @q) {}.should
+          be_kind_of(Dispatch::Source)
+        Dispatch::Source.new(Dispatch::Source::SIGNAL, 0,  0, @q) {}.should
+          be_kind_of(Dispatch::Source)
+      end    
+
+      it "can create a file Source" do
+        Dispatch::Source.new(Dispatch::Source::READ, 0,  0, @q) {}.should
+          be_kind_of(Dispatch::Source)
+        Dispatch::Source.new(Dispatch::Source::VNODE, 0,  0, @q) {}.should
+          be_kind_of(Dispatch::Source)
+        Dispatch::Source.new(Dispatch::Source::WRITE, 0,  0, @q) {}.should
+          be_kind_of(Dispatch::Source)
+      end    
       
     end
       
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/macruby-changes/attachments/20091222/5f5a7321/attachment-0001.html>


More information about the macruby-changes mailing list