1Notifier(3) Tcl Library Procedures Notifier(3)
2
3
4
5______________________________________________________________________________
6
8 Tcl_CreateEventSource, Tcl_DeleteEventSource, Tcl_SetMaxBlockTime,
9 Tcl_QueueEvent, Tcl_ThreadQueueEvent, Tcl_ThreadAlert, Tcl_GetCurrent‐
10 Thread, Tcl_DeleteEvents, Tcl_InitNotifier, Tcl_FinalizeNotifier,
11 Tcl_WaitForEvent, Tcl_AlertNotifier, Tcl_SetTimer, Tcl_ServiceAll,
12 Tcl_ServiceEvent, Tcl_GetServiceMode, Tcl_SetServiceMode - the event
13 queue and notifier interfaces
14
16 #include <tcl.h>
17
18 void
19 Tcl_CreateEventSource(setupProc, checkProc, clientData)
20
21 void
22 Tcl_DeleteEventSource(setupProc, checkProc, clientData)
23
24 void
25 Tcl_SetMaxBlockTime(timePtr)
26
27 void
28 Tcl_QueueEvent(evPtr, position)
29
30 void │
31 Tcl_ThreadQueueEvent(threadId, evPtr, position) │
32
33 void │
34 Tcl_ThreadAlert(threadId) │
35
36 Tcl_ThreadId │
37 Tcl_GetCurrentThread() │
38
39 void │
40 Tcl_DeleteEvents(deleteProc, clientData) │
41
42 ClientData │
43 Tcl_InitNotifier() │
44
45 void │
46 Tcl_FinalizeNotifier(clientData) │
47
48 int │
49 Tcl_WaitForEvent(timePtr) │
50
51 void │
52 Tcl_AlertNotifier(clientData) │
53
54 void │
55 Tcl_SetTimer(timePtr) │
56
57 int │
58 Tcl_ServiceAll() │
59
60 int │
61 Tcl_ServiceEvent(flags) │
62
63 int │
64 Tcl_GetServiceMode() │
65
66 int │
67 Tcl_SetServiceMode(mode) │
68
69
71 Tcl_EventSetupProc *setupProc (in) Procedure to invoke to
72 prepare for event wait
73 in Tcl_DoOneEvent.
74
75 Tcl_EventCheckProc *checkProc (in) Procedure for
76 Tcl_DoOneEvent to invoke
77 after waiting for
78 events. Checks to see
79 if any events have
80 occurred and, if so,
81 queues them.
82
83 ClientData clientData (in) Arbitrary one-word value
84 to pass to setupProc,
85 checkProc, or
86 deleteProc.
87
88 Tcl_Time *timePtr (in) Indicates the maximum
89 amount of time to wait
90 for an event. This is
91 specified as an interval
92 (how long to wait), not
93 an absolute time (when
94 to wakeup). If the
95 pointer passed to
96 Tcl_WaitForEvent is
97 NULL, it means there is
98 no maximum wait time:
99 wait forever if neces‐
100 sary.
101
102 Tcl_Event *evPtr (in) An event to add to the
103 event queue. The stor‐
104 age for the event must
105 have been allocated by
106 the caller using
107 Tcl_Alloc or ckalloc.
108
109 Tcl_QueuePosition position (in) Where to add the new
110 event in the queue:
111 TCL_QUEUE_TAIL,
112 TCL_QUEUE_HEAD, or
113 TCL_QUEUE_MARK.
114
115 Tcl_ThreadId threadId (in) A unique identifier for
116 a thread.
117
118 Tcl_EventDeleteProc *deleteProc (in) Procedure to invoke for
119 each queued event in
120 Tcl_DeleteEvents.
121
122 int flags (in) What types of events to
123 service. These flags
124 are the same as those
125 passed to
126 Tcl_DoOneEvent. │
127
128 int mode (in) │
129 Indicates whether events │
130 should be serviced by │
131 Tcl_ServiceAll. Must be │
132 one of TCL_SERVICE_NONE │
133 or TCL_SERVICE_ALL.
134_________________________________________________________________
135
136
138 The interfaces described here are used to customize the Tcl event loop.
139 The two most common customizations are to add new sources of events and
140 to merge Tcl's event loop with some other event loop, such as one pro‐
141 vided by an application in which Tcl is embedded. Each of these tasks
142 is described in a separate section below.
143
144 The procedures in this manual entry are the building blocks out of
145 which the Tcl event notifier is constructed. The event notifier is the
146 lowest layer in the Tcl event mechanism. It consists of three things:
147
148 [1] Event sources: these represent the ways in which events can be
149 generated. For example, there is a timer event source that
150 implements the Tcl_CreateTimerHandler procedure and the after
151 command, and there is a file event source that implements the
152 Tcl_CreateFileHandler procedure on Unix systems. An event
153 source must work with the notifier to detect events at the right
154 times, record them on the event queue, and eventually notify
155 higher-level software that they have occurred. The procedures
156 Tcl_CreateEventSource, Tcl_DeleteEventSource, and Tcl_Set‐
157 MaxBlockTime, Tcl_QueueEvent, and Tcl_DeleteEvents are used pri‐
158 marily by event sources.
159
160 [2] The event queue: for non-threaded applications, there is a sin‐
161 gle queue for the whole application, containing events that have
162 been detected but not yet serviced. Event sources place events
163 onto the queue so that they may be processed in order at appro‐
164 priate times during the event loop. The event queue guarantees a
165 fair discipline of event handling, so that no event source can
166 starve the others. It also allows events to be saved for ser‐
167 vicing at a future time. Threaded applications work in a simi‐ │
168 lar manner, except that there is a separate event queue for each │
169 thread containing a Tcl interpreter. Tcl_QueueEvent is used │
170 (primarily by event sources) to add events to the event queue │
171 and Tcl_DeleteEvents is used to remove events from the queue │
172 without processing them. In a threaded application, │
173 Tcl_QueueEvent adds an event to the current thread's queue, and │
174 Tcl_ThreadQueueEvent adds an event to a queue in a specific │
175 thread. │
176
177 [3] │
178 The event loop: in order to detect and process events, the │
179 application enters a loop that waits for events to occur, places │
180 them on the event queue, and then processes them. Most applica‐ │
181 tions will do this by calling the procedure Tcl_DoOneEvent, │
182 which is described in a separate manual entry. │
183
184 Most Tcl applications need not worry about any of the internals of the │
185 Tcl notifier. However, the notifier now has enough flexibility to be │
186 retargeted either for a new platform or to use an external event loop │
187 (such as the Motif event loop, when Tcl is embedded in a Motif applica‐ │
188 tion). The procedures Tcl_WaitForEvent and Tcl_SetTimer are normally │
189 implemented by Tcl, but may be replaced with new versions to retarget │
190 the notifier (the Tcl_InitNotifier, Tcl_AlertNotifier, Tcl_FinalizeNo‐ │
191 tifier, Tcl_Sleep, Tcl_CreateFileHandler, and Tcl_DeleteFileHandler │
192 must also be replaced; see CREATING A NEW NOTIFIER below for details). │
193 The procedures Tcl_ServiceAll, Tcl_ServiceEvent, Tcl_GetServiceMode, │
194 and Tcl_SetServiceMode are provided to help connect Tcl's event loop to │
195 an external event loop such as Motif's. │
196
198 The easiest way to understand how the notifier works is to consider
199 what happens when Tcl_DoOneEvent is called. Tcl_DoOneEvent is passed a
200 flags argument that indicates what sort of events it is OK to process
201 and also whether or not to block if no events are ready.
202 Tcl_DoOneEvent does the following things:
203
204 [1] Check the event queue to see if it contains any events that can
205 be serviced. If so, service the first possible event, remove it │
206 from the queue, and return. It does this by calling Tcl_Ser‐ │
207 viceEvent and passing in the flags argument.
208
209 [2] Prepare to block for an event. To do this, Tcl_DoOneEvent
210 invokes a setup procedure in each event source. The event
211 source will perform event-source specific initialization and │
212 possibly call Tcl_SetMaxBlockTime to limit how long Tcl_Wait‐
213 ForEvent will block if no new events occur.
214
215 [3] Call Tcl_WaitForEvent. This procedure is implemented differ‐
216 ently on different platforms; it waits for an event to occur,
217 based on the information provided by the event sources. It may
218 cause the application to block if timePtr specifies an interval
219 other than 0. Tcl_WaitForEvent returns when something has hap‐
220 pened, such as a file becoming readable or the interval given by
221 timePtr expiring. If there are no events for Tcl_WaitForEvent
222 to wait for, so that it would block forever, then it returns
223 immediately and Tcl_DoOneEvent returns 0.
224
225 [4] Call a check procedure in each event source. The check proce‐
226 dure determines whether any events of interest to this source
227 occurred. If so, the events are added to the event queue.
228
229 [5] Check the event queue to see if it contains any events that can
230 be serviced. If so, service the first possible event, remove it
231 from the queue, and return.
232
233 [6] See if there are idle callbacks pending. If so, invoke all of
234 them and return.
235
236 [7] Either return 0 to indicate that no events were ready, or go
237 back to step [2] if blocking was requested by the caller.
238
239
241 An event source consists of three procedures invoked by the notifier,
242 plus additional C procedures that are invoked by higher-level code to
243 arrange for event-driven callbacks. The three procedures called by the
244 notifier consist of the setup and check procedures described above,
245 plus an additional procedure that is invoked when an event is removed
246 from the event queue for servicing.
247
248 The procedure Tcl_CreateEventSource creates a new event source. Its
249 arguments specify the setup procedure and check procedure for the event
250 source. SetupProc should match the following prototype:
251 typedef void Tcl_EventSetupProc(
252 ClientData clientData,
253 int flags);
254 The clientData argument will be the same as the clientData argument to
255 Tcl_CreateEventSource; it is typically used to point to private infor‐
256 mation managed by the event source. The flags argument will be the
257 same as the flags argument passed to Tcl_DoOneEvent except that it will
258 never be 0 (Tcl_DoOneEvent replaces 0 with TCL_ALL_EVENTS). Flags
259 indicates what kinds of events should be considered; if the bit corre‐
260 sponding to this event source isn't set, the event source should return
261 immediately without doing anything. For example, the file event source
262 checks for the TCL_FILE_EVENTS bit.
263
264 SetupProc's job is to make sure that the application wakes up when
265 events of the desired type occur. This is typically done in a plat‐
266 form-dependent fashion. For example, under Unix an event source might
267 call Tcl_CreateFileHandler; under Windows it might request notification
268 with a Windows event. For timer-driven event sources such as timer
269 events or any polled event, the event source can call Tcl_SetMaxBlock‐
270 Time to force the application to wake up after a specified time even if
271 no events have occurred. If no event source calls Tcl_SetMaxBlockTime │
272 then Tcl_WaitForEvent will wait as long as necessary for an event to │
273 occur; otherwise, it will only wait as long as the shortest interval │
274 passed to Tcl_SetMaxBlockTime by one of the event sources. If an event │
275 source knows that it already has events ready to report, it can request │
276 a zero maximum block time. For example, the setup procedure for the X │
277 event source looks to see if there are events already queued. If there │
278 are, it calls Tcl_SetMaxBlockTime with a 0 block time so that Tcl_Wait‐ │
279 ForEvent does not block if there is no new data on the X connection.
280 The timePtr argument to Tcl_WaitForEvent points to a structure that
281 describes a time interval in seconds and microseconds:
282 typedef struct Tcl_Time {
283 long sec;
284 long usec;
285 } Tcl_Time;
286 The usec field should be less than 1000000.
287
288 Information provided to Tcl_SetMaxBlockTime is only used for the next │
289 call to Tcl_WaitForEvent; it is discarded after Tcl_WaitForEvent │
290 returns. The next time an event wait is done each of the event
291 sources' setup procedures will be called again, and they can specify
292 new information for that event wait.
293
294 If the application uses an external event loop rather than │
295 Tcl_DoOneEvent, the event sources may need to call Tcl_SetMaxBlockTime │
296 at other times. For example, if a new event handler is registered that │
297 needs to poll for events, the event source may call Tcl_SetMaxBlockTime │
298 to set the block time to zero to force the external event loop to call │
299 Tcl. In this case, Tcl_SetMaxBlockTime invokes Tcl_SetTimer with the │
300 shortest interval seen since the last call to Tcl_DoOneEvent or │
301 Tcl_ServiceAll. │
302
303 In addition to the generic procedure Tcl_SetMaxBlockTime, other plat‐ │
304 form-specific procedures may also be available for setupProc, if there │
305 is additional information needed by Tcl_WaitForEvent on that platform. │
306 For example, on Unix systems the Tcl_CreateFileHandler interface can be │
307 used to wait for file events.
308
309 The second procedure provided by each event source is its check proce‐
310 dure, indicated by the checkProc argument to Tcl_CreateEventSource.
311 CheckProc must match the following prototype:
312 typedef void Tcl_EventCheckProc(
313 ClientData clientData,
314 int flags);
315 The arguments to this procedure are the same as those for setupProc.
316 CheckProc is invoked by Tcl_DoOneEvent after it has waited for events.
317 Presumably at least one event source is now prepared to queue an event.
318 Tcl_DoOneEvent calls each of the event sources in turn, so they all
319 have a chance to queue any events that are ready. The check procedure
320 does two things. First, it must see if any events have triggered.
321 Different event sources do this in different ways.
322
323 If an event source's check procedure detects an interesting event, it
324 must add the event to Tcl's event queue. To do this, the event source
325 calls Tcl_QueueEvent. The evPtr argument is a pointer to a dynamically
326 allocated structure containing the event (see below for more informa‐
327 tion on memory management issues). Each event source can define its
328 own event structure with whatever information is relevant to that event
329 source. However, the first element of the structure must be a struc‐
330 ture of type Tcl_Event, and the address of this structure is used when
331 communicating between the event source and the rest of the notifier. A
332 Tcl_Event has the following definition:
333 typedef struct {
334 Tcl_EventProc *proc;
335 struct Tcl_Event *nextPtr;
336 } Tcl_Event;
337 The event source must fill in the proc field of the event before call‐
338 ing Tcl_QueueEvent. The nextPtr is used to link together the events in
339 the queue and should not be modified by the event source.
340
341 An event may be added to the queue at any of three positions, depending
342 on the position argument to Tcl_QueueEvent:
343
344 TCL_QUEUE_TAIL Add the event at the back of the queue, so that
345 all other pending events will be serviced
346 first. This is almost always the right place
347 for new events.
348
349 TCL_QUEUE_HEAD Add the event at the front of the queue, so
350 that it will be serviced before all other
351 queued events.
352
353 TCL_QUEUE_MARK Add the event at the front of the queue, unless
354 there are other events at the front whose posi‐
355 tion is TCL_QUEUE_MARK; if so, add the new
356 event just after all other TCL_QUEUE_MARK
357 events. This value of position is used to
358 insert an ordered sequence of events at the
359 front of the queue, such as a series of Enter
360 and Leave events synthesized during a grab or
361 ungrab operation in Tk.
362
363 When it is time to handle an event from the queue (steps 1 and 4 above) │
364 Tcl_ServiceEvent will invoke the proc specified in the first queued
365 Tcl_Event structure. Proc must match the following prototype:
366 typedef int Tcl_EventProc(
367 Tcl_Event *evPtr,
368 int flags);
369 The first argument to proc is a pointer to the event, which will be the
370 same as the first argument to the Tcl_QueueEvent call that added the
371 event to the queue. The second argument to proc is the flags argument
372 for the current call to Tcl_ServiceEvent; this is used by the event │
373 source to return immediately if its events are not relevant.
374
375 It is up to proc to handle the event, typically by invoking one or more
376 Tcl commands or C-level callbacks. Once the event source has finished
377 handling the event it returns 1 to indicate that the event can be
378 removed from the queue. If for some reason the event source decides
379 that the event cannot be handled at this time, it may return 0 to indi‐
380 cate that the event should be deferred for processing later; in this │
381 case Tcl_ServiceEvent will go on to the next event in the queue and
382 attempt to service it. There are several reasons why an event source
383 might defer an event. One possibility is that events of this type are
384 excluded by the flags argument. For example, the file event source
385 will always return 0 if the TCL_FILE_EVENTS bit isn't set in flags.
386 Another example of deferring events happens in Tk if Tk_RestrictEvents
387 has been invoked to defer certain kinds of window events.
388
389 When proc returns 1, Tcl_ServiceEvent will remove the event from the │
390 event queue and free its storage. Note that the storage for an event │
391 must be allocated by the event source (using Tcl_Alloc or the Tcl macro │
392 ckalloc) before calling Tcl_QueueEvent, but it will be freed by │
393 Tcl_ServiceEvent, not by the event source. │
394
395 Threaded applications work in a similar manner, except that there is a │
396 separate event queue for each thread containing a Tcl interpreter. │
397 Calling Tcl_QueueEvent in a multithreaded application adds an event to │
398 the current thread's queue. To add an event to another thread's queue, │
399 use Tcl_ThreadQueueEvent. Tcl_ThreadQueueEvent accepts as an argument │
400 a Tcl_ThreadId argument, which uniquely identifies a thread in a Tcl │
401 application. To obtain the Tcl_ThreadID for the current thread, use │
402 the Tcl_GetCurrentThread procedure. (A thread would then need to pass │
403 this identifier to other threads for those threads to be able to add │
404 events to its queue.) After adding an event to another thread's queue, │
405 you then typically need to call Tcl_ThreadAlert to "wake up" that │
406 thread's notifier to alert it to the new event. │
407
408 Tcl_DeleteEvents can be used to explicitly remove one or more events │
409 from the event queue. Tcl_DeleteEvents calls proc for each event in │
410 the queue, deleting those for with the procedure returns 1. Events for │
411 which the procedure returns 0 are left in the queue. Proc should match │
412 the following prototype: │
413 typedef int Tcl_EventDeleteProc( │
414 Tcl_Event *evPtr, │
415 ClientData clientData); │
416 The clientData argument will be the same as the clientData argument to │
417 Tcl_DeleteEvents; it is typically used to point to private information │
418 managed by the event source. The evPtr will point to the next event in │
419 the queue. │
420
421 Tcl_DeleteEventSource deletes an event source. The setupProc, check‐ │
422 Proc, and clientData arguments must exactly match those provided to the │
423 Tcl_CreateEventSource for the event source to be deleted. If no such │
424 source exists, Tcl_DeleteEventSource has no effect.
425
426
428 The notifier consists of all the procedures described in this manual
429 entry, plus Tcl_DoOneEvent and Tcl_Sleep, which are available on all │
430 platforms, and Tcl_CreateFileHandler and Tcl_DeleteFileHandler, which │
431 are Unix-specific. Most of these procedures are generic, in that they │
432 are the same for all notifiers. However, eight of the procedures are │
433 notifier-dependent: Tcl_InitNotifier, Tcl_AlertNotifier, Tcl_Final‐ │
434 izeNotifier, Tcl_SetTimer, Tcl_Sleep, Tcl_WaitForEvent, Tcl_CreateFile‐ │
435 Handler and Tcl_DeleteFileHandler. To support a new platform or to │
436 integrate Tcl with an application-specific event loop, you must write │
437 new versions of these procedures. │
438
439 Tcl_InitNotifier initializes the notifier state and returns a handle to │
440 the notifier state. Tcl calls this procedure when initializing a Tcl │
441 interpreter. Similarly, Tcl_FinalizeNotifier shuts down the notifier, │
442 and is called by Tcl_Finalize when shutting down a Tcl interpreter. │
443
444 Tcl_WaitForEvent is the lowest-level procedure in the notifier; it is │
445 responsible for waiting for an ``interesting'' event to occur or for a │
446 given time to elapse. Before Tcl_WaitForEvent is invoked, each of the │
447 event sources' setup procedure will have been invoked. The timePtr │
448 argument to Tcl_WaitForEvent gives the maximum time to block for an │
449 event, based on calls to Tcl_SetMaxBlockTime made by setup procedures │
450 and on other information (such as the TCL_DONT_WAIT bit in flags). │
451
452 Ideally, Tcl_WaitForEvent should only wait for an event to occur; it │
453 should not actually process the event in any way. Later on, the event │
454 sources will process the raw events and create Tcl_Events on the event │
455 queue in their checkProc procedures. However, on some platforms (such │
456 as Windows) this isn't possible; events may be processed in Tcl_Wait‐ │
457 ForEvent, including queuing Tcl_Events and more (for example, callbacks │
458 for native widgets may be invoked). The return value from Tcl_Wait‐ │
459 ForEvent must be either 0, 1, or -1. On platforms such as Windows │
460 where events get processed in Tcl_WaitForEvent, a return value of 1 │
461 means that there may be more events still pending that haven't been │
462 processed. This is a sign to the caller that it must call Tcl_Wait‐ │
463 ForEvent again if it wants all pending events to be processed. A 0 │
464 return value means that calling Tcl_WaitForEvent again will not have │
465 any effect: either this is a platform where Tcl_WaitForEvent only waits │
466 without doing any event processing, or Tcl_WaitForEvent knows for sure │
467 that there are no additional events to process (e.g. it returned │
468 because the time elapsed). Finally, a return value of -1 means that │
469 the event loop is no longer operational and the application should │
470 probably unwind and terminate. Under Windows this happens when a │
471 WM_QUIT message is received; under Unix it happens when Tcl_Wait‐ │
472 ForEvent would have waited forever because there were no active event │
473 sources and the timeout was infinite. │
474
475 Tcl_AlertNotifier is used in multithreaded applications to allow any │
476 thread to "wake up" the notifier to alert it to new events on its │
477 queue. Tcl_AlertNotifier requires as an argument the notifier handle │
478 returned by Tcl_InitNotifier. │
479
480 If the notifier will be used with an external event loop, then it must │
481 also support the Tcl_SetTimer interface. Tcl_SetTimer is invoked by │
482 Tcl_SetMaxBlockTime whenever the maximum blocking time has been │
483 reduced. Tcl_SetTimer should arrange for the external event loop to │
484 invoke Tcl_ServiceAll after the specified interval even if no events │
485 have occurred. This interface is needed because Tcl_WaitForEvent isn't │
486 invoked when there is an external event loop. If the notifier will │
487 only be used from Tcl_DoOneEvent, then Tcl_SetTimer need not do any‐ │
488 thing. │
489
490 On Unix systems, the file event source also needs support from the │
491 notifier. The file event source consists of the Tcl_CreateFileHandler │
492 and Tcl_DeleteFileHandler procedures, which are described in the │
493 Tcl_CreateFileHandler manual page. │
494
495 The Tcl_Sleep and Tcl_DoOneEvent interfaces are described in their │
496 respective manual pages. │
497
498 The easiest way to create a new notifier is to look at the code for an │
499 existing notifier, such as the files unix/tclUnixNotfy.c or win/tclWin‐ │
500 Notify.c in the Tcl source distribution. │
501
502
504 The notifier interfaces are designed so that Tcl can be embedded into │
505 applications that have their own private event loops. In this case, │
506 the application does not call Tcl_DoOneEvent except in the case of │
507 recursive event loops such as calls to the Tcl commands update or │
508 vwait. Most of the time is spent in the external event loop of the │
509 application. In this case the notifier must arrange for the external │
510 event loop to call back into Tcl when something happens on the various │
511 Tcl event sources. These callbacks should arrange for appropriate Tcl │
512 events to be placed on the Tcl event queue. │
513
514 Because the external event loop is not calling Tcl_DoOneEvent on a reg‐ │
515 ular basis, it is up to the notifier to arrange for Tcl_ServiceEvent to │
516 be called whenever events are pending on the Tcl event queue. The eas‐ │
517 iest way to do this is to invoke Tcl_ServiceAll at the end of each │
518 callback from the external event loop. This will ensure that all of │
519 the event sources are polled, any queued events are serviced, and any │
520 pending idle handlers are processed before returning control to the │
521 application. In addition, event sources that need to poll for events │
522 can call Tcl_SetMaxBlockTime to force the external event loop to call │
523 Tcl even if no events are available on the system event queue. │
524
525 As a side effect of processing events detected in the main external │
526 event loop, Tcl may invoke Tcl_DoOneEvent to start a recursive event │
527 loop in commands like vwait. Tcl_DoOneEvent will invoke the external │
528 event loop, which will result in callbacks as described in the preced‐ │
529 ing paragraph, which will result in calls to Tcl_ServiceAll. However, │
530 in these cases it is undesirable to service events in Tcl_ServiceAll. │
531 Servicing events there is unnecessary because control will immediately │
532 return to the external event loop and hence to Tcl_DoOneEvent, which │
533 can service the events itself. Furthermore, Tcl_DoOneEvent is supposed │
534 to service only a single event, whereas Tcl_ServiceAll normally ser‐ │
535 vices all pending events. To handle this situation, Tcl_DoOneEvent │
536 sets a flag for Tcl_ServiceAll that causes it to return without servic‐ │
537 ing any events. This flag is called the service mode; Tcl_DoOneEvent │
538 restores it to its previous value before it returns. │
539
540 In some cases, however, it may be necessary for Tcl_ServiceAll to ser‐ │
541 vice events even when it has been invoked from Tcl_DoOneEvent. This │
542 happens when there is yet another recursive event loop invoked via an │
543 event handler called by Tcl_DoOneEvent (such as one that is part of a │
544 native widget). In this case, Tcl_DoOneEvent may not have a chance to │
545 service events so Tcl_ServiceAll must service them all. Any recursive │
546 event loop that calls an external event loop rather than Tcl_DoOneEvent │
547 must reset the service mode so that all events get processed in │
548 Tcl_ServiceAll. This is done by invoking the Tcl_SetServiceMode proce‐ │
549 dure. If Tcl_SetServiceMode is passed TCL_SERVICE_NONE, then calls to │
550 Tcl_ServiceAll will return immediately without processing any events. │
551 If Tcl_SetServiceMode is passed TCL_SERVICE_ALL, then calls to Tcl_Ser‐ │
552 viceAll will behave normally. Tcl_SetServiceMode returns the previous │
553 value of the service mode, which should be restored when the recursive │
554 loop exits. Tcl_GetServiceMode returns the current value of the ser‐ │
555 vice mode.
556
558 Tcl_CreateFileHandler, Tcl_DeleteFileHandler, Tcl_Sleep,
559 Tcl_DoOneEvent, Thread(3)
560
562 event, notifier, event queue, event sources, file events, timer, idle,
563 service mode, threads
564
565
566
567Tcl 8.1 Notifier(3)