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

ARGUMENTS

71       Tcl_EventSetupProc    *setupProc     (in)      Procedure to  invoke  to
72                                                      prepare  for  event wait
73                                                      in Tcl_DoOneEvent.
74
75       Tcl_EventCheckProc    *checkProc     (in)      Procedure            for
76                                                      Tcl_DoOneEvent to invoke
77                                                      after    waiting     for
78                                                      events.   Checks  to see
79                                                      if   any   events   have
80                                                      occurred   and,  if  so,
81                                                      queues them.
82
83       ClientData            clientData     (in)      Arbitrary one-word value
84                                                      to  pass  to  setupProc,
85                                                      checkProc,            or
86                                                      deleteProc.
87
88       Tcl_Time              *timePtr       (in)      Indicates   the  maximum
89                                                      amount of time  to  wait
90                                                      for  an  event.  This is
91                                                      specified as an interval
92                                                      (how  long to wait), not
93                                                      an absolute  time  (when
94                                                      to   wakeup).    If  the
95                                                      pointer    passed     to
96                                                      Tcl_WaitForEvent      is
97                                                      NULL, it means there  is
98                                                      no  maximum  wait  time:
99                                                      wait forever  if  neces‐
100                                                      sary.
101
102       Tcl_Event             *evPtr         (in)      An  event  to add to the
103                                                      event queue.  The  stor‐
104                                                      age  for  the event must
105                                                      have been  allocated  by
106                                                      the     caller     using
107                                                      Tcl_Alloc or ckalloc.
108
109       Tcl_QueuePosition     position       (in)      Where  to  add  the  new
110                                                      event   in   the  queue:
111                                                      TCL_QUEUE_TAIL,
112                                                      TCL_QUEUE_HEAD,       or
113                                                      TCL_QUEUE_MARK.
114
115       Tcl_ThreadId          threadId       (in)      A unique identifier  for
116                                                      a thread.
117
118       Tcl_EventDeleteProc   *deleteProc    (in)      Procedure  to invoke for
119                                                      each  queued  event   in
120                                                      Tcl_DeleteEvents.
121
122       int                   flags          (in)      What  types of events to
123                                                      service.   These   flags
124                                                      are  the  same  as those
125                                                      passed                to
126                                                      Tcl_DoOneEvent.          │
127
128       int                   mode           (in)                               │
129                                                      Indicates whether events │
130                                                      should  be  serviced  by │
131                                                      Tcl_ServiceAll.  Must be │
132                                                      one of  TCL_SERVICE_NONE 
133                                                      or TCL_SERVICE_ALL.
134_________________________________________________________________
135
136

INTRODUCTION

