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