SMOP REFERENCE and RELEASE Policy: Revision 10
All files were reviewed, SMOP is valgrind-clean at the moment.
Even if not all object systems use reference counting garbage collection, the possible existance of some object system that does, requires us to implement the mechanisms that make it possible. That is why, besides MESSAGE, two other functions are defined in the responder interface lowlevel type. The REFERENCE and RELEASE functions. This functions are supposed to be the hooks for implementing a refcount garbage collector.
Who owns the object?
This is the most important question in the matter of when to call REFERENCE and when to call RELEASE. And a simple policy shall describe this decision:
What does it mean?
Simple as: every time you pass an object as an argument to a call, the object will belong to the called method and you will no longer be allowed to use the object. Unless, of course, you pass it while defining a new REFERENCE. A little code to illustrate:
SMOP__Object* foo = smop_lowlevel_alloc(sizeof(SMOP__Object)); // the object is owned by the current code. // if you want to be able to use the object after passing it to // a capture, you must reference it. SMOP__Object* cap = SMOP__NATIVE__capture_create(intr, SMOP_REFERENCE(intr,foo), NULL, NULL); // but if you won't need the object in this code anymore, you can // save a little effort and just do. SMOP__Object* cap2 = SMOP__NATIVE__capture_create(intr, foo, NULL, NULL); // but Objects that you own must be released when you don't need them // anymore. SMOP_RELEASE(intr, cap); SMOP_RELEASE(intr, cap2);
The same concept is valid for the capture itself, when you pass a capture in a DISPATCH, you're implying transfer of ownership. Some code to illustrate it:
// The capture object is owned by the current code. SMOP__Object* cap = SMOP__NATIVE__capture_create(intr, NULL, NULL, NULL); // if you want to use it later, you must reference it. SMOP_DISPATCH(..., SMOP_REFERENCE(intr,cap)); // but when you won't use it later, you can simply // pass it along, and the called method should release // it when its not needed anymore SMOP_DISPATCH(..., cap);