tcl_preserve(3)
NAME
Tcl_Preserve, Tcl_Release, Tcl_EventuallyFree - avoid
freeing storage while it's being used
SYNOPSIS
#include <tcl.h> Tcl_Preserve(clientData) Tcl_Release(clientData) Tcl_EventuallyFree(clientData, freeProc)
ARGUMENTS
- ClientData clientData (in) Token describing
- structure to be
freed or reallo
cated. Usually a
pointer to memory
for structure. - Tcl_FreeProc *freeProc (in) Procedure to invoke
- to free clientData.
DESCRIPTION
These three procedures help implement a simple reference
count mechanism for managing storage. They are designed
to solve a problem having to do with widget deletion, but
are also useful in many other situations. When a widget
is deleted, its widget record (the structure holding
information specific to the widget) must be returned to
the storage allocator. However, it's possible that the
widget record is in active use by one of the procedures on
the stack at the time of the deletion. This can happen,
for example, if the command associated with a button wid
get causes the button to be destroyed: an X event causes
an event-handling C procedure in the button to be invoked,
which in turn causes the button's associated Tcl command
to be executed, which in turn causes the button to be
deleted, which in turn causes the button's widget record
to be de-allocated. Unfortunately, when the Tcl command
returns, the button's event-handling procedure will need
to reference the button's widget record. Because of this,
the widget record must not be freed as part of the dele
tion, but must be retained until the event-handling proce
dure has finished with it. In other situations where the
widget is deleted, it may be possible to free the widget
record immediately.
Tcl_Preserve and Tcl_Release implement short-term refer
ence counts for their clientData argument. The clientData
argument identifies an object and usually consists of the
address of a structure. The reference counts guarantee
that an object will not be freed until each call to
Tcl_Preserve for the object has been matched by calls to
Tcl_Release. There may be any number of unmatched
Tcl_Preserve calls in effect at once.
Tcl_EventuallyFree is invoked to free up its clientData
argument. It checks to see if there are unmatched
Tcl_Preserve calls for the object. If not, then Tcl_Even
tuallyFree calls freeProc immediately. Otherwise
Tcl_EventuallyFree records the fact that clientData needs
eventually to be freed. When all calls to Tcl_Preserve
have been matched with calls to Tcl_Release then freeProc
will be called by Tcl_Release to do the cleanup.
- All the work of freeing the object is carried out by
freeProc. FreeProc must have arguments and result that match the type Tcl_FreeProc: - typedef void Tcl_FreeProc(char *blockPtr);
- The blockPtr argument to freeProc will be the same as the clientData argument to Tcl_EventuallyFree. The type of blockPtr (char *) is different than the type of the clientData argument to Tcl_EventuallyFree for historical reasons, but the value is the same.
- When the clientData argument to Tcl_EventuallyFree refers
to storage allocated and returned by a prior call to
Tcl_Alloc, ckalloc, or another function of the Tcl library, then the freeProc argument should be given the special value of TCL_DYNAMIC. - This mechanism can be used to solve the problem described
above by placing Tcl_Preserve and Tcl_Release calls around actions that may cause undesired storage re-allocation.
The mechanism is intended only for short-term use (i.e.
while procedures are pending on the stack); it will not
work efficiently as a mechanism for long-term reference
counts. The implementation does not depend in any way on
the internal structure of the objects being freed; it
keeps the reference counts in a separate structure.
SEE ALSO
Tcl_Interp, Tcl_Alloc
KEYWORDS
- free, reference count, storage