Finalize.mesa
Copyright Ó 1987, 1991 by Xerox Corporation. All rights reserved.
Weiser, March 6, 1989 3:47:28 pm PST
Demers, March 28, 1989 11:34:26 am PST
Willie-s, August 6, 1991 1:13 pm PDT
Christian Jacobi, July 20, 1992 11:14 am PDT
Finalize: CEDAR DEFINITIONS ~ BEGIN
Types
Handle: TYPE ~ REF FinalizableObject;
FinalizableObject: TYPE;
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).
IsHandle: PROC [x: REF] RETURNS [BOOL];
Like ISTYPE[x, Handle]
NarrowHandle: PROC [x: REF] RETURNS [Handle];
Like NARROW[x, Handle]
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.
END.