138       The interfaces described here are used to customize the Tcl event loop.
139       The two most common customizations are to add new sources of events and
140       to  merge Tcl's event loop with some other event loop, such as one pro‐
141       vided by an application in which Tcl is embedded.  Each of these  tasks
142       is described in a separate section below.
143
144       The  procedures  in  this  manual  entry are the building blocks out of
145       which the Tcl event notifier is constructed.  The event notifier is the
146       lowest layer in the Tcl event mechanism.  It consists of three things:
147
148       [1]    Event  sources:  these represent the ways in which events can be
149              generated.  For example, there is  a  timer  event  source  that
150              implements  the  Tcl_CreateTimerHandler  procedure and the after
151              command, and there is a file event source  that  implements  the
152              Tcl_CreateFileHandler  procedure  on  Unix  systems.   An  event
153              source must work with the notifier to detect events at the right
154              times,  record  them  on  the event queue, and eventually notify
155              higher-level software that they have occurred.   The  procedures
156              Tcl_CreateEventSource,   Tcl_DeleteEventSource,   and   Tcl_Set‐
157              MaxBlockTime, Tcl_QueueEvent, and Tcl_DeleteEvents are used pri‐
158              marily by event sources.
159
160       [2]    The  event queue: for non-threaded applications, there is a sin‐
161              gle queue for the whole application, containing events that have
162              been  detected but not yet serviced.  Event sources place events
163              onto the queue so that they may be processed in order at  appro‐
164              priate times during the event loop. The event queue guarantees a
165              fair discipline of event handling, so that no event  source  can
166              starve  the  others.  It also allows events to be saved for ser‐
167              vicing at a future time.  Threaded applications work in a  simi‐ │
168              lar manner, except that there is a separate event queue for each │
169              thread containing a Tcl  interpreter.   Tcl_QueueEvent  is  used │
170              (primarily  by  event  sources) to add events to the event queue │
171              and Tcl_DeleteEvents is used to remove  events  from  the  queue │
172              without   processing   them.    In   a   threaded   application, │
173              Tcl_QueueEvent adds an event to the current thread's queue,  and │
174              Tcl_ThreadQueueEvent  adds  an  event  to  a queue in a specific │
175              thread.                                                          │
176
177       [3]                                                                     │
178              The event loop: in order  to  detect  and  process  events,  the │
179              application enters a loop that waits for events to occur, places │
180              them on the event queue, and then processes them.  Most applica‐ │
181              tions  will  do  this  by  calling the procedure Tcl_DoOneEvent, │
182              which is described in a separate manual entry.                   │
183
184       Most Tcl applications need not worry about any of the internals of  the │
185       Tcl  notifier.   However, the notifier now has enough flexibility to be │
186       retargeted either for a new platform or to use an external  event  loop │
187       (such as the Motif event loop, when Tcl is embedded in a Motif applica‐ │
188       tion).  The procedures Tcl_WaitForEvent and Tcl_SetTimer  are  normally │
189       implemented  by  Tcl, but may be replaced with new versions to retarget │
190       the notifier (the Tcl_InitNotifier, Tcl_AlertNotifier,  Tcl_FinalizeNo‐ 
191       tifier,  Tcl_Sleep,  Tcl_CreateFileHandler,  and  Tcl_DeleteFileHandler 
192       must also be replaced; see CREATING A NEW NOTIFIER below for  details). │
193       The  procedures  Tcl_ServiceAll,  Tcl_ServiceEvent, Tcl_GetServiceMode, │
194       and Tcl_SetServiceMode are provided to help connect Tcl's event loop to │
195       an external event loop such as Motif's.                                 │
196

NOTIFIER BASICS │

198       The  easiest  way  to  understand how the notifier works is to consider
199       what happens when Tcl_DoOneEvent is called.  Tcl_DoOneEvent is passed a
200       flags  argument  that indicates what sort of events it is OK to process
201       and  also  whether  or  not  to  block  if   no   events   are   ready.
202       Tcl_DoOneEvent does the following things:
203
204       [1]    Check  the event queue to see if it contains any events that can
205              be serviced.  If so, service the first possible event, remove it │
206              from  the  queue,  and return.  It does this by calling Tcl_Ser‐ 
207              viceEvent and passing in the flags argument.
208
209       [2]    Prepare to block for  an  event.   To  do  this,  Tcl_DoOneEvent
210              invokes  a  setup  procedure  in  each  event source.  The event
211              source will perform  event-source  specific  initialization  and │
212              possibly  call  Tcl_SetMaxBlockTime  to limit how long Tcl_Wait‐
213              ForEvent will block if no new events occur.
214
215       [3]    Call Tcl_WaitForEvent.  This procedure  is  implemented  differ‐
216              ently  on  different platforms;  it waits for an event to occur,
217              based on the information provided by the event sources.  It  may
218              cause  the application to block if timePtr specifies an interval
219              other than 0.  Tcl_WaitForEvent returns when something has  hap‐
220              pened, such as a file becoming readable or the interval given by
221              timePtr expiring.  If there are no events  for  Tcl_WaitForEvent
222              to  wait  for,  so  that it would block forever, then it returns
223              immediately and Tcl_DoOneEvent returns 0.
224
225       [4]    Call a check procedure in each event source.  The  check  proce‐
226              dure  determines  whether  any events of interest to this source
227              occurred.  If so, the events are added to the event queue.
228
229       [5]    Check the event queue to see if it contains any events that  can
230              be serviced.  If so, service the first possible event, remove it
231              from the queue, and return.
232
233       [6]    See if there are idle callbacks pending. If so,  invoke  all  of
234              them and return.
235
236       [7]    Either  return  0  to  indicate that no events were ready, or go
237              back to step [2] if blocking was requested by the caller.
238
239

