Extracted from Pike v7.6 release 61 at 2005-12-30.
pike.ida.liu.se
[Top]
lfun::

Method lfun::destroy()


Method destroy

void lfun::destroy()

Description

Object destruction callback.

This function is called by destruct() right before it zeroes all the object variables and destroys the object.

Note

Note that it's also called on implicit destruct, i.e. when there are no more references to the object, or when the garbage collector decides to destruct it.

Note

Regarding destruction order during garbage collection:

If an object is destructed by the garbage collector, it's part of a reference cycle with other things but with no external references. If there are other objects with destroy functions in the same cycle, it becomes a problem which to call first.

E.g. if this object has a variable with another object which (directly or indirectly) points back to this one, you might find that the other object already has been destructed and the variable thus contains zero.

The garbage collector tries to minimize such problems by defining an order as far as possible:

  • If an object A contains an lfun::destroy and an object B does not, then A is destructed before B.

  • If A references B single way, then A is destructed before B.

  • If A and B are in a cycle, and there is a reference somewhere from B to A that is weaker than any reference from A to B, then A is destructed before B.

  • Weak references (e.g. set with set_weak_flag() ) are considered weaker than normal references, and both are considered weaker than strong references.

  • Strong references are those from objects to the objects of their lexically surrounding classes. There can never be a cycle consisting only of strong references. (This means the gc never destructs a parent object before all children have been destructed.)

An example with well defined destruct order due to strong references:

class Super { class Sub { static void destroy() { if (!Super::this) error ("My parent has been destructed!\n"); } } Sub sub = Sub(); static void destroy() { if (!sub) werror ("sub already destructed.\n"); } }

The garbage collector ensures that these objects are destructed in an order so that werror in Super is called and not error in Sub.

Note

When the garbage collector calls lfun::destroy , all accessible non-objects and objects without destroy functions are still intact. They are not freed if the destroy function adds external references to them. However, all objects with lfun::destroy in the cycle are already scheduled for destruction and are thus be destroyed even if external references are added to them.

Note

The garbage collector had completely random destruct order in versions prior to 7.2.

See also

lfun::create() , destruct()