2011/2/6 Tony A. [email protected]:
GCed… you seem to be suggesting it’s the other way around.
Sorry, I was wrong about the meaning of “marking an object”.
If you mark all VALUEs your C extension is internally referencing in your C
extension’s “mark” function it will prevent them from being garbage
collected.
But this is not my case. My case is as follows (an example code):
domain = ARGV[0]
module UdnsWatcher
def initialize(resolver)
@resolver = resolver
end
def notify_readable
@resolver.ioevent
end
end
EM.run do
resolver = EM::Udns::Resolver.new
EM.watch resolver.fd, UdnsWatcher, resolver do |conn|
conn.notify_readable = true
end
query = EM::Udns::Query.new
query.submit_A resolver, domain
query.callback do |result|
puts “DEFERRABLE CALLBACK: result = #{result.inspect}”
end
end
-
“Resolver” class is my C extension which wraps a C struct
‘dns_context’, no more Ruby objects for now.
-
“Query” class is pure Ruby and includes EM::Deferrable (it has nothing
else).
-
“query.submit_A resolver, domain” invokes a function of udns C
library:
VALUE Query_submit_query_A(VALUE self, VALUE context, VALUE str)
{
struct dns_ctx *dns_context = NULL;
char *domain;
Data_Get_Struct(context, struct dns_ctx, dns_context);
domain = StringValueCStr(str);
dns_submit_a4(dns_context, domain, 0, dns_res_A_cb, (void*)self);
[...]
}
As you can see “self” is passed as argument to dns_submit_a4(). This
is because when the DNS response arrives, a callback “dns_res_A_cb()”
function will be called, and that function contains as argument the
same (void*)self so I can know which Query instance the response
belongs to, and can invoke “set_deferred_status” by using
rb_funcall().
But in my above Ruby code I don’t store “query” in a hash or array, so
it could be GC’ed before the DNS response arrives, so when the
callback is called I’d get a coredump. I don’t want to store “query”
in a Hash or Array since it requires inserting and deleting it (so
wasted time), I just want “query” not to be GC’ed until udns callback
function is executed.
So, if I include rb_gc_mark(self) in Query_submit_query_A() function,
would it prevent “query” from being GC’ed?
But in this case, how to unmark it so it can be GC’ed after query
completes? wouldn’t leak if not? (note that Resolver instance lives
forever.
Thanks a lot.