On Thu, May 07, 2015 at 01:02:13PM -0400, Rafael Schloming wrote:
> The way the python code does this is by checking whenever a C object is
> returned to python code. If the record contains an attachment indicating
> that the C object has previously been wrapped, it uses this to
> construct/retrieve an appropriate wrapper object. If it doesn't have the
> appropriate attachment then it uses the record API to define/set the
> attachment to the appropriate value. I presume you could do something
> similar with ruby.

After we chatted the other day, I've tried the following approach, using
the pn_transport_t type as my test bed since it has relatively fewer
dependencies. However, the plumbing in Proton for objects isn't quite
clear to me and my code's not quite working the way we had discussed and
I'm not sure why.

The goal is to have a type that will live for as long as one of the
impls in Proton lives; i.e., when we create something like
pn_transport_t, the attachment created for this would hold some type
that will get finalized when the pn_transport_t type is finalized. And
that type would be the hook to clean up the single instance of a Ruby
class that wraps the underlying C type.

I've created a new type in the ruby.i descriptor for Swig and named it
pn_rbkey_t, with three files: void* registry (a pointer to an object
held in Ruby), char* method (the name of a method to invoke on that
object), and char* key_value (the argument to be passed to that method).

The code defines pn_rbkey_initialize and pn_rbkey_finalize methods, as
well as getter and setter methods for the three fields. But I've put
debugging into the code and never see the pn_rbkey_finalize method being
invoked.

My registry_test app does the following:

1. create an instance of pn_transport_t: impl = Cproton.pn_transport
2. create a Ruby Transport object: transport =  Transport.wrap(impl)
   a. puts a weak reference to the Transport into the hashtable
   b. creates a pn_rbkey_t object and sets it as the sole record for the
      pn_transport_t object
   c. calls Cproton.pn_incref on the pn_rbkey_t instance
3. remove the reference: transport = nil
4. call garbage collection: ObjectSpace.garbage_collect
5. get the object back: transport = Transport.wrap(impl)
   a. calls pn_transport_attachment and retrieves the record created in 2
   b. should then be able to get the key_value from the pn_rbkey_t type
   c. should then get the object out of the hashtable to return

It's at step 5 that the example app segfaults. The segfault happens
when, from Ruby, there's a call to print the attachment retrieve in 5a.
Swig isn't failing since it's returning a value that seems to have been
cached. But when Swig tries to retrieve data from the pn_rbkey_t struct
underneath of it, *THAT* seems to have been reaped by Proton and Swig
then segfaults, thinking there was an object still under the covers.

Any ideas or suggestions of where to look for what's going on?

-- 
Darryl L. Pierce, Sr. Software Engineer @ Red Hat, Inc.
Delivering value year after year.
Red Hat ranks #1 in value among software vendors.
http://www.redhat.com/promo/vendor/

Attachment: pgpmyZ1IC9zbA.pgp
Description: PGP signature

Reply via email to