Tcl_LimitCheck(3)
π NAME π
Okay bestie, welcome to the Tcl_LimitCheck(3) manual page from the Tcl Library Procedures! This whole page is about managing and checking resource limits on interpreters. The squad of functions here is: Tcl_LimitAddHandler, Tcl_LimitCheck, Tcl_LimitExceeded, Tcl_LimitGetCommands, Tcl_LimitGetGranularity, Tcl_LimitGetTime, Tcl_LimitReady, Tcl_LimitRemoveHandler, Tcl_LimitSetCommands, Tcl_LimitSetGranularity, Tcl_LimitSetTime, Tcl_LimitTypeEnabled, Tcl_LimitTypeExceeded, Tcl_LimitTypeReset, Tcl_LimitTypeSet.
πΈ SYNOPSIS πΈ
#include <tcl.h>
int
Tcl_LimitCheck(interp)
int
Tcl_LimitReady(interp)
int
Tcl_LimitExceeded(interp)
int
Tcl_LimitTypeExceeded(interp, type)
int
Tcl_LimitTypeEnabled(interp, type)
Tcl_LimitTypeSet(interp, type)
Tcl_LimitTypeReset(interp, type)
Tcl_Size
Tcl_LimitGetCommands(interp)
Tcl_LimitSetCommands(interp, commandLimit)
Tcl_LimitGetTime(interp, timeLimitPtr)
Tcl_LimitSetTime(interp, timeLimitPtr)
int
Tcl_LimitGetGranularity(interp, type)
Tcl_LimitSetGranularity(interp, type, granularity)
Tcl_LimitAddHandler(interp, type, handlerProc, clientData, deleteProc)
Tcl_LimitRemoveHandler(interp, type, handlerProc, clientData)
π ARGUMENTS π
Tcl_Interp *interp(in) β The interpreter that the limit being managed applies to, or the one whose limits are about to get checked. It's the main character here. πint type(in) β The type of limit the operation is referring to. It has to be eitherTCL_LIMIT_COMMANDSorTCL_LIMIT_TIME. No other vibes allowed.Tcl_Size commandLimit(in) β The max number of commands that may be executed in the interpreter, as reported byinfo cmdcount. So like, the command budget, bestie.Tcl_Time *timeLimitPtr(in/out) β A pointer to a structure that either has the new time limit read from it (Tcl_LimitSetTime) or gets the current time limit written to it (Tcl_LimitGetTime). It's giving in/out energy.int granularity(in) β A divisor that says how often a particular limit should really be checked. Must be at least1. Do not test it with zero, I'm begging. πTcl_LimitHandlerProc *handlerProc(in) β The function to call when a particular limit is exceeded. If thehandlerProcremoves or raises the limit while it's processing, the limited interpreter will be permitted to continue processing after the handler returns. Many handlers may be attached to the same interpreter limit; their order of execution is not defined, and they must be identified byhandlerProcandclientDatawhen they are deleted.void *clientData(in) β An arbitrary pointer-sized word used to pass some context to thehandlerProcfunction. It's the little backpack of data. πTcl_LimitHandlerDeleteProc *deleteProc(in) β The function to call whenever a handler is deleted. May beNULLif theclientDatarequires no deletion. Lowkey optional, highkey useful.
π¦ DESCRIPTION π¦
Tcl's interpreter resource limit subsystem lets you have close control over how much computation time a script may use. It's super useful when a program is split into multiple pieces and some parts are more trusted than others (e.g. web application servers). Not all code is your bestie, and that's okay. π
Every interpreter may have a limit on the wall-time for execution, and a limit on the number of commands that the interpreter may execute. Since checking these limits is potentially expensive (especially the time limit), each limit also has a checking granularity. That granularity is a divisor for an internal count of the number of points in the core where a check may be performed β which is immediately before executing a command and at an unspecified frequency between running commands, which can happen in empty-bodied while loops. So yeah, it's not checking at every possible point, because that would be a lot. π«
The final component of the limit engine is a callback scheme. It allows for notifications of when a limit has been exceeded. These callbacks can just provide logging, or they may allocate more resources to the interpreter to permit it to continue processing longer. So they can be chill little note-takers or full-on resource fairies. π§
When a limit is exceeded (and the callbacks have run; the order of execution of the callbacks is unspecified) execution in the limited interpreter is stopped by raising an error and setting a flag that prevents the catch command in that interpreter from trapping that error. It is up to the context that started execution in that interpreter (typically the main interpreter) to handle the error. So like, catch cannot save you here β the error has to go up to the grown-ups. π
π₯ LIMIT CHECKING API π₯
To check the resource limits for an interpreter, call Tcl_LimitCheck. It returns TCL_OK if the limit was not exceeded (after processing callbacks) and TCL_ERROR if the limit was exceeded β in which case an error message is also placed in the interpreter result. That function should only be called when Tcl_LimitReady returns non-zero so that granularity policy is enforced. This API is designed to be similar in usage to Tcl_AsyncReady and Tcl_AsyncInvoke. Iconic sister APIs, honestly. β¨
When writing code that may behave like catch in respect of errors, you should only trap an error if Tcl_LimitExceeded returns zero. If it returns non-zero, the interpreter is in a limit-exceeded state and errors should be allowed to propagate to the calling context. You can also check whether a particular type of limit has been exceeded using Tcl_LimitTypeExceeded. No sneaky trapping, bestie. Let it propagate. π
π LIMIT CONFIGURATION π
To check whether a limit has been set (but not whether it has actually been exceeded) on an interpreter, call Tcl_LimitTypeEnabled with the type of limit you want to check. To enable a particular limit call Tcl_LimitTypeSet, and to disable a limit call Tcl_LimitTypeReset. It's the on/off switch energy. π
The level of a command limit may be set using Tcl_LimitSetCommands, and retrieved using Tcl_LimitGetCommands. Similarly for a time limit with Tcl_LimitSetTime and Tcl_LimitGetTime respectively, but with that API the time limit is copied from and to the Tcl_Time structure that the timeLimitPtr argument points to. So it's not just a number, it's a whole struct moment. β°
The checking granularity for a particular limit may be set using Tcl_LimitSetGranularity and retrieved using Tcl_LimitGetGranularity. Note that granularities must always be positive. Always. Positive. Periodt. π©·
π§ LIMIT CALLBACKS π§
To add a handler callback to be invoked when a limit is exceeded, call Tcl_LimitAddHandler. The handlerProc argument describes the function that will actually be called; it should have the following prototype:
typedef void Tcl_LimitHandlerProc(
void *clientData,
Tcl_Interp *interp);
The clientData argument to the handler will be whatever is passed to the clientData argument to Tcl_LimitAddHandler, and the interp is the interpreter that had its limit exceeded. So the handler knows exactly which interpreter is going through it. π
The deleteProc argument to Tcl_LimitAddHandler is a function to call to delete the clientData value. It may be TCL_STATIC or NULL if no deletion action is necessary, or TCL_DYNAMIC if all that is necessary is to free the structure with Tcl_Free. Otherwise, it should refer to a function with the following prototype:
typedef void Tcl_LimitHandlerDeleteProc(
void *clientData);
A limit handler may be deleted using Tcl_LimitRemoveHandler; the handler removed will be the first one found (out of the handlers added with Tcl_LimitAddHandler) with exactly matching type, handlerProc and clientData arguments. This function always invokes the deleteProc on the clientData (unless the deleteProc was NULL or TCL_STATIC). So if you're deleting, be precise, bestie β it's matching on all three. π―
β¨ KEYWORDS β¨
ok so these are the lil search terms bestie π β the words you'd type into man -k or throw at your brain when you're trying to remember what this page was even called:
interpreterπresourceπlimitβ¨commandsπΈtimeβ°callbackπ¦
like that's the whole vibe. six words. iconic. no cap. π
and that's a wrap on Tcl_LimitCheck(3), bestie π«Ά you made it to the end, so proud of you fr fr ππ this lil beauty ships out of the Tcl 8.5 era β go check the footer if you don't believe me, it's right there in the source and version line, date and all πβ now go forth and not blow your interpreter's budget, mwah π
π
π¦ where this page comes from
- alpine 3.23: tcl9-doc 9.0.3-r0 Β· TCL
- alpine 3.24: tcl9-doc 9.0.3-r2 Β· TCL
- fedora 43: tcl-doc 1:9.0.2-1.fc43 Β· TCL AND GPL-3.0-or-later WITH Bison-exception-2.2 AND BSD-3-Clause
- fedora 44: tcl-doc 1:9.0.2-1.fc44 Β· TCL AND GPL-3.0-or-later WITH Bison-exception-2.2 AND BSD-3-Clause
- nixos 26.05: tcl 9.0.3
- nixpkgs unstable: tcl 9.1.0
- Copyright (c) 2004 Donal K. Fellows
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms