Tcl_Preserve(3) Tcl Library Procedures Tcl_Preserve(3)

____________________________________________________________________________

NAME


Tcl_Preserve, Tcl_Release, Tcl_EventuallyFree - avoid freeing storage
while it is 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 reallocated.
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 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. 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 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 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

Tcl 7.5 Tcl_Preserve(3)

tribblix@gmail.com :: GitHub :: Privacy