CREATING A NEW EVENT SOURCE

241       An event source consists of three procedures invoked by  the  notifier,
242       plus  additional  C procedures that are invoked by higher-level code to
243       arrange for event-driven callbacks.  The three procedures called by the
244       notifier  consist  of  the  setup and check procedures described above,
245       plus an additional procedure that is invoked when an event  is  removed
246       from the event queue for servicing.
247
248       The  procedure  Tcl_CreateEventSource  creates a new event source.  Its
249       arguments specify the setup procedure and check procedure for the event
250       source.  SetupProc should match the following prototype:
251              typedef void Tcl_EventSetupProc(
252                ClientData clientData,
253                int flags);
254       The  clientData argument will be the same as the clientData argument to
255       Tcl_CreateEventSource;  it is typically used to point to private infor‐
256       mation  managed  by  the  event source.  The flags argument will be the
257       same as the flags argument passed to Tcl_DoOneEvent except that it will
258       never  be  0  (Tcl_DoOneEvent  replaces  0 with TCL_ALL_EVENTS).  Flags
259       indicates what kinds of events should be considered; if the bit  corre‐
260       sponding to this event source isn't set, the event source should return
261       immediately without doing anything.  For example, the file event source
262       checks for the TCL_FILE_EVENTS bit.
263
264       SetupProc's  job  is  to  make  sure that the application wakes up when
265       events of the desired type occur.  This is typically done  in  a  plat‐
266       form-dependent  fashion.  For example, under Unix an event source might
267       call Tcl_CreateFileHandler; under Windows it might request notification
268       with  a  Windows  event.   For timer-driven event sources such as timer
269       events or any polled event, the event source can call  Tcl_SetMaxBlock‐
270       Time to force the application to wake up after a specified time even if
271       no events have occurred.  If no event source calls  Tcl_SetMaxBlockTime 
272       then  Tcl_WaitForEvent  will  wait as long as necessary for an event to │
273       occur; otherwise, it will only wait as long as  the  shortest  interval │
274       passed to Tcl_SetMaxBlockTime by one of the event sources.  If an event │
275       source knows that it already has events ready to report, it can request │
276       a  zero maximum block time.  For example, the setup procedure for the X │
277       event source looks to see if there are events already queued.  If there │
278       are, it calls Tcl_SetMaxBlockTime with a 0 block time so that Tcl_Wait‐ 
279       ForEvent does not block if there is no new data on  the  X  connection.
280       The  timePtr  argument  to  Tcl_WaitForEvent points to a structure that
281       describes a time interval in seconds and microseconds:
282              typedef struct Tcl_Time {
283                long sec;
284                long usec;
285              } Tcl_Time;
286       The usec field should be less than 1000000.
287
288       Information provided to Tcl_SetMaxBlockTime is only used for  the  next │
289       call  to  Tcl_WaitForEvent;  it  is  discarded  after  Tcl_WaitForEvent 
290       returns.  The next time an  event  wait  is  done  each  of  the  event
291       sources'  setup  procedures  will be called again, and they can specify
292       new information for that event wait.
293
294       If  the  application  uses  an  external   event   loop   rather   than │
295       Tcl_DoOneEvent,  the event sources may need to call Tcl_SetMaxBlockTime 
296       at other times.  For example, if a new event handler is registered that │
297       needs to poll for events, the event source may call Tcl_SetMaxBlockTime 
298       to set the block time to zero to force the external event loop to  call │
299       Tcl.   In  this case, Tcl_SetMaxBlockTime invokes Tcl_SetTimer with the │
300       shortest interval  seen  since  the  last  call  to  Tcl_DoOneEvent  or │
301       Tcl_ServiceAll.                                                         │
302
303       In  addition  to the generic procedure Tcl_SetMaxBlockTime, other plat‐ │
304       form-specific procedures may also be available for setupProc, if  there │
305       is  additional information needed by Tcl_WaitForEvent on that platform. │
306       For example, on Unix systems the Tcl_CreateFileHandler interface can be │
307       used to wait for file events.
308
309       The  second procedure provided by each event source is its check proce‐
310       dure, indicated by the  checkProc  argument  to  Tcl_CreateEventSource.
311       CheckProc must match the following prototype:
312              typedef void Tcl_EventCheckProc(
313                ClientData clientData,
314                int flags);
315       The  arguments  to  this procedure are the same as those for setupProc.
316       CheckProc is invoked by Tcl_DoOneEvent after it has waited for  events.
317       Presumably at least one event source is now prepared to queue an event.
318       Tcl_DoOneEvent calls each of the event sources in  turn,  so  they  all
319       have  a chance to queue any events that are ready.  The check procedure
320       does two things.  First, it must see  if  any  events  have  triggered.
321       Different event sources do this in different ways.
322
323       If  an  event source's check procedure detects an interesting event, it
324       must add the event to Tcl's event queue.  To do this, the event  source
325       calls Tcl_QueueEvent.  The evPtr argument is a pointer to a dynamically
326       allocated structure containing the event (see below for  more  informa‐
327       tion  on  memory  management issues).  Each event source can define its
328       own event structure with whatever information is relevant to that event
329       source.   However,  the first element of the structure must be a struc‐
330       ture of type Tcl_Event, and the address of this structure is used  when
331       communicating between the event source and the rest of the notifier.  A
332       Tcl_Event has the following definition:
333              typedef struct {
334                  Tcl_EventProc *proc;
335                  struct Tcl_Event *nextPtr;
336              } Tcl_Event;
337       The event source must fill in the proc field of the event before  call‐
338       ing Tcl_QueueEvent.  The nextPtr is used to link together the events in
339       the queue and should not be modified by the event source.
340
341       An event may be added to the queue at any of three positions, depending
342       on the position argument to Tcl_QueueEvent:
343
344       TCL_QUEUE_TAIL          Add the event at the back of the queue, so that
345                               all  other  pending  events  will  be  serviced
346                               first.   This  is almost always the right place
347                               for new events.
348
349       TCL_QUEUE_HEAD          Add the event at the front  of  the  queue,  so
350                               that  it  will  be  serviced  before  all other
351                               queued events.
352
353       TCL_QUEUE_MARK          Add the event at the front of the queue, unless
354                               there are other events at the front whose posi‐
355                               tion is TCL_QUEUE_MARK;  if  so,  add  the  new
356                               event   just  after  all  other  TCL_QUEUE_MARK
357                               events.  This value  of  position  is  used  to
358                               insert  an  ordered  sequence  of events at the
359                               front of the queue, such as a series  of  Enter
360                               and  Leave  events synthesized during a grab or
361                               ungrab operation in Tk.
362
363       When it is time to handle an event from the queue (steps 1 and 4 above) │
364       Tcl_ServiceEvent  will  invoke  the  proc specified in the first queued
365       Tcl_Event structure.  Proc must match the following prototype:
366              typedef int Tcl_EventProc(
367                Tcl_Event *evPtr,
368                int flags);
369       The first argument to proc is a pointer to the event, which will be the
370       same  as  the  first argument to the Tcl_QueueEvent call that added the
371       event to the queue.  The second argument to proc is the flags  argument
372       for  the  current  call to Tcl_ServiceEvent;  this is used by the event │
373       source to return immediately if its events are not relevant.
374
375       It is up to proc to handle the event, typically by invoking one or more
376       Tcl  commands or C-level callbacks.  Once the event source has finished
377       handling the event it returns 1 to  indicate  that  the  event  can  be
378       removed  from  the  queue.  If for some reason the event source decides
379       that the event cannot be handled at this time, it may return 0 to indi‐
380       cate  that  the event should be deferred for processing later;  in this │
381       case Tcl_ServiceEvent will go on to the next event  in  the  queue  and
382       attempt  to  service it.  There are several reasons why an event source
383       might defer an event.  One possibility is that events of this type  are
384       excluded  by  the  flags  argument.  For example, the file event source
385       will always return 0 if the TCL_FILE_EVENTS bit  isn't  set  in  flags.
386       Another  example of deferring events happens in Tk if Tk_RestrictEvents
387       has been invoked to defer certain kinds of window events.
388
389       When proc returns 1, Tcl_ServiceEvent will remove the  event  from  the │
390       event  queue  and free its storage.  Note that the storage for an event │
391       must be allocated by the event source (using Tcl_Alloc or the Tcl macro │
392       ckalloc)  before  calling  Tcl_QueueEvent,  but  it  will  be  freed by │
393       Tcl_ServiceEvent, not by the event source.                              │
394
395       Threaded applications work in a similar manner, except that there is  a │
396       separate  event  queue  for  each  thread containing a Tcl interpreter. │
397       Calling Tcl_QueueEvent in a multithreaded application adds an event  to │
398       the current thread's queue.  To add an event to another thread's queue, │
399       use Tcl_ThreadQueueEvent.  Tcl_ThreadQueueEvent accepts as an  argument │
400       a  Tcl_ThreadId  argument,  which uniquely identifies a thread in a Tcl │
401       application.  To obtain the Tcl_ThreadID for the  current  thread,  use │
402       the  Tcl_GetCurrentThread procedure.  (A thread would then need to pass │
403       this identifier to other threads for those threads to be  able  to  add │
404       events to its queue.)  After adding an event to another thread's queue, │
405       you then typically need to  call  Tcl_ThreadAlert  to  "wake  up"  that │
406       thread's notifier to alert it to the new event.                         │
407
408       Tcl_DeleteEvents  can  be  used to explicitly remove one or more events │
409       from the event queue.  Tcl_DeleteEvents calls proc for  each  event  in │
410       the queue, deleting those for with the procedure returns 1.  Events for │
411       which the procedure returns 0 are left in the queue.  Proc should match │
412       the following prototype:                                                │
413              typedef int Tcl_EventDeleteProc(                                 │
414                Tcl_Event *evPtr,                                              │
415                ClientData clientData);                                        │
416       The  clientData argument will be the same as the clientData argument to │
417       Tcl_DeleteEvents; it is typically used to point to private  information │
418       managed by the event source.  The evPtr will point to the next event in │
419       the queue.                                                              │
420
421       Tcl_DeleteEventSource deletes an event source.  The  setupProc,  check‐
422       Proc, and clientData arguments must exactly match those provided to the │
423       Tcl_CreateEventSource for the event source to be deleted.  If  no  such │
424       source exists, Tcl_DeleteEventSource has no effect.
425
426

CREATING A NEW NOTIFIER

428       The  notifier  consists  of all the procedures described in this manual
429       entry, plus Tcl_DoOneEvent and Tcl_Sleep, which are  available  on  all │
430       platforms,  and  Tcl_CreateFileHandler and Tcl_DeleteFileHandler, which │
431       are Unix-specific.  Most of these procedures are generic, in that  they │
432       are  the  same for all notifiers.  However, eight of the procedures are │
433       notifier-dependent:  Tcl_InitNotifier,  Tcl_AlertNotifier,   Tcl_Final‐ 
434       izeNotifier, Tcl_SetTimer, Tcl_Sleep, Tcl_WaitForEvent, Tcl_CreateFile‐ 
435       Handler and Tcl_DeleteFileHandler.  To support a  new  platform  or  to │
436       integrate  Tcl  with an application-specific event loop, you must write │
437       new versions of these procedures.                                       │
438
439       Tcl_InitNotifier initializes the notifier state and returns a handle to │
440       the  notifier  state.  Tcl calls this procedure when initializing a Tcl │
441       interpreter.  Similarly, Tcl_FinalizeNotifier shuts down the  notifier, │
442       and is called by Tcl_Finalize when shutting down a Tcl interpreter.     │
443
444       Tcl_WaitForEvent  is  the lowest-level procedure in the notifier; it is │
445       responsible for waiting for an ``interesting'' event to occur or for  a │
446       given  time to elapse.  Before Tcl_WaitForEvent is invoked, each of the │
447       event sources' setup procedure will have  been  invoked.   The  timePtr
448       argument  to  Tcl_WaitForEvent  gives  the maximum time to block for an │
449       event, based on calls to Tcl_SetMaxBlockTime made by  setup  procedures │
450       and on other information (such as the TCL_DONT_WAIT bit in flags).      │
451
452       Ideally,  Tcl_WaitForEvent  should  only wait for an event to occur; it │
453       should not actually process the event in any way.  Later on, the  event │
454       sources  will process the raw events and create Tcl_Events on the event │
455       queue in their checkProc procedures.  However, on some platforms  (such │
456       as  Windows)  this isn't possible; events may be processed in Tcl_Wait‐ 
457       ForEvent, including queuing Tcl_Events and more (for example, callbacks │
458       for  native  widgets  may be invoked).  The return value from Tcl_Wait‐ 
459       ForEvent must be either 0, 1, or -1.   On  platforms  such  as  Windows │
460       where  events  get  processed  in Tcl_WaitForEvent, a return value of 1 │
461       means that there may be more events still  pending  that  haven't  been │
462       processed.   This  is  a sign to the caller that it must call Tcl_Wait‐ 
463       ForEvent again if it wants all pending events  to  be  processed.  A  0 │
464       return  value  means  that calling Tcl_WaitForEvent again will not have │
465       any effect: either this is a platform where Tcl_WaitForEvent only waits │
466       without  doing any event processing, or Tcl_WaitForEvent knows for sure │
467       that there are no  additional  events  to  process  (e.g.  it  returned │
468       because  the  time  elapsed).  Finally, a return value of -1 means that │
469       the event loop is no longer  operational  and  the  application  should │
470       probably  unwind  and  terminate.   Under  Windows  this happens when a │
471       WM_QUIT message is received;  under  Unix  it  happens  when  Tcl_Wait‐ 
472       ForEvent  would  have waited forever because there were no active event │
473       sources and the timeout was infinite.                                   │
474
475       Tcl_AlertNotifier is used in multithreaded applications  to  allow  any │
476       thread  to  "wake  up"  the  notifier  to alert it to new events on its │
477       queue.  Tcl_AlertNotifier requires as an argument the  notifier  handle │
478       returned by Tcl_InitNotifier.                                           │
479
480       If  the notifier will be used with an external event loop, then it must │
481       also support the Tcl_SetTimer interface.  Tcl_SetTimer  is  invoked  by │
482       Tcl_SetMaxBlockTime   whenever  the  maximum  blocking  time  has  been │
483       reduced.  Tcl_SetTimer should arrange for the external  event  loop  to │
484       invoke  Tcl_ServiceAll  after  the specified interval even if no events │
485       have occurred.  This interface is needed because Tcl_WaitForEvent isn't │
486       invoked  when  there  is  an external event loop.  If the notifier will │
487       only be used from Tcl_DoOneEvent, then Tcl_SetTimer need  not  do  any‐ │
488       thing.                                                                  │
489
490       On  Unix  systems,  the  file  event source also needs support from the │
491       notifier.  The file event source consists of the  Tcl_CreateFileHandler 
492       and  Tcl_DeleteFileHandler  procedures,  which  are  described  in  the │
493       Tcl_CreateFileHandler manual page.                                      │
494
495       The Tcl_Sleep and Tcl_DoOneEvent  interfaces  are  described  in  their │
496       respective manual pages.                                                │
497
498       The  easiest way to create a new notifier is to look at the code for an │
499       existing notifier, such as the files unix/tclUnixNotfy.c or win/tclWin‐ 
500       Notify.c in the Tcl source distribution.                                │
501
502

