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