Skip to content

Instantly share code, notes, and snippets.

Created January 30, 2013 13:26
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save anonymous/4673294 to your computer and use it in GitHub Desktop.
Save anonymous/4673294 to your computer and use it in GitHub Desktop.
Proposed NativeCall object lifecycle changes

Better handling of C objects' lifecycle

To handle certain kinds of operations better (and not leak memory), NativeCall needs to be able to control the lifecycle of objects. Specifically, we need to be able to relinquish control of memory allocated on the Perl side (so that it can be handed to C code), and the ability to take responsibility for a chunk of memory (so that it will be freed when the object is GCed.

To do this, I suggest adding two new functions, adopt() and disown(), and reworking the string marshalling rules.

adopt() and disown()

These two functions do what you'd expect. adopt() assumes control of the memory allocated by the object, indicating that it should be freed when the object is GCed. disown() releases control, so that the memory is untouched on GC. Neither function should apply recursively to the members of structs or arrays.

NativeCall objects created in Perl 6 will be adopted by default, and those returned from C will be disowned by default.

Implementation-wise, I expect to add a flag for adoption state in the dyncall REPR types and NQP ops for setting it. Zavolaj will then only need to expose the ops through the functions.

String handling

explicitly-manage() is terribly named, not very elegant, and I don't like it much. So we'll remove it and replace it with something else.

Under the new scheme, a normal Str object passed to a native function will be marshalled to a temporary string buffer which is sent to C and immediately freed after the function returns. No exceptions.

If you need more expressive handling than that, I propose adding a new standard class (a la OpaquePointer): CStr, which will be backed by a reworked CStr REPR (which we have from our current explicitly-manage() scheme). Functionally, it will be similar to a CArray[int8], but with some additional functionality to work with string semantics. Objects of this class will be normal NativeCall objects that can be adopted and disowned.

Implementation-wise, this'll require reworking the CStr REPR and adding a class to Zavolaj doing the necessary NQP/6model plumbing.

@FROGGS
Copy link

FROGGS commented Jan 30, 2013

+1

What I just want to mention: For the SDL Perl 5 module we wrapped the C-Objects, to attach information to it. This included an identifier of the thread which created the object. Only this thread was allowed to free an object when its refcount was zero. I have no clue if this applies to Perl 6's threading models, but I still wanted to tell.

Btw, in case I have a C-Object, that keeps pointers to other C-Objetcs, has Zavolay the capabilities to adopt/disown a tree of objects? Since I cant free child-objects that are referenced by parents I (Perl) dont own.

@arnsholt
Copy link

I'm not sure anyone knows what the Perl 6 threading model will look like, so that's probably an issue we're going to have to revisit. Good point.

My idea was that adopt/disown only tweak a single object, not a whole tree. If you want to adopt or disown a whole object graph, I think that should be the responsibility of user code. Especially if we ever run into complicated structures like cyclic graphs, which would mean that the adopt/disown code has to be more complicated than I like.

Of course, we might want to supply additional recursive variants to traverse a full non-cyclic graph.

@FROGGS
Copy link

FROGGS commented Jan 30, 2013

Right, thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment