Tcl_Preserve(3tcl)
π Tcl_Preserve β the manual page, but make it a group chat π
okay bestie so this is from the Tcl Library Procedures manual, and it's about three little functions that keep your memory from getting yanked out from under you mid-sentence. genuinely iconic behaviour tbh. π«Ά
β¨ NAME β¨
Tcl_Preserve, Tcl_Release, Tcl_EventuallyFree β avoid freeing storage while it is being used
like... don't delete the thing while somebody's still holding it, okay?? that's the whole vibe. π
πΈ SYNOPSIS πΈ
#include <tcl.h>
Tcl_Preserve(clientData)
Tcl_Release(clientData)
Tcl_EventuallyFree(clientData, freeProc)
π¦ ARGUMENTS π¦
void *clientData(in) β a token that describes the structure that's gonna get freed or reallocated. usually it's just a pointer to the memory for that structure. πTcl_FreeProc *freeProc(in) β the procedure you invoke to freeclientData.
π DESCRIPTION π
okay so these three procedures help you implement a simple reference count mechanism for managing storage. they were literally designed to solve a problem about widget deletion, but ngl they're useful in a whole bunch of other situations too. β¨
here's the drama: when a widget gets deleted, its widget record (that's the structure holding all the info specific to that widget) has to go back to the storage allocator. but β and this is the messy part β it's totally possible that the widget record is still in active use by one of the procedures on the stack at the moment of deletion. π
when does that even happen?? okay imagine: 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 get invoked, which causes the button's associated Tcl command to be executed, which causes the button to be deleted, which causes the button's widget record to be de-allocated. chain reaction, main character energy. π₯
but then, unfortunately, when the Tcl command returns, the button's event-handling procedure is still gonna need to reference the button's widget record. so because of that, the widget record must not be freed as part of the deletion β it has to be retained until the event-handling procedure has finished with it. meanwhile in other situations where a widget is deleted, it might be totally fine to free the widget record immediately. it's giving "it depends". π
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. these reference counts guarantee that an object will not be freed until each call to Tcl_Preserve for that object has been matched by calls to Tcl_Release. and bestie, there may be any number of unmatched Tcl_Preserve calls in effect at once. no cap. π«Ά
Tcl_EventuallyFree is the one you invoke to free up its clientData argument. it checks to see if there are unmatched Tcl_Preserve calls for the object:
- if there are not, then
Tcl_EventuallyFreecallsfreeProcimmediately. slay. - otherwise,
Tcl_EventuallyFreerecords the fact thatclientDataneeds eventually to be freed. then, when all calls toTcl_Preservehave been matched with calls toTcl_Release,freeProcwill be called byTcl_Releaseto 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(
void *blockPtr);
the blockPtr argument to freeProc will be the same as the clientData argument to Tcl_EventuallyFree. β¨
when the clientData argument to Tcl_EventuallyFree refers to storage allocated and returned by a prior call to Tcl_Alloc 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.
β οΈ heads up bestie: this 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. so don't try it. π
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. lowkey elegant tbh. π§
π SEE ALSO π
Tcl_InterpTcl_Alloc
β KEYWORDS β
free, reference count, storage
and that's the whole page, bestie β brought to you by the Tcl 7.5 era of the Tcl_Preserve(3tcl) page, π periodt π
π¦ where this page comes from
- debian trixie: tcl9.0-doc 9.0.1+dfsg-2
- ubuntu questing: tcl9.0-doc 9.0.2+dfsg-1
- ubuntu resolute: tcl9.0-doc 9.0.3+dfsg-1
- ubuntu stonking: tcl9.0-doc 9.0.4+dfsg-1
- Copyright (c) 1990 The Regents of the University of California
- Copyright (c) 1994-1996 Sun Microsystems, Inc
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms