Types
Handle: TYPE ~ REF FinalizableObject;
FinalizationQueue: TYPE ~ REF FinalizationQueueRep;
FinalizationQueueRep:
TYPE;
FinalizationState:
TYPE ~
MACHINE
DEPENDENT {
enabled(0), -- waiting for all REFs to disappear
onFQ(1), -- on a finalization queue
disabled(2), -- none of the above
error(CARDINAL.LAST)
};
A handle is a "disguised" REF to an object. It can be converted to an ordinary REF using HandleToObject, below.
An object is guaranteed not to be garbage collected while there exist handles to it.
A handle may be in one of three states: enabled, onFQ, or disabled. When in the enabled or onFQ state, a handle has a FinalizationQueue associated with it.
- A handle in the enabled state is awaiting finalization. It will remain in the enabled state until there are no remaining undisguised REFs or non-enabled handles referring to its object; the system will then put the handle on its associated FinalizationQueue and change its state to onFQ.
- A handle in the onFQ state is on a FinalizationQueue. It will remain there until removed, either explicitly using FQNext, or implicitly by DisableFinalization or ReenableFinalization.
- A handle in the disabled state is neither awaiting finalization nor on a FinalizationQueue. Such a handle can still be converted to a REF (using HandleToObject), and it prevents the associated object from being garbage collected or finalized (even if there is some other handle in the enabled state).
Finalization Control
EnableFinalization:
PROC [object:
REF, fq: FinalizationQueue, clientData:
REF ¬
NIL]
RETURNS [handle: Handle];
Register object for finalization, returning a handle in enabled state. ClientData is stored for the benefit of the caller.
DisableFinalization:
PROC [handle: Handle]
RETURNS [oldState: FinalizationState];
Disable finalization for handle, returning its previous finalization state.
If handle was on a finalization queue, this removes it from the queue.
ReenableFinalization:
PROC [handle: Handle, fq: FinalizationQueue]
RETURNS [oldState: FinalizationState];
Reenable finalization for handle, returning its previous finalization state .
If handle was on a finalization queue, this removes it from the queue.
GetFinalizationState:
PROC [handle: Handle]
RETURNS [state: FinalizationState];
Return the finalization state of handle. The state is computed atomically, but it is subject to change; e.g. it can change spontaneously from enabled to onFQ, and other transitions are possible as a result of calls to DisableFinalization, ReenableFinalization, or FQNext.
HandleToObject:
PROC [handle: Handle]
RETURNS [object:
REF];
Take a Handle and return the associated object.
GetClientData:
PROC [handle: Handle]
RETURNS [
REF];
Returns client client data associated with handle.
Finalization Queue Manipulation
NewFQ:
PROC
RETURNS [FinalizationQueue];
Return a new FinalizationQueue.
FQNext:
PROC [fq: FinalizationQueue]
RETURNS[handle: Handle];
Wait (with ABORTs enabled) for fq to be non-empty, then dequeue and return the first entry.
FQNextNoAbort:
PROC [fq: FinalizationQueue]
RETURNS[handle: Handle ¬
NIL];
Equivalent to FQNext with a catch phrase for ABORTED that just returns NIL.
FQEmpty:
PROC [fq: FinalizationQueue]
RETURNS[
BOOL];
Test whether fq is empty.