Tcl_LimitCheck(3tcl)
π Tcl_LimitCheck β the Tcl Library Procedures glow-up π
okay bestie, so this one is Tcl_LimitCheck(3tcl) from the Tcl Library Procedures and it's literally the whole β¨resource limitsβ¨ subsystem for interpreters. it's giving "let me put a leash on this script before it eats my whole CPU" and honestly? iconic. π
β¨ NAME β¨
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 β manage and check resource limits on interpreters π«Ά
β¨ 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 that's about to get its limits checked. it's the main character here πint type(in) β which kind of limit the operation is talking about. it must be eitherTCL_LIMIT_COMMANDSorTCL_LIMIT_TIME. no third option, bestie, that's the whole list.Tcl_Size commandLimit(in) β the max number of commands that may be executed in the interpreter (counted the wayinfo cmdcountreports it). so like, the vibe ceiling. πΈTcl_Time *timeLimitPtr(in/out) β a pointer to a struct that either gets the new time limit read from it (Tcl_LimitSetTime) or gets the current time limit written to it (Tcl_LimitGetTime). yes it swings both ways, we love a versatile king πint granularity(in) β a divisor saying how often a particular limit should actually get checked. must be at least1. (zero would be a crime, do not.) πTcl_LimitHandlerProc *handlerProc(in) β the function to call when a particular limit is exceeded. and here's the juicy part: if thehandlerProcremoves or raises the limit while it's running, the limited interpreter is allowed to keep on processing after the handler returns. also, you can attach many handlers to the same interpreter limit β their order of execution is not defined, and they have to be identified byhandlerProcandclientDatawhen you delete them. so keep receipts, fr fr πvoid *clientData(in) β an arbitrary pointer-sized word used to pass some context to thehandlerProcfunction. the little handbag of extra info. πTcl_LimitHandlerDeleteProc *deleteProc(in) β the function to call whenever a handler gets deleted. it may beNULLif theclientDatadoesn't need any deletion. π
β¨ DESCRIPTION β¨
Tcl's interpreter resource limit subsystem lets you keep close control over how much computation time a script is allowed to use. it's super useful when a program is split into multiple pieces and some pieces are more trusted than others (think: web application servers π). some parts get the keys to the house, some parts get a timer. π
Every interpreter can have a limit on the wall-time for execution, and a limit on the number of commands the interpreter may execute. but here's the thing β checking these limits is potentially expensive (especially the time limit, she's high maintenance π
). so each limit also has a checking granularity, which is a divisor for an internal count of the number of points in the core where a check may be performed. and where are those points? immediately before executing a command, and at an unspecified frequency between running commands (which can happen in empty-bodied while loops β sneaky little things). π¦
The final component of the limit engine is a callback scheme, which lets you get notified when a limit has been exceeded. these callbacks can just do some logging, or they can allocate more resources to the interpreter so it's permitted to keep processing longer. generous queen behavior. π
When a limit is exceeded (and the callbacks have run β and reminder, the order the callbacks run in 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. so catch can't save you here, bestie, it's blocked. π€ it's up to the context that started execution in that interpreter (typically the main interpreter) to handle the error.
β¨ 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 also gets placed in the interpreter result. π¬
but babes, only call that function when Tcl_LimitReady returns non-zero, so the granularity policy is enforced. that's the rule. π¨
this API is designed to be similar in usage to Tcl_AsyncReady and Tcl_AsyncInvoke, iykyk.
When you're writing code that might behave like catch with respect to 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. let it go, let it flow, do not intercept. π you can also check whether a particular type of limit has been exceeded using Tcl_LimitTypeExceeded.
β¨ LIMIT CONFIGURATION β¨
To check whether a limit has been set (not whether it's actually been exceeded β different thing, bestie) on an interpreter, call Tcl_LimitTypeEnabled with the type of limit you want to check.
- to enable a particular limit, call
Tcl_LimitTypeSet - to disable a limit, call
Tcl_LimitTypeReset
The level of a command limit can be set using Tcl_LimitSetCommands, and retrieved using Tcl_LimitGetCommands. same deal for a time limit with Tcl_LimitSetTime and Tcl_LimitGetTime respectively β except with that API, the time limit is copied from and to the Tcl_Time structure that the timeLimitPtr argument points to. struct handoff, love that for us. π«±
The checking granularity for a particular limit can be set using Tcl_LimitSetGranularity and retrieved using Tcl_LimitGetGranularity.
note: granularities must always be positive. always. no exceptions. β¨
πΈ LIMIT CALLBACKS πΈ
To add a handler callback that gets invoked when a limit is exceeded, call Tcl_LimitAddHandler. the handlerProc argument describes the function that will actually be called, and it should have this prototype:
typedef void Tcl_LimitHandlerProc(
void *clientData,
Tcl_Interp *interp);
The clientData argument that gets passed to the handler will be whatever you passed to the clientData argument of Tcl_LimitAddHandler, and the interp is the interpreter that had its limit exceeded. π
The deleteProc argument to Tcl_LimitAddHandler is a function to call in order to delete the clientData value. it may be:
TCL_STATICorNULLif no deletion action is necessaryTCL_DYNAMICif all that's necessary is to free the structure withTcl_Free
otherwise, it should refer to a function with this 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. first come, first yeeted. π this function always invokes the deleteProc on the clientData β unless the deleteProc was NULL or TCL_STATIC.
β¨ KEYWORDS β¨
okay bestie, final section, and it's literally just the vibe tags for this page β the little search terms so future you (or man -k) can find it again when your brain is mush π
interpreterπΈresourceπlimitπcommandsβ¨timeβ°callbackπ«Ά
that's the whole list, no cap. six words, all of them doing their little search-engine job so this page doesn't get lost in the void π
and that's a wrap on Tcl_LimitCheck(3tcl), bestie π you made it to the end of the whole page β go set some limits, protect your interpreter, and slay responsibly ππ
this page shipped with Tcl 8.5 β yes, 8.5, she's an icon and she's been iconic π¦ mwah, see you in the next manpage β
π¦ where this page comes from
- 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) 2004 Donal K. Fellows
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms