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  - the event
13       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       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

INTRODUCTION

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

NOTIFIER BASICS

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

CREATING A NEW EVENT SOURCE

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

CREATING A NEW NOTIFIER

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

REPLACING THE NOTIFIER

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

EXTERNAL EVENT LOOPS

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

SEE ALSO

617       Tcl_CreateFileHandler,        Tcl_DeleteFileHandler,         Tcl_Sleep,
618       Tcl_DoOneEvent, Thread(3)
619

KEYWORDS

621       event,  notifier, event queue, event sources, file events, timer, idle,
622       service mode, threads
623
624
625
626Tcl                                   8.1                          Notifier(3)
Impressum