[macruby-changes] [3165] MacRuby/trunk

source_changes at macosforge.org source_changes at macosforge.org
Wed Dec 23 13:33:10 PST 2009


Revision: 3165
          http://trac.macosforge.org/projects/ruby/changeset/3165
Author:   ernest.prabhakar at gmail.com
Date:     2009-12-23 13:33:07 -0800 (Wed, 23 Dec 2009)
Log Message:
-----------
Added finalizers for Dispatch classes

Modified Paths:
--------------
    MacRuby/trunk/gcd.c
    MacRuby/trunk/spec/macruby/core/gcd/source_spec.rb
    MacRuby/trunk/spec/macruby/core/gcd/source_spec_disabled.rb
    MacRuby/trunk/spec/macruby/tags/macruby/core/gcd/source_tags.txt

Modified: MacRuby/trunk/gcd.c
===================================================================
--- MacRuby/trunk/gcd.c	2009-12-23 21:04:48 UTC (rev 3164)
+++ MacRuby/trunk/gcd.c	2009-12-23 21:33:07 UTC (rev 3165)
@@ -77,9 +77,9 @@
     struct RBasic basic;
     int suspension_count;
     dispatch_source_t source;
-    dispatch_source_type_t type;
+    dispatch_source_type_t type; // remove?
     rb_vm_block_t *event_handler;
-    rb_vm_block_t *cancel_handler;
+    rb_vm_block_t *cancel_handler;// remove?
 } rb_source_t;
 
 #define RSource(val) ((rb_source_t*)val)
@@ -662,7 +662,21 @@
      == 0	? Qtrue : Qfalse;
 }
 
+static IMP rb_group_finalize_super;
 
+static void
+rb_group_finalize(void *rcv, SEL sel)
+{
+    rb_group_t *grp = RGroup(rcv);
+    if (grp->group != NULL) {
+        dispatch_release(grp->group);
+    }
+    if (rb_group_finalize_super != NULL) {
+        ((void(*)(void *, SEL))rb_group_finalize_super)(rcv, sel);
+    }
+}
+
+
 enum SOURCE_TYPE_ENUM
 {
     SOURCE_TYPE_DATA_ADD,
@@ -716,22 +730,6 @@
     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_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)
 {
@@ -741,6 +739,8 @@
     return (VALUE)source;
 }
 
+static VALUE rb_source_on_event(VALUE self, SEL sel);
+static void rb_source_event_handler(void* sourceptr);
 
 static VALUE
 rb_source_init(VALUE self, SEL sel,
@@ -753,16 +753,12 @@
         NUM2UINT(handle), NUM2LONG(mask), RQueue(queue)->queue);
 
     if (rb_block_given_p()) {
+        fprintf(stderr, "Setting event handler for %p\n", (void*) src);
         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;
 }
@@ -810,12 +806,22 @@
     rb_source_t *src = RSource(self);
     rb_vm_block_t *block = given_block();
     GC_WB(&src->event_handler, block);
+    fprintf(stderr, "Setting context for %p to %p\n", (void*) src->source, (void*) self);
+    GC_RETAIN(self);
     dispatch_set_context(src->source, (void *)self); // retain this?
+    fprintf(stderr, "Set context for %p\n", src);
     dispatch_source_set_event_handler_f(src->source, rb_source_event_handler);
     return Qnil;
 }
 
 static VALUE
+rb_source_merge(VALUE self, SEL sel, VALUE data)
+{
+    dispatch_source_merge_data(RSource(self)->source, NUM2INT(data));
+    return Qnil;
+}
+
+static VALUE
 rb_source_cancel(VALUE self, SEL sel)
 {
     dispatch_source_cancel(RSource(self)->source);
@@ -828,6 +834,25 @@
     return dispatch_source_testcancel(RSource(self)->source) ? Qtrue : Qfalse;
 }
 
+static IMP rb_source_finalize_super;
+
+static void
+rb_source_finalize(void *rcv, SEL sel)
+{
+    rb_source_t *src = RSource(rcv);
+    if (src->source != NULL) {
+        while (src->suspension_count < 0) {
+            dispatch_resume(src->source);
+            src->suspension_count--;
+        }
+        dispatch_release(src->source);
+    }
+    if (rb_source_finalize_super != NULL) {
+        ((void(*)(void *, SEL))rb_source_finalize_super)(rcv, sel);
+    }
+
+}
+
 static VALUE
 rb_semaphore_alloc(VALUE klass, SEL sel)
 {
@@ -965,6 +990,10 @@
     rb_objc_define_method(cGroup, "notify", rb_group_notify, 1);
     rb_objc_define_method(cGroup, "on_completion", rb_group_notify, 1);
     rb_objc_define_method(cGroup, "wait", rb_group_wait, -1);
+    
+    rb_group_finalize_super = rb_objc_install_method2((Class)cGroup,
+	    "finalize", (IMP)rb_group_finalize);
+    
         
     cSource = rb_define_class_under(mDispatch, "Source", rb_cObject);
     rb_define_const(cSource, "DATA_ADD", INT2NUM(SOURCE_TYPE_DATA_ADD));
@@ -981,17 +1010,21 @@
     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);
