Tcl_Preserve(3) Tcl Library Procedures Tcl_Preserve(3)
Tcl_Preserve, Tcl_Release, Tcl_EventuallyFree - avoid freeing storage while it is being
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.
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 is 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 widget 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. Unfortu-
nately, 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 deletion, but must be retained until the event-handling procedure 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 reference 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_EventuallyFree
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 argu-
ments 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_Even-
tuallyFree. 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.
free, reference count, storage
Tcl 7.5 Tcl_Preserve(3)