Beefy Boxes and Bandwidth Generously Provided by pair Networks
XP is just a number
 
PerlMonks  

comment on

( [id://3333]=superdoc: print w/replies, xml ) Need Help??

I thought this was an FAQ, but since I've not been able to find a single mention of the problem, I try here.

Suppose I have a C library like this:
typedef struct _person { char* name, ... } *person; typedef struct _record { int a, person *p ....} *record; int new_person(person *out_person_freeable, char *name....); int free_person(person p); int new_record(record *out_record, ....); int free_record(record r); /* free the contained person too */ int record_get_person(record r, person *out_person_notfreeable); /* out_person_notfreeable is owned by the record object and must not b +e freed */

In other words... There's several API calls. Sometime I get a pointer to an object I must free myself later - and at other times I just get to borrow a pointer to a "person" and must NOT free it.

I want to expose "person" and "record" objects to Perl through XS.

So I have an XS wrapper whit a typemap converting the returned pointers to IV and returning a blessed reference to the pointer:

OUTPUT T_MYOBJPRT sv_setref_pv($arg, \"${ntype}\", (void*)$var);

This all works fine. But when such an object reached refcount 0 and DESTROY is called I have to decide whether to call the C library free_*() functions.

And the problem is that I can't see when I get a "person" pointer I get back in DESTROY whether I'm allowed to free it.

Free'ing all "person" pointers would corrupt "record" objects still alive. Not free'ing them would leak. I would have thought there was an idiomatic way of doing this. But I haven't found one. One solution I could imagine is to use PERL_MAGIC_ext and make a note about whether to free or not. But Magic doesn't survive assignments, so it's easy to loose that information as the object is handled in Perl code.

Also, - it have to take into account both the scenarios where "record" survives the "person" and where "person" survives the "record". I know that latter is not how you would normally use this in C, but Perl code usually expects to be able to take any reference it gets with it an let reference counting handle postponing any cleanup.

So: The hackerish solution... What if the XS function returning a "person" which must not be free'd incremented the reference count on the "record" SV (thus postponing its deletion) and at the same time put a pointer to the "record" SV into the NV slot of the "person" SV. ... so when I get a "person" SV in DESTROY, I check whether it has a NV value and if it does, I don't delete it, but instead decrement the reference count on the SV pointed to by the NV value?

It's a hack ... but I don't see where else to store the back-reference for making reference counting handling this. (weakening doesn't survive copy either). NV values seem to survive assignment

But surely, there's an official recommended way to do this? ;-)


In reply to Managing C library memory in XS by petermogensen

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post; it's "PerlMonks-approved HTML":



  • Are you posting in the right place? Check out Where do I post X? to know for sure.
  • Posts may use any of the Perl Monks Approved HTML tags. Currently these include the following:
    <code> <a> <b> <big> <blockquote> <br /> <dd> <dl> <dt> <em> <font> <h1> <h2> <h3> <h4> <h5> <h6> <hr /> <i> <li> <nbsp> <ol> <p> <small> <strike> <strong> <sub> <sup> <table> <td> <th> <tr> <tt> <u> <ul>
  • Snippets of code should be wrapped in <code> tags not <pre> tags. In fact, <pre> tags should generally be avoided. If they must be used, extreme care should be taken to ensure that their contents do not have long lines (<70 chars), in order to prevent horizontal scrolling (and possible janitor intervention).
  • Want more info? How to link or How to display code and escape characters are good places to start.
Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others scrutinizing the Monastery: (5)
As of 2024-03-19 08:22 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found