EXTERNAL EVENT LOOPS │

504       The  notifier  interfaces are designed so that Tcl can be embedded into │
505       applications that have their own private event loops.   In  this  case, │
506       the  application  does  not  call  Tcl_DoOneEvent except in the case of │
507       recursive event loops such as calls  to  the  Tcl  commands  update  or │
508       vwait.   Most  of  the  time is spent in the external event loop of the │
509       application.  In this case the notifier must arrange for  the  external │
510       event  loop to call back into Tcl when something happens on the various │
511       Tcl event sources.  These callbacks should arrange for appropriate  Tcl │
512       events to be placed on the Tcl event queue.                             │
513
514       Because the external event loop is not calling Tcl_DoOneEvent on a reg‐ │
515       ular basis, it is up to the notifier to arrange for Tcl_ServiceEvent to │
516       be called whenever events are pending on the Tcl event queue.  The eas‐ │
517       iest way to do this is to invoke Tcl_ServiceAll  at  the  end  of  each │
518       callback  from  the  external event loop.  This will ensure that all of │
519       the event sources are polled, any queued events are serviced,  and  any │
520       pending  idle  handlers  are  processed before returning control to the │
521       application.  In addition, event sources that need to poll  for  events │
522       can  call  Tcl_SetMaxBlockTime to force the external event loop to call │
523       Tcl even if no events are available on the system event queue.          │
524
525       As a side effect of processing events detected  in  the  main  external │
526       event  loop,  Tcl  may invoke Tcl_DoOneEvent to start a recursive event │
527       loop in commands like vwait.  Tcl_DoOneEvent will invoke  the  external │
528       event  loop, which will result in callbacks as described in the preced‐ │
529       ing paragraph, which will result in calls to Tcl_ServiceAll.   However, │
530       in  these  cases it is undesirable to service events in Tcl_ServiceAll. │
531       Servicing events there is unnecessary because control will  immediately │
532       return  to  the  external event loop and hence to Tcl_DoOneEvent, which │
533       can service the events itself.  Furthermore, Tcl_DoOneEvent is supposed │
534       to  service  only  a single event, whereas Tcl_ServiceAll normally ser‐ │
535       vices all pending events.  To  handle  this  situation,  Tcl_DoOneEvent 
536       sets a flag for Tcl_ServiceAll that causes it to return without servic‐ │
537       ing any events.  This flag is called the service  mode;  Tcl_DoOneEvent 
538       restores it to its previous value before it returns.                    │
539
540       In  some cases, however, it may be necessary for Tcl_ServiceAll to ser‐ │
541       vice events even when it has been invoked  from  Tcl_DoOneEvent.   This │
542       happens  when  there is yet another recursive event loop invoked via an │
543       event handler called by Tcl_DoOneEvent (such as one that is part  of  a │
544       native  widget).  In this case, Tcl_DoOneEvent may not have a chance to │
545       service events so Tcl_ServiceAll must service them all.  Any  recursive │
546       event loop that calls an external event loop rather than Tcl_DoOneEvent 
547       must reset the service  mode  so  that  all  events  get  processed  in │
548       Tcl_ServiceAll.  This is done by invoking the Tcl_SetServiceMode proce‐ │
549       dure.  If Tcl_SetServiceMode is passed TCL_SERVICE_NONE, then calls  to │
550       Tcl_ServiceAll  will  return immediately without processing any events. │
551       If Tcl_SetServiceMode is passed TCL_SERVICE_ALL, then calls to Tcl_Ser‐ 
552       viceAll  will behave normally.  Tcl_SetServiceMode returns the previous │
553       value of the service mode, which should be restored when the  recursive │
554       loop  exits.   Tcl_GetServiceMode returns the current value of the ser‐ │
555       vice mode.
556

SEE ALSO

558       Tcl_CreateFileHandler,        Tcl_DeleteFileHandler,         Tcl_Sleep,
559       Tcl_DoOneEvent, Thread(3)
560

KEYWORDS

562       event,  notifier, event queue, event sources, file events, timer, idle,
563       service mode, threads
564
565
566
567Tcl                                   8.1                          Notifier(3)
Impressum