+    rb_objc_define_method(cSource, "merge", rb_source_merge, 1);
 
     cTimer = rb_define_class_under(mDispatch, "Timer", cSource);
     rb_objc_define_method(cTimer, "initialize", rb_timer_init, -1);
 
+    rb_source_finalize_super = rb_objc_install_method2((Class)cSource,
+	    "finalize", (IMP)rb_source_finalize);
+
     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);
     rb_objc_define_method(cSemaphore, "wait", rb_semaphore_wait, -1);
     rb_objc_define_method(cSemaphore, "signal", rb_semaphore_signal, 0);
 
-    rb_queue_finalize_super = rb_objc_install_method2((Class)cSemaphore,
+    rb_semaphore_finalize_super = rb_objc_install_method2((Class)cSemaphore,
 	    "finalize", (IMP)rb_semaphore_finalize);
 
     rb_define_const(mDispatch, "TIME_NOW", ULL2NUM(DISPATCH_TIME_NOW));

Modified: MacRuby/trunk/spec/macruby/core/gcd/source_spec.rb
===================================================================
--- MacRuby/trunk/spec/macruby/core/gcd/source_spec.rb	2009-12-23 21:04:48 UTC (rev 3164)
+++ MacRuby/trunk/spec/macruby/core/gcd/source_spec.rb	2009-12-23 21:33:07 UTC (rev 3165)
@@ -31,5 +31,12 @@
       end
     end
 
+    describe "of type" do
+      before :each do
+        @q = Dispatch::Queue.new('org.macruby.gcd_spec.sources')
+      end
+
+    end
+    
   end
 end

Modified: MacRuby/trunk/spec/macruby/core/gcd/source_spec_disabled.rb
===================================================================
--- MacRuby/trunk/spec/macruby/core/gcd/source_spec_disabled.rb	2009-12-23 21:04:48 UTC (rev 3164)
+++ MacRuby/trunk/spec/macruby/core/gcd/source_spec_disabled.rb	2009-12-23 21:33:07 UTC (rev 3165)
@@ -313,3 +313,63 @@
   end
 
 end
+
+describe :DATA_ADD do
+  before :each do
+    @type = Dispatch::Source::DATA_ADD
+  end
+
+  it "returns an instance of Dispatch::Source" do
+    p @type
+    src = Dispatch::Source.new(@type, 1, 2, @q) { true.should == true }
+    p src
+    src.should be_kind_of(Dispatch::Source)
+  end
+
+  it "should not be suspended" do
+    src = Dispatch::Source.new(@type, 1, 2, @q) { true.should == true }
+    src.suspended?.should == false
+  end
+
+  it "requires an event handler block" do
+    lambda { Dispatch::Source.new(@type, 1, 2, @q) }.should
+    raise_error(ArgumentError)
+  end
+
+  it "fires event handler on merge" do
+    src = Dispatch::Source.new(@type, 1, 2, @q) do
+      true.should == true
+    end
+    lambda { src.merge 1 }.should_not raise_error(Exception)
+    @q.sync {}
+  end
+
+  it "fires event handler on merge" do
+    src = Dispatch::Source.new(@type, 1, 2, @q) do
+      true.should == true
+    end
+    #src.merge 1
+    @q.sync {}
+  end
+
+  it "passes source to event handler" do
+    src = Dispatch::Source.new(@type, 1, 2, @q) do |source|
+      source.should be_kind_of(Dispatch::Source)
+    end
+    #src.merge 1
+    @q.sync {}
+  end
+
+  it "should execute event handler when Fixnum merged with <<" do
+    @src.suspend
+    @src.merge 20
+    @src.merge 22
+    @src.resume
+    @q.sync {}
+  end
+
+  it "will only merge Fixnum arguments" do
+    lambda { @src.merge :foo}.should raise_error(ArgumentError)
+  end
+end
+    

Modified: MacRuby/trunk/spec/macruby/tags/macruby/core/gcd/source_tags.txt
===================================================================
--- MacRuby/trunk/spec/macruby/tags/macruby/core/gcd/source_tags.txt	2009-12-23 21:04:48 UTC (rev 3164)
+++ MacRuby/trunk/spec/macruby/tags/macruby/core/gcd/source_tags.txt	2009-12-23 21:33:07 UTC (rev 3165)
@@ -1,6 +0,0 @@
-fails:Dispatch::Source event handler will be invoked
-fails:Dispatch::Source event handler receives the source
-fails:Dispatch::Source event handler can get data
-fails:Dispatch::Source event handler will get merged data
-fails:Dispatch::Source event handler can get handle
-fails:Dispatch::Source event handler can get mask
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/macruby-changes/attachments/20091223/45576635/attachment-0001.html>


More information about the macruby-changes mailing list