[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