Notifier(3)
okay bestie, grab your boba π§ because we're doing Notifier(3) from the Tcl Library Procedures and it's a whole thing β it's the event queue and notifier interfaces, and honestly? it's giving foundational. lowkey the backbone of everything. let's go π
β¨ NAME β¨
So basically, this one page covers a whole squad of procedures, and they're all about the event queue and notifier interfaces:
Tcl_CreateEventSource, Tcl_DeleteEventSource, Tcl_SetMaxBlockTime, Tcl_QueueEvent, Tcl_ThreadQueueEvent, Tcl_ThreadAlert, Tcl_GetCurrentThread, Tcl_DeleteEvents, Tcl_InitNotifier, Tcl_FinalizeNotifier, Tcl_WaitForEvent, Tcl_AlertNotifier, Tcl_SetTimer, Tcl_ServiceAll, Tcl_ServiceEvent, Tcl_GetServiceMode, Tcl_SetServiceMode, Tcl_ServiceModeHook, Tcl_SetNotifier
that's the roster. iconic lineup, no cap π
πΈ SYNOPSIS πΈ
#include <tcl.h>
Tcl_CreateEventSource(setupProc, checkProc, clientData)
Tcl_DeleteEventSource(setupProc, checkProc, clientData)
Tcl_SetMaxBlockTime(timePtr)
Tcl_QueueEvent(evPtr, position)
Tcl_ThreadQueueEvent(threadId, evPtr, position)
Tcl_ThreadAlert(threadId)
Tcl_ThreadId
Tcl_GetCurrentThread()
Tcl_DeleteEvents(deleteProc, clientData)
void *
Tcl_InitNotifier()
Tcl_FinalizeNotifier(clientData)
int
Tcl_WaitForEvent(timePtr)
Tcl_AlertNotifier(clientData)
Tcl_SetTimer(timePtr)
int
Tcl_ServiceAll()
int
Tcl_ServiceEvent(flags)
int
Tcl_GetServiceMode()
int
Tcl_SetServiceMode(mode)
Tcl_ServiceModeHook(mode)
Tcl_SetNotifier(notifierProcPtr)
π ARGUMENTS π
okay here's who's who and what they actually do, bestie:
Tcl_EventSetupProc *setupProc(in) β the procedure you invoke to get everything ready for the event wait insideTcl_DoOneEvent. it's the little pre-game ritual β¨Tcl_EventCheckProc *checkProc(in) β the procedureTcl_DoOneEventinvokes after it's waited for events. it checks whether any events actually happened, and if they did, it queues them up. no skipping this step π«Άvoid *clientData(in) β some arbitrary one-word value you pass along tosetupProc,checkProc, ordeleteProc. it's the little "hey, this is yours" sticky note πconst Tcl_Time *timePtr(in) β tells you the maximum amount of time to wait for an event. important distinction: this is an interval (how long to wait), not an absolute time (when to wake up). and if the pointer you hand toTcl_WaitForEventisNULL? that means there is no maximum wait time β wait forever if necessary. main character energy, honestly, just vibing for eternity πTcl_Event *evPtr(in) β an event you're adding to the event queue. heads up though: the storage for the event must have been allocated by the caller usingTcl_Alloc. don't get cute with it πint position(in) β where the new event goes in the queue:TCL_QUEUE_TAIL,TCL_QUEUE_HEAD,TCL_QUEUE_MARK, plus whether to do an alert if the queue is empty:TCL_QUEUE_ALERT_IF_EMPTY. so many options, so much power πTcl_ThreadId threadId(in) β a unique identifier for a thread. that's it, that's the whole vibe. π§Tcl_EventDeleteProc *deleteProc(in) β the procedure to invoke for each queued event inTcl_DeleteEvents. one by one, bestie π₯int flags(in) β what types of events to service. these flags are the exact same ones you'd pass toTcl_DoOneEvent. consistency, periodt πint mode(in) β says whether events should be serviced byTcl_ServiceAll. must be one ofTCL_SERVICE_NONEorTCL_SERVICE_ALL. pick one, there's no third option β¨const Tcl_NotifierProcs*(notifierProcPtr) β a structure of function pointers describing notifier procedures that are going to replace the ones installed in the executable. for the deets, see REPLACING THE NOTIFIER below π
π INTRODUCTION π
okay so here's the tea β β the interfaces on this page are how you customize the Tcl event loop. the two most common glow-ups people do are: (1) add new sources of events, and (2) merge Tcl's event loop with some other event loop, like one an application provides when Tcl is embedded inside it. each of those tasks gets its own section below, so keep reading bestie.
all the procedures in this manual entry are literally the building blocks that the Tcl event notifier is constructed out of. the event notifier is the lowest layer in the Tcl event mechanism. and it consists of three things, a little trio, a girl group if you will:
- Event sources β these represent the ways events can be generated. for example, there's a timer event source that implements the
Tcl_CreateTimerHandlerprocedure and theaftercommand, and there's a file event source that implements theTcl_CreateFileHandlerprocedure on Unix systems. an event source has to work with the notifier to detect events at the right times, record them on the event queue, and eventually notify higher-level software that they've occurred. the proceduresTcl_CreateEventSource,Tcl_DeleteEventSource, andTcl_SetMaxBlockTime,Tcl_QueueEvent, andTcl_DeleteEventsare used primarily by event sources. π - The event queue β there is a single queue for each thread containing a Tcl interpreter, and it holds events that have been detected but not yet serviced. event sources place events onto the queue so they can be processed in order at the appropriate times during the event loop. and here's the slay part: the event queue guarantees a fair discipline of event handling, so that no event source can starve the others. mutual respect, we love to see it π«Ά. it also lets events be saved for servicing at a future time.
Tcl_QueueEventis used (primarily by event sources) to add events to the current thread's event queue, andTcl_DeleteEventsis used to remove events from the queue without processing them. ghosting, but make it legal π - The event loop β to detect and process events, the application enters a loop that waits for events to occur, places them on the event queue, and then processes them. most applications do this by calling the procedure
Tcl_DoOneEvent, which is described in its own separate manual entry. go read that one too, bestie β¨
most Tcl applications do not need to worry about any of the internals of the Tcl notifier. however β and this is highkey important β the notifier now has enough flexibility to be retargeted either for a new platform or to use an external event loop (like the Motif event loop, when Tcl is embedded in a Motif application). the procedures Tcl_WaitForEvent and Tcl_SetTimer are normally implemented by Tcl, but they may be replaced with new versions to retarget the notifier (and note: Tcl_InitNotifier, Tcl_AlertNotifier, Tcl_FinalizeNotifier, Tcl_Sleep, Tcl_CreateFileHandler, and Tcl_DeleteFileHandler must also be replaced β see CREATING A NEW NOTIFIER below for details). also, the procedures Tcl_ServiceAll, Tcl_ServiceEvent, Tcl_GetServiceMode, and Tcl_SetServiceMode are provided to help connect Tcl's event loop to an external event loop such as Motif's. teamwork makes the dream work ππ
ngl this is a lot of layers but that's the whole point β the notifier is the bottom of the stack, so if you're messing with it you're playing at the lowest level of the game π
β¨ NOTIFIER BASICS β¨
okay bestie, the easiest way to understand how the notifier works is to consider what happens when Tcl_DoOneEvent is called. Tcl_DoOneEvent is passed a flags argument that indicates what sort of events it is OK to process and also whether or not to block if no events are ready. Then Tcl_DoOneEvent does the following things, in order, no cap:
- Check the event queue to see if it contains any events that can be serviced. If so, service the first possible event, remove it from the queue, and return. It does this by calling
Tcl_ServiceEventand passing in theflagsargument. β¨ - Prepare to block for an event. To do this,
Tcl_DoOneEventinvokes a setup procedure in each event source. The event source will perform event-source specific initialization and possibly callTcl_SetMaxBlockTimeto limit how longTcl_WaitForEventwill block if no new events occur. π - Call
Tcl_WaitForEvent. This procedure is implemented differently on different platforms; it waits for an event to occur, based on the information provided by the event sources. It may cause the application to block iftimePtrspecifies an interval other than0.Tcl_WaitForEventreturns when something has happened, such as a file becoming readable or the interval given bytimePtrexpiring. If there are no events forTcl_WaitForEventto wait for, so that it would block forever, then it returns immediately andTcl_DoOneEventreturns0. π¦ - Call a check procedure in each event source. The check procedure determines whether any events of interest to this source occurred. If so, the events are added to the event queue. π
- Check the event queue to see if it contains any events that can be serviced. If so, service the first possible event, remove it from the queue, and return. π
- See if there are idle callbacks pending. If so, invoke all of them and return. π
- Either return
0to indicate that no events were ready, or go back to step [2] if blocking was requested by the caller. π₯
β¨ CREATING A NEW EVENT SOURCE β¨
okay bestie, so an event source is basically this little trio of procedures that the notifier calls up, plus some extra C procedures that higher-level code calls to set up event-driven callbacks π. The three procedures the notifier itself invokes are the setup and check procedures we already talked about, and one more that gets called when an event gets pulled off the event queue to be serviced. three besties, one job π«Ά
The procedure Tcl_CreateEventSource creates a new event source. Its arguments specify the setup procedure and the check procedure for the event source. SetupProc should match this prototype, no cap:
typedef void Tcl_EventSetupProc(
void *clientData,
int flags);
The clientData argument will be the same as the clientData argument to Tcl_CreateEventSource; it's typically used to point to private information managed by the event source π. The flags argument will be the same as the flags argument passed to Tcl_DoOneEvent, except that it will never be 0 (because Tcl_DoOneEvent replaces 0 with TCL_ALL_EVENTS). Flags tells you what kinds of events should be considered; if the bit corresponding to this event source is not set, the event source should just return immediately and do absolutely nothing, periodt. For example, the file event source checks for the TCL_FILE_EVENTS bit π.
SetupProc's whole job is to make sure the application wakes up when events of the desired type occur. This is typically done in a platform-dependent fashion β like, under Unix an event source might call Tcl_CreateFileHandler; under Windows it might request notification with a Windows event πͺ. For timer-driven event sources such as timer events or any polled event, the event source can call Tcl_SetMaxBlockTime to force the application to wake up after a specified time even if no events have occurred. If no event source calls Tcl_SetMaxBlockTime, then Tcl_WaitForEvent will wait as long as necessary for an event to occur; otherwise, it will only wait as long as the shortest interval passed to Tcl_SetMaxBlockTime by one of the event sources β°. If an event source already knows it has events ready to report, it can request a zero maximum block time. For example, the setup procedure for the X event source looks to see if there are events already queued. If there are, it calls Tcl_SetMaxBlockTime with a 0 block time so that Tcl_WaitForEvent does not block if there is no new data on the X connection. The timePtr argument to Tcl_WaitForEvent points to a structure that describes a time interval in seconds and microseconds:
typedef struct {
long long sec;
long usec;
} Tcl_Time;
The usec field should be less than 1000000 π.
Information provided to Tcl_SetMaxBlockTime is only used for the next call to Tcl_WaitForEvent; it is discarded after Tcl_WaitForEvent returns ποΈ. The next time an event wait is done, each of the event sources' setup procedures will be called again, and they can specify new information for that event wait. iconic behavior honestly π
If the application uses an external event loop rather than Tcl_DoOneEvent, the event sources may need to call Tcl_SetMaxBlockTime at other times. For example, if a new event handler is registered that needs to poll for events, the event source may call Tcl_SetMaxBlockTime to set the block time to zero to force the external event loop to call Tcl. In this case, Tcl_SetMaxBlockTime invokes Tcl_SetTimer with the shortest interval seen since the last call to Tcl_DoOneEvent or Tcl_ServiceAll π.
In addition to the generic procedure Tcl_SetMaxBlockTime, other platform-specific procedures may also be available for setupProc, if there is additional information needed by Tcl_WaitForEvent on that platform. For example, on Unix systems the Tcl_CreateFileHandler interface can be used to wait for file events π§.
π¦ the check procedure π¦
The second procedure provided by each event source is its check procedure, indicated by the checkProc argument to Tcl_CreateEventSource. CheckProc must match the following prototype:
typedef void Tcl_EventCheckProc(
void *clientData,
int flags);
The arguments to this procedure are the same as those for setupProc, slay. CheckProc is invoked by Tcl_DoOneEvent after it has waited for events. Presumably at least one event source is now prepared to queue an event. Tcl_DoOneEvent calls each of the event sources in turn, so they all get a chance to queue any events that are ready π. The check procedure does two things. First, it must see if any events have triggered. Different event sources do this in different ways β everyone's got their own method, iykyk π
.
If an event source's check procedure detects an interesting event, it must add the event to Tcl's event queue. To do this, the event source calls Tcl_QueueEvent. The evPtr argument is a pointer to a dynamically allocated structure containing the event (see below for more info on memory management issues, bestie β it's giving β¨importantβ¨). Each event source can define its own event structure with whatever information is relevant to that event source. However, the first element of the structure must be a structure of type Tcl_Event, and the address of this structure is used when communicating between the event source and the rest of the notifier π¬. A Tcl_Event has this definition:
typedef struct Tcl_Event {
Tcl_EventProc *proc;
struct Tcl_Event *nextPtr;
} Tcl_Event;
The event source must fill in the proc field of the event before calling Tcl_QueueEvent. The nextPtr is used to link together the events in the queue and should not be modified by the event source π
ββοΈ.
An event may be added to the queue at any of three positions, depending on the position argument to Tcl_QueueEvent:
TCL_QUEUE_TAILβ Add the event at the back of the queue, so that all other pending events will be serviced first. This is almost always the right place for new events π.TCL_QUEUE_HEADβ Add the event at the front of the queue, so that it will be serviced before all other queued events π.TCL_QUEUE_MARKβ Add the event at the front of the queue, unless there are other events at the front whose position isTCL_QUEUE_MARK; if so, add the new event just after all otherTCL_QUEUE_MARKevents. This value of position is used to insert an ordered sequence of events at the front of the queue, such as a series of Enter and Leave events synthesized during a grab or ungrab operation in Tk π±οΈ.TCL_QUEUE_ALERT_IF_EMPTYβ When used inTcl_ThreadQueueEvent, arranges for an automatic call ofTcl_ThreadAlertwhen the queue was empty π.
When it is time to handle an event from the queue (steps 1 and 4 above, bestie β keep up π) Tcl_ServiceEvent will invoke the proc specified in the first queued Tcl_Event structure. Proc must match the following prototype:
typedef int Tcl_EventProc(
Tcl_Event *evPtr,
int flags);
The first argument to proc is a pointer to the event, which will be the same as the first argument to the Tcl_QueueEvent call that added the event to the queue. The second argument to proc is the flags argument for the current call to Tcl_ServiceEvent; this is used by the event source to return immediately if its events are not relevant πββοΈ.
It's up to proc to handle the event, typically by invoking one or more Tcl commands or C-level callbacks. Once the event source has finished handling the event, it returns 1 to indicate that the event can be removed from the queue β
. If for some reason the event source decides that the event cannot be handled at this time, it may return 0 to indicate that the event should be deferred for processing later; in this case Tcl_ServiceEvent will go on to the next event in the queue and attempt to service it βοΈ. There are several reasons why an event source might defer an event. One possibility is that events of this type are excluded by the flags argument. For example, the file event source will always return 0 if the TCL_FILE_EVENTS bit is not set in flags. Another example of deferring events happens in Tk if Tk_RestrictEvents has been invoked to defer certain kinds of window events πͺ.
When proc returns 1, Tcl_ServiceEvent will remove the event from the event queue and free its storage. Note that the storage for an event must be allocated by the event source (using Tcl_Alloc) before calling Tcl_QueueEvent, but it will be freed by Tcl_ServiceEvent, not by the event source. so likeβ¦ you allocate it, someone else frees it. the duality bestie π
Calling Tcl_QueueEvent adds an event to the current thread's queue. To add an event to another thread's queue, use Tcl_ThreadQueueEvent. Tcl_ThreadQueueEvent accepts as an argument a Tcl_ThreadId argument, which uniquely identifies a thread in a Tcl application π§΅. To obtain the Tcl_ThreadId for the current thread, use the Tcl_GetCurrentThread procedure. (A thread would then need to pass this identifier to other threads for those threads to be able to add events to its queue β sharing is caring β¨.) After adding an event to another thread's queue, you then typically need to call Tcl_ThreadAlert to "wake up" that thread's notifier to alert it to the new event βοΈ.
Tcl_DeleteEvents can be used to explicitly remove one or more events from the event queue ποΈ. Tcl_DeleteEvents calls proc for each event in the queue, deleting those for which the procedure returns 1. Events for which the procedure returns 0 are left in the queue. Proc should match the following prototype:
typedef int Tcl_EventDeleteProc(
Tcl_Event *evPtr,
void *clientData);
The clientData argument will be the same as the clientData argument to Tcl_DeleteEvents; it's typically used to point to private information managed by the event source π. The evPtr will point to the next event in the queue π.
Tcl_DeleteEventSource deletes an event source π. The setupProc, checkProc, and clientData arguments must exactly match those provided to the Tcl_CreateEventSource for the event source to be deleted β no vibes-based matching, bestie, exact or nothing β. If no such source exists, Tcl_DeleteEventSource has no effect at all. it's giving shrug π€·ββοΈ
π¦ CREATING A NEW NOTIFIER π¦
okay bestie, so the notifier is basically the whole ensemble cast π
β it's all the procedures described in this manual entry, PLUS Tcl_DoOneEvent and Tcl_Sleep (those two are available on all platforms), PLUS Tcl_CreateFileHandler and Tcl_DeleteFileHandler, which are Unix-specific. Most of these procedures are generic, meaning they're literally the same for all notifiers. That said, none of the procedures are notifier-dependent: Tcl_InitNotifier, Tcl_AlertNotifier, Tcl_FinalizeNotifier, Tcl_SetTimer, Tcl_Sleep, Tcl_WaitForEvent, Tcl_CreateFileHandler, Tcl_DeleteFileHandler and Tcl_ServiceModeHook.
So if you wanna support a new platform, or you wanna integrate Tcl with an application-specific event loop, you gotta write new versions of these procedures. no cap π«Ά
Tcl_InitNotifier initializes the notifier state and returns a handle to the notifier state. Tcl calls this procedure when it's initializing a Tcl interpreter. Similarly, Tcl_FinalizeNotifier shuts down the notifier, and it gets called by Tcl_Finalize when shutting down a Tcl interpreter.
Tcl_WaitForEvent is the lowest-level procedure in the notifier β it's the one responsible for waiting for an "interesting" event to occur, or for a given time to elapse. Before Tcl_WaitForEvent is invoked, each of the event sources' setup procedure will have been invoked. The timePtr argument to Tcl_WaitForEvent gives the maximum time to block for an event, based on calls to Tcl_SetMaxBlockTime made by setup procedures and on other information (such as the TCL_DONT_WAIT bit in flags).
Ideally, Tcl_WaitForEvent should only wait for an event to occur; it should not actually process the event in any way. Later on, the event sources will process the raw events and create Tcl_Events on the event queue in their checkProc procedures. However, on some platforms (such as Windows) this is not possible; events may be processed in Tcl_WaitForEvent, including queuing Tcl_Events and more (for example, callbacks for native widgets may be invoked). π
The return value from Tcl_WaitForEvent must be either 0, 1, or -1. Here's the vibe check on each:
- On platforms such as Windows where events get processed in
Tcl_WaitForEvent, a return value of1means that there may be more events still pending that have not been processed. This is a sign to the caller that it must callTcl_WaitForEventagain if it wants all pending events to be processed. - A
0return value means that callingTcl_WaitForEventagain will not have any effect: either this is a platform whereTcl_WaitForEventonly waits without doing any event processing, orTcl_WaitForEventknows for sure that there are no additional events to process (e.g. it returned because the time elapsed). - Finally, a return value of
-1means that the event loop is no longer operational and the application should probably unwind and terminate. π Under Windows this happens when aWM_QUITmessage is received; under Unix it happens whenTcl_WaitForEventwould have waited forever because there were no active event sources and the timeout was infinite.
Tcl_AlertNotifier is what lets any thread "wake up" the notifier and alert it to new events on its queue. Tcl_AlertNotifier requires as an argument the notifier handle returned by Tcl_InitNotifier. β¨
If the notifier is gonna be used with an external event loop, then it must also support the Tcl_SetTimer interface. Tcl_SetTimer is invoked by Tcl_SetMaxBlockTime whenever the maximum blocking time has been reduced. Tcl_SetTimer should arrange for the external event loop to invoke Tcl_ServiceAll after the specified interval even if no events have occurred. This interface is needed because Tcl_WaitForEvent is not invoked when there is an external event loop. If the notifier will only be used from Tcl_DoOneEvent, then Tcl_SetTimer need not do anything. easy π
Tcl_ServiceModeHook is called by the platform-independent portion of the notifier when client code makes a call to Tcl_SetServiceMode. This hook exists to support operating systems that require special event handling when the application is in a modal loop (the Windows notifier, for instance, uses this hook to create a communication window). π
On Unix systems, the file event source also needs support from the notifier. That file event source consists of the Tcl_CreateFileHandler and Tcl_DeleteFileHandler procedures, which are described in the Tcl_CreateFileHandler manual page.
The Tcl_Sleep and Tcl_DoOneEvent interfaces are described in their respective manual pages.
And the easiest way to create a new notifier is to go look at the code for an existing notifier, such as the files unix/tclUnixNotfy.c or win/tclWinNotify.c in the Tcl source distribution. go read the source bestie, it ate π
π₯ REPLACING THE NOTIFIER π₯
A notifier that has been written according to the conventions above can also be installed in a running process in place of the standard notifier. Why tho? Because this mechanism is used so that a single executable can be used (with the standard notifier) as a stand-alone program AND reused (with a replacement notifier in a loadable extension) as an extension to another program β like, say, a Web browser plugin. iconic tbh β¨
To do this, the extension makes a call to Tcl_SetNotifier passing a pointer to a Tcl_NotifierProcs data structure. The structure has the following layout:
typedef struct {
Tcl_SetTimerProc *setTimerProc;
Tcl_WaitForEventProc *waitForEventProc;
Tcl_CreateFileHandlerProc *createFileHandlerProc;
Tcl_DeleteFileHandlerProc *deleteFileHandlerProc;
Tcl_InitNotifierProc *initNotifierProc;
Tcl_FinalizeNotifierProc *finalizeNotifierProc;
Tcl_AlertNotifierProc *alertNotifierProc;
Tcl_ServiceModeHookProc *serviceModeHookProc;
} Tcl_NotifierProcs;
Following the call to Tcl_SetNotifier, the pointers given in the Tcl_NotifierProcs structure replace whatever notifier had been installed in the process.
π¨ It is extraordinarily unwise to replace a running notifier. Normally,Tcl_SetNotifiershould be called at process initialization time before the first call toTcl_InitNotifier. Do not do the chaotic thing, bestie. π
π EXTERNAL EVENT LOOPS π
The notifier interfaces are designed so that Tcl can be embedded into applications that have their own private event loops. In this case, the application does not call Tcl_DoOneEvent except in the case of recursive event loops such as calls to the Tcl commands update or vwait. Most of the time is spent in the external event loop of the application. In this case the notifier must arrange for the external event loop to call back into Tcl when something happens on the various Tcl event sources. These callbacks should arrange for appropriate Tcl events to be placed on the Tcl event queue.
Because the external event loop is not calling Tcl_DoOneEvent on a regular basis, it is up to the notifier to arrange for Tcl_ServiceEvent to be called whenever events are pending on the Tcl event queue. The easiest way to do this is to invoke Tcl_ServiceAll at the end of each callback from the external event loop. This will ensure that all of the event sources are polled, any queued events are serviced, and any pending idle handlers are processed before returning control to the application. In addition, event sources that need to poll for events can call Tcl_SetMaxBlockTime to force the external event loop to call Tcl even if no events are available on the system event queue. π
As a side effect of processing events detected in the main external event loop, Tcl may invoke Tcl_DoOneEvent to start a recursive event loop in commands like vwait. Tcl_DoOneEvent will invoke the external event loop, which will result in callbacks as described in the preceding paragraph, which will result in calls to Tcl_ServiceAll. However, in these cases it is undesirable to service events in Tcl_ServiceAll. Servicing events there is unnecessary because control will immediately return to the external event loop and hence to Tcl_DoOneEvent, which can service the events itself. Furthermore, Tcl_DoOneEvent is supposed to service only a single event, whereas Tcl_ServiceAll normally services all pending events. To handle this situation, Tcl_DoOneEvent sets a flag for Tcl_ServiceAll that causes it to return without servicing any events. This flag is called the service mode; Tcl_DoOneEvent restores it to its previous value before it returns.
In some cases, however, it may be necessary for Tcl_ServiceAll to service events even when it has been invoked from Tcl_DoOneEvent. This happens when there is yet another recursive event loop invoked via an event handler called by Tcl_DoOneEvent (such as one that is part of a native widget). In this case, Tcl_DoOneEvent may not have a chance to service events so Tcl_ServiceAll must service them all. Any recursive event loop that calls an external event loop rather than Tcl_DoOneEvent must reset the service mode so that all events get processed in Tcl_ServiceAll. This is done by invoking the Tcl_SetServiceMode procedure.
- If
Tcl_SetServiceModeis passedTCL_SERVICE_NONE, then calls toTcl_ServiceAllwill return immediately without processing any events. - If
Tcl_SetServiceModeis passedTCL_SERVICE_ALL, then calls toTcl_ServiceAllwill behave normally.
Tcl_SetServiceMode returns the previous value of the service mode, which should be restored when the recursive loop exits. Tcl_GetServiceMode returns the current value of the service mode. π«Ά
β¨ SEE ALSO β¨
π KEYWORDS π
event, notifier, event queue, event sources, file events, timer, idle, service mode, threads
and that's a wrap on the whole Notifier(3) saga, bestie π this page is from Tcl version 8.1 and it's dated way back in the day β the version string says 8.1 and the footer stamps it as Notifier(3). go forth and write a notifier, you absolute icon π π
π¦ 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) 1998-1999 Scriptics Corporation
- Copyright (c) 1995-1997 Sun Microsystems, Inc
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms