1Notifier(3)                 Tcl Library Procedures                 Notifier(3)
2
3
4
5______________________________________________________________________________
6

NAME

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

SYNOPSIS

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

ARGUMENTS

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

INTRODUCTION

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

NOTIFIER BASICS

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

CREATING A NEW EVENT SOURCE

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

CREATING A NEW NOTIFIER

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

REPLACING THE NOTIFIER

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

EXTERNAL EVENT LOOPS

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

SEE ALSO

625       Tcl_CreateFileHandler(3),    Tcl_DeleteFileHandler(3),    Tcl_Sleep(3),
626       Tcl_DoOneEvent(3), Thread(3)
627

KEYWORDS

629       event,  notifier, event queue, event sources, file events, timer, idle,
630       service mode, threads
631
632
633
634Tcl                                   8.1                          Notifier(3)
Impressum