Seth Woolley's Man Viewer

Tcl_CreateEventSource(3) - Tcl_AlertNotifier, Tcl_CreateEventSource, Tcl_DeleteEventSource, Tcl_DeleteEvents, Tcl_FinalizeNotifier, Tcl_GetCurrentThread, Tcl_GetServiceMode, Tcl_InitNotifier, Tcl_QueueEvent, Tcl_ServiceAll, Tcl_ServiceEvent, Tcl_SetMaxBlockTime, Tcl_SetServiceMode, Tcl_SetTimer, Tcl_ThreadAlert, Tcl_ThreadQueueEvent, Tcl_WaitForEvent - the event queue and notifier interfaces - man 3 Tcl_CreateEventSource

([section] manual, -k keyword, -K [section] search, -f whatis)
man plain no title

Notifier(3)                 Tcl Library Procedures                 Notifier(3)


       Tcl_CreateEventSource,    Tcl_DeleteEventSource,   Tcl_SetMaxBlockTime,
       Tcl_QueueEvent, Tcl_ThreadQueueEvent, Tcl_ThreadAlert,  Tcl_GetCurrent-
       Thread,   Tcl_DeleteEvents,   Tcl_InitNotifier,   Tcl_FinalizeNotifier,
       Tcl_WaitForEvent,  Tcl_AlertNotifier,   Tcl_SetTimer,   Tcl_ServiceAll,
       Tcl_ServiceEvent,  Tcl_GetServiceMode,  Tcl_SetServiceMode  - the event
       queue(1,3) and notifier interfaces

       #include <tcl.h>

       Tcl_CreateEventSource(setupProc, checkProc, clientData)

       Tcl_DeleteEventSource(setupProc, checkProc, clientData)


       Tcl_QueueEvent(evPtr, position)

       void                                                                    |
       Tcl_ThreadQueueEvent(threadId, evPtr, position)                         |

       void                                                                    |
       Tcl_ThreadAlert(threadId, clientData)                                   |

       Tcl_ThreadId                                                            |
       Tcl_GetCurrentThread()                                                  |

       void                                                                    |
       Tcl_DeleteEvents(deleteProc, clientData)                                |

       ClientData                                                              |
       Tcl_InitNotifier()                                                      |

       void                                                                    |
       Tcl_FinalizeNotifier(clientData)                                        |

       int                                                                     |
       Tcl_WaitForEvent(timePtr)                                               |

       void                                                                    |
       Tcl_AlertNotifier(clientData)                                           |

       void                                                                    |
       Tcl_SetTimer(timePtr)                                                   |

       int                                                                     |
       Tcl_ServiceAll()                                                        |

       int                                                                     |
       Tcl_ServiceEvent(flags)                                                 |

       int                                                                     |
       Tcl_GetServiceMode()                                                    |

       int                                                                     |
       Tcl_SetServiceMode(mode)                                                |

       Tcl_EventSetupProc    *setupProc     (in(1,8))      Procedure to  invoke  to
                                                      prepare  for  event wait
                                                      in(1,8) Tcl_DoOneEvent.

       Tcl_EventCheckProc    *checkProc     (in(1,8))      Procedure            for
                                                      Tcl_DoOneEvent to invoke
                                                      after    waiting     for
                                                      events.   Checks  to see
                                                      if(3,n)   any   events   have
                                                      occurred   and,  if(3,n)  so,
                                                      queues them.

       ClientData            clientData     (in(1,8))      Arbitrary one-word value
                                                      to  pass  to  setupProc,
                                                      checkProc,            or

       Tcl_Time              *timePtr       (in(1,8))      Indicates   the  maximum
                                                      amount of time(1,2,n)  to  wait
                                                      for  an  event.  This is
                                                      specified as an interval
                                                      (how  long to wait), not
                                                      an absolute  time(1,2,n)  (when
                                                      to   wakeup).    If  the
                                                      pointer    passed     to
                                                      Tcl_WaitForEvent      is
                                                      NULL, it means there  is
                                                      no  maximum  wait  time:
                                                      wait forever  if(3,n)  neces-

       Tcl_Event             *evPtr         (in(1,8))      An  event  to add to the
                                                      event queue.  The  stor-
                                                      age  for  the event must
                                                      have been  allocated  by
                                                      the     caller     using
                                                      Tcl_Alloc or ckalloc.

       Tcl_QueuePosition     position       (in(1,8))      Where  to  add  the  new
                                                      event   in(1,8)   the  queue:
                                                      TCL_QUEUE_HEAD,       or

       Tcl_ThreadId          threadId       (in(1,8))      A unique identifier  for
                                                      a thread.

       Tcl_EventDeleteProc   *deleteProc    (in(1,8))      Procedure  to invoke for
                                                      each  queued  event   in(1,8)

       int                   flags          (in(1,8))      What  types of events to
                                                      service.   These   flags
                                                      are  the  same  as those
                                                      passed                to
                                                      Tcl_DoOneEvent.          |

       int                   mode           (in(1,8))                               ||
                                                      Indicates whether events |
                                                      should  be  serviced  by |
                                                      Tcl_ServiceAll.  Must be |
                                                      one  of TCL_SERVICE_NONE |
                                                      or TCL_SERVICE_ALL.

       The interfaces described here are used to customize the Tcl event loop.
       The two most common customizations are to add new sources of events and
       to merge(1,8) Tcl's event loop with some other event loop, such as one  pro-
       vided  by an application in(1,8) which Tcl is embedded.  Each of these tasks
       is described in(1,8) a separate section below.

       The procedures in(1,8) this manual entry are  the  building  blocks  out  of
       which the Tcl event notifier is constructed.  The event notifier is the
       lowest layer in(1,8) the Tcl event mechanism.  It consists of three things:

       [1]    Event sources: these represent the ways in(1,8) which events  can  be
              generated.   For  example,  there  is  a timer event source that
              implements the Tcl_CreateTimerHandler procedure  and  the  after
              command,  and  there  is a file(1,n) event source that implements the
              Tcl_CreateFileHandler  procedure  on  Unix  systems.   An  event
              source must work with the notifier to detect events at the right
              times, record them on the event  queue(1,3),  and  eventually  notify
              higher-level  software  that they have occurred.  The procedures
              Tcl_CreateEventSource,   Tcl_DeleteEventSource,   and   Tcl_Set-
              MaxBlockTime, Tcl_QueueEvent, and Tcl_DeleteEvents are used pri-
              marily by event sources.

       [2]    The event queue: for non-threaded applications, there is a  sin-
              gle queue(1,3) for the whole application, containing events that have
              been detected but not yet serviced.  Event sources place  events
              onto  the queue(1,3) so that they may be processed in(1,8) order at appro-
              priate times during the event loop. The event queue(1,3) guarantees a
              fair  discipline  of event handling, so that no event source can
              starve the others.  It also allows events to be saved  for  ser-
              vicing  at a future time.  Threaded applications work in(1,8) a simi- |
              lar manner, except that there is a separate event queue(1,3) for each |
              thread  containing  a  Tcl  interpreter.  Tcl_QueueEvent is used |
              (primarily by event sources) to add events to  the  event  queue(1,3) |
              and  Tcl_DeleteEvents  is  used  to remove events from the queue(1,3) |
              without   processing   them.    In   a   threaded   application, |
              Tcl_QueueEvent  adds an event to the current thread's queue(1,3), and |
              Tcl_ThreadQueueEvent adds an event to  a  queue(1,3)  in(1,8)  a  specific |
              thread.                                                          |

       [3]                                                                     ||
              The event loop: in(1,8) order  to  detect  and  process  events,  the |
              application enters a loop that waits for events to occur, places |
              them on the event queue(1,3), and then processes them.  Most applica- |
              tions  will  do  this  by  calling the procedure Tcl_DoOneEvent, |
              which is described in(1,8) a separate manual entry.                   |

       Most Tcl applications need not worry about any of the internals of  the |
       Tcl  notifier.   However, the notifier now has enough flexibility to be |
       retargeted either for a new platform or to use an external  event  loop |
       (such as the Motif event loop, when Tcl is embedded in(1,8) a Motif applica- |
       tion).  The procedures Tcl_WaitForEvent and Tcl_SetTimer  are  normally |
       implemented  by  Tcl, but may be replaced with new versions to retarget |
       the notifier (the Tcl_InitNotifier, Tcl_AlertNotifier,  Tcl_FinalizeNo- |
       tifier,  Tcl_Sleep,  Tcl_CreateFileHandler,  and  Tcl_DeleteFileHandler |
       must also be replaced; see CREATING A NEW NOTIFIER below for  details). |
       The  procedures  Tcl_ServiceAll,  Tcl_ServiceEvent, Tcl_GetServiceMode, |
       and Tcl_SetServiceMode are provided to help connect Tcl's event loop to |
       an external event loop such as Motif's.                                 |

NOTIFIER BASICS                                                                |
       The  easiest  way  to  understand how the notifier works is to consider
       what happens when Tcl_DoOneEvent is called.  Tcl_DoOneEvent is passed a
       flags  argument  that indicates what sort(1,3) of events it is OK to process
       and  also  whether  or  not  to  block  if(3,n)   no   events   are   ready.
       Tcl_DoOneEvent does the following things:

       [1]    Check  the event queue(1,3) to see if(3,n) it contains any events that can
              be serviced.  If so, service the first possible event, remove it |
              from  the  queue(1,3),  and return.  It does this by calling Tcl_Ser- |
              viceEvent and passing in(1,8) the flags argument.

       [2]    Prepare to block for  an  event.   To  do  this,  Tcl_DoOneEvent
              invokes  a  setup(2,8)  procedure  in(1,8)  each  event source.  The event
              source will perform  event-source  specific  initialization  and |
              possibly  call  Tcl_SetMaxBlockTime  to limit how long Tcl_Wait-
              ForEvent will block if(3,n) no new events occur.

       [3]    Call Tcl_WaitForEvent.  This procedure  is  implemented  differ-
              ently  on  different platforms;  it waits for an event to occur,
              based on the information provided by the event sources.  It  may
              cause  the application to block if(3,n) timePtr specifies an interval
              other than 0.  Tcl_WaitForEvent returns when something has  hap-
              pened, such as a file(1,n) becoming readable or the interval given by
              timePtr expiring.  If there are no events  for  Tcl_WaitForEvent
              to  wait  for,  so  that it would block forever, then it returns
              immediately and Tcl_DoOneEvent returns 0.

       [4]    Call a check procedure in(1,8) each event source.  The  check  proce-
              dure  determines  whether  any events of interest to this source
              occurred.  If so, the events are added to the event queue.

       [5]    Check the event queue(1,3) to see if(3,n) it contains any events that  can
              be serviced.  If so, service the first possible event, remove it
              from the queue(1,3), and return.

       [6]    See if(3,n) there are idle callbacks pending. If so,  invoke  all  of
              them and return.

       [7]    Either  return  0  to  indicate that no events were ready, or go
              back to step [2] if(3,n) blocking was requested by the caller.

       An event source consists of three procedures invoked by  the  notifier,
       plus  additional  C procedures that are invoked by higher-level code to
       arrange for event-driven callbacks.  The three procedures called by the
       notifier  consist  of  the  setup(2,8) and check procedures described above,
       plus an additional procedure that is invoked when an event  is  removed
       from the event queue(1,3) for servicing.

       The  procedure  Tcl_CreateEventSource  creates a new event source.  Its
       arguments specify the setup(2,8) procedure and check procedure for the event
       source.  SetupProc should match the following prototype:
              typedef void Tcl_EventSetupProc(
                ClientData clientData,
                int flags);
       The  clientData argument will be the same as the clientData argument to
       Tcl_CreateEventSource;  it is typically used to point to private infor-
       mation  managed  by  the  event source.  The flags argument will be the
       same as the flags argument passed to Tcl_DoOneEvent except that it will
       never  be  0  (Tcl_DoOneEvent  replaces  0 with TCL_ALL_EVENTS).  Flags
       indicates what kinds of events should be considered; if(3,n) the bit  corre-
       sponding to this event source isn't set(7,n,1 builtins), the event source should return
       immediately without doing anything.  For example, the file(1,n) event source
       checks for the TCL_FILE_EVENTS bit.

       SetupProc's  job  is  to  make  sure that the application wakes up when
       events of the desired type occur.  This is typically done  in(1,8)  a  plat-
       form-dependent  fashion.  For example, under Unix an event source might
       call Tcl_CreateFileHandler; under Windows it might request notification
       with  a  Windows  event.   For timer-driven event sources such as timer
       events or any polled event, the event source can call  Tcl_SetMaxBlock-
       Time to force the application to wake up after a specified time(1,2,n) even if(3,n)
       no events have occurred.  If no event source calls  Tcl_SetMaxBlockTime |
       then  Tcl_WaitForEvent  will  wait as long as necessary for an event to |
       occur; otherwise, it will only wait as long as  the  shortest  interval |
       passed to Tcl_SetMaxBlockTime by one of the event sources.  If an event |
       source knows that it already has events ready to report, it can request |
       a  zero maximum block time.  For example, the setup(2,8) procedure for the X |
       event source looks to see if(3,n) there are events already queued.  If there |
       are, it calls Tcl_SetMaxBlockTime with a 0 block time(1,2,n) so that Tcl_Wait- |
       ForEvent does not block if(3,n) there is no new data on  the  X  connection.
       The  timePtr  argument  to  Tcl_WaitForEvent points to a structure that
       describes a time(1,2,n) interval in(1,8) seconds and microseconds:
              typedef struct Tcl_Time {
                long sec;
                long usec;
              } Tcl_Time;
       The usec field should be less(1,3) than 1000000.

       Information provided to Tcl_SetMaxBlockTime is only used for  the  next |
       call  to  Tcl_WaitForEvent;  it  is  discarded  after  Tcl_WaitForEvent |
       returns.  The next time(1,2,n) an  event  wait  is  done  each  of  the  event
       sources'  setup(2,8)  procedures  will be called again, and they can specify
       new information for that event wait.

       If  the  application  uses  an  external   event   loop   rather   than |
       Tcl_DoOneEvent,  the event sources may need to call Tcl_SetMaxBlockTime |
       at other times.  For example, if(3,n) a new event handler is registered that |
       needs to poll for events, the event source may call Tcl_SetMaxBlockTime |
       to set(7,n,1 builtins) the block time(1,2,n) to zero to force the external event loop to  call |
       Tcl.   In  this case, Tcl_SetMaxBlockTime invokes Tcl_SetTimer with the |
       shortest interval  seen  since  the  last  call  to  Tcl_DoOneEvent  or |
       Tcl_ServiceAll.                                                         |

       In  addition  to the generic procedure Tcl_SetMaxBlockTime, other plat- |
       form-specific procedures may also be available for setupProc, if(3,n)  there |
       is  additional information needed by Tcl_WaitForEvent on that platform. |
       For example, on Unix systems the Tcl_CreateFileHandler interface can be |
       used to wait for file(1,n) events.

       The  second procedure provided by each event source is its check proce-
       dure, indicated by the  checkProc  argument  to  Tcl_CreateEventSource.
       CheckProc must match the following prototype:
              typedef void Tcl_EventCheckProc(
                ClientData clientData,
                int flags);
       The  arguments  to  this procedure are the same as those for setupProc.
       CheckProc is invoked by Tcl_DoOneEvent after it has waited for  events.
       Presumably at least one event source is now prepared to queue(1,3) an event.
       Tcl_DoOneEvent calls each of the event sources in(1,8)  turn,  so  they  all
       have  a chance to queue(1,3) any events that are ready.  The check procedure
       does two things.  First, it must see  if(3,n)  any  events  have  triggered.
       Different event sources do this in(1,8) different ways.

       If  an  event source's check procedure detects an interesting event, it
       must add the event to Tcl's event queue.  To do this, the event  source
       calls Tcl_QueueEvent.  The evPtr argument is a pointer to a dynamically
       allocated structure containing the event (see below for  more  informa-
       tion  on  memory  management issues).  Each event source can define its
       own event structure with whatever information is relevant to that event
       source.   However,  the first element of the structure must be a struc-
       ture of type Tcl_Event, and the address of this structure is used  when
       communicating between the event source and the rest of the notifier.  A
       Tcl_Event has the following definition:
              typedef struct {
                  Tcl_EventProc *proc(5,n);
                  struct Tcl_Event *nextPtr;
              } Tcl_Event;
       The event source must fill in(1,8) the proc(5,n) field of the event before  call-
       ing Tcl_QueueEvent.  The nextPtr is used to link(1,2) together the events in(1,8)
       the queue(1,3) and should not be modified by the event source.

       An event may be added to the queue(1,3) at any of three positions, depending
       on the position argument to Tcl_QueueEvent:

       TCL_QUEUE_TAIL          Add the event at the back of the queue(1,3), so that
                               all  other  pending  events  will  be  serviced
                               first.   This  is almost always the right place
                               for new events.

       TCL_QUEUE_HEAD          Add the event at the front  of  the  queue(1,3),  so
                               that  it  will  be  serviced  before  all other
                               queued events.

       TCL_QUEUE_MARK          Add the event at the front of the queue(1,3), unless
                               there are other events at the front whose posi-
                               tion is TCL_QUEUE_MARK;  if(3,n)  so,  add  the  new
                               event   just  after  all  other  TCL_QUEUE_MARK
                               events.  This value  of  position  is  used  to
                               insert  an  ordered  sequence  of events at the
                               front of the queue(1,3), such as a series  of  Enter
                               and  Leave  events synthesized during a grab or
                               ungrab operation in(1,8) Tk.

       When it is time(1,2,n) to handle an event from the queue(1,3) (steps 1 and 4 above) |
       Tcl_ServiceEvent  will  invoke  the  proc(5,n) specified in(1,8) the first queued
       Tcl_Event structure.  Proc must match the following prototype:
              typedef int Tcl_EventProc(
                Tcl_Event *evPtr,
                int flags);
       The first argument to proc(5,n) is a pointer to the event, which will be the
       same  as  the  first argument to the Tcl_QueueEvent call that added the
       event to the queue.  The second argument to proc(5,n) is the flags  argument
       for  the  current  call to Tcl_ServiceEvent;  this is used by the event |
       source to return immediately if(3,n) its events are not relevant.

       It is up to proc(5,n) to handle the event, typically by invoking one or more
       Tcl  commands or C-level callbacks.  Once the event source has finished
       handling the event it returns 1 to  indicate  that  the  event  can  be
       removed  from  the  queue.  If for some reason the event source decides
       that the event cannot be handled at this time(1,2,n), it may return 0 to indi-
       cate  that  the event should be deferred for processing later;  in(1,8) this |
       case Tcl_ServiceEvent will go on to the next event  in(1,8)  the  queue(1,3)  and
       attempt  to  service it.  There are several reasons why an event source
       might defer an event.  One possibility is that events of this type  are
       excluded  by  the  flags  argument.  For example, the file(1,n) event source
       will always return 0 if(3,n) the TCL_FILE_EVENTS bit  isn't  set(7,n,1 builtins)  in(1,8)  flags.
       Another  example of deferring events happens in(1,8) Tk if(3,n) Tk_RestrictEvents
       has been invoked to defer certain kinds of window events.

       When proc(5,n) returns 1, Tcl_ServiceEvent will remove the  event  from  the |
       event  queue(1,3)  and free its storage.  Note that the storage for an event |
       must be allocated by the event source (using Tcl_Alloc or the Tcl macro |
       ckalloc)  before  calling  Tcl_QueueEvent,  but  it  will  be  freed by |
       Tcl_ServiceEvent, not by the event source.                              |

       Threaded applications work in(1,8) a similar manner, except that there is  a |
       separate  event  queue(1,3)  for  each  thread containing a Tcl interpreter. |
       Calling Tcl_QueueEvent in(1,8) a multithreaded application adds an event  to |
       the current thread's queue.  To add an event to another thread's queue(1,3), |
       use Tcl_ThreadQueueEvent.  Tcl_ThreadQueueEvent accepts as an  argument |
       a  Tcl_ThreadId  argument,  which uniquely identifies a thread in(1,8) a Tcl |
       application.  To obtain the Tcl_ThreadID for the  current  thread,  use |
       the  Tcl_GetCurrentThread procedure.  (A thread would then need to pass |
       this identifier to other threads for those threads to be  able  to  add |
       events to its queue.)  After adding an event to another thread's queue(1,3), |
       you then typically need to  call  Tcl_ThreadAlert  to  "wake  up"  that |
       thread's notifier to alert it to the new event.                         |

       Tcl_DeleteEvents  can  be  used to explicitly remove one or more events |
       from the event queue.  Tcl_DeleteEvents calls proc(5,n) for  each  event  in(1,8) |
       the queue(1,3), deleting those for with the procedure returns 1.  Events for |
       which the procedure returns 0 are left in(1,8) the queue.  Proc should match |
       the following prototype:                                                |
              typedef int Tcl_EventDeleteProc(                                 |
                Tcl_Event *evPtr,                                              |
                ClientData clientData);                                        |
       The  clientData argument will be the same as the clientData argument to |
       Tcl_DeleteEvents; it is typically used to point to private  information |
       managed by the event source.  The evPtr will point to the next event in(1,8) |
       the queue.                                                              |

       Tcl_DeleteEventSource deletes an event source.  The  setupProc,  check- |
       Proc, and clientData arguments must exactly match those provided to the |
       Tcl_CreateEventSource for the event source to be deleted.  If  no  such |
       source exists, Tcl_DeleteEventSource has no effect.

       The  notifier  consists  of all the procedures described in(1,8) this manual
       entry, plus Tcl_DoOneEvent and Tcl_Sleep, which are  available  on  all |
       platforms,  and  Tcl_CreateFileHandler and Tcl_DeleteFileHandler, which |
       are Unix-specific.  Most of these procedures are generic, in(1,8) that  they |
       are  the  same for all notifiers.  However, eight of the procedures are |
       notifier-dependent:  Tcl_InitNotifier,  Tcl_AlertNotifier,   Tcl_Final- |
       izeNotifier, Tcl_SetTimer, Tcl_Sleep, Tcl_WaitForEvent, Tcl_CreateFile- |
       Handler and Tcl_DeleteFileHandler.  To support a  new  platform  or  to |
       integrate  Tcl  with an application-specific event loop, you must write(1,2) |
       new versions of these procedures.                                       |

       Tcl_InitNotifier initializes the notifier state and returns a handle to |
       the  notifier  state.  Tcl calls this procedure when initializing a Tcl |
       interpreter.  Similarly, Tcl_FinalizeNotifier shuts down the  notifier, |
       and is called by Tcl_Finalize when shutting down a Tcl interpreter.     |

       Tcl_WaitForEvent  is  the lowest-level procedure in(1,8) the notifier; it is |
       responsible for waiting for an ``interesting'' event to occur or for  a |
       given  time(1,2,n) to elapse.  Before Tcl_WaitForEvent is invoked, each of the |
       event sources' setup(2,8) procedure will have  been  invoked.   The  timePtr |
       argument  to  Tcl_WaitForEvent  gives  the maximum time(1,2,n) to block for an |
       event, based on calls to Tcl_SetMaxBlockTime made by  setup(2,8)  procedures |
       and on other information (such as the TCL_DONT_WAIT bit in(1,8) flags).      |

       Ideally,  Tcl_WaitForEvent  should  only wait for an event to occur; it |
       should not actually process the event in(1,8) any way.  Later on, the  event |
       sources  will process the raw(3x,7,8,3x cbreak) events and create Tcl_Events on the event |
       queue(1,3) in(1,8) their checkProc procedures.  However, on some platforms  (such |
       as  Windows)  this isn't possible; events may be processed in(1,8) Tcl_Wait- |
       ForEvent, including queuing Tcl_Events and more (for example, callbacks |
       for  native  widgets  may be invoked).  The return value from Tcl_Wait- |
       ForEvent must be either 0, 1, or -1.   On  platforms  such  as  Windows |
       where  events  get  processed  in(1,8) Tcl_WaitForEvent, a return value of 1 |
       means that there may be more events still  pending  that  haven't  been |
       processed.   This  is  a sign to the caller that it must call Tcl_Wait- |
       ForEvent again if(3,n) it wants all pending events  to  be  processed.  A  0 |
       return  value  means  that calling Tcl_WaitForEvent again will not have |
       any effect: either this is a platform where Tcl_WaitForEvent only waits |
       without  doing any event processing, or Tcl_WaitForEvent knows for sure |
       that there are no  additional  events  to  process  (e.g.  it  returned |
       because  the  time(1,2,n)  elapsed).  Finally, a return value of -1 means that |
       the event loop is no longer  operational  and  the  application  should |
       probably  unwind  and  terminate.   Under  Windows  this happens when a |
       WM_QUIT message is received;  under  Unix  it  happens  when  Tcl_Wait- |
       ForEvent  would  have waited forever because there were no active event |
       sources and the timeout(1,3x,3x cbreak) was infinite.                                   |

       Tcl_AlertNotifier is used in(1,8) multithreaded applications  to  allow  any |
       thread  to  "wake  up"  the  notifier  to alert it to new events on its |
       queue.  Tcl_AlertNotifier requires as an argument the  notifier  handle |
       returned by Tcl_InitNotifier.                                           |

       If  the notifier will be used with an external event loop, then it must |
       also support the Tcl_SetTimer interface.  Tcl_SetTimer  is  invoked  by |
       Tcl_SetMaxBlockTime   whenever  the  maximum  blocking  time(1,2,n)  has  been |
       reduced.  Tcl_SetTimer should arrange for the external  event  loop  to |
       invoke  Tcl_ServiceAll  after  the specified interval even if(3,n) no events |
       have occurred.  This interface is needed because Tcl_WaitForEvent isn't |
       invoked  when  there  is  an external event loop.  If the notifier will |
       only be used from Tcl_DoOneEvent, then Tcl_SetTimer need  not  do  any- |
       thing.                                                                  |

       On  Unix  systems,  the  file(1,n)  event source also needs support from the |
       notifier.  The file(1,n) event source consists of the  Tcl_CreateFileHandler |
       and  Tcl_DeleteFileHandler  procedures,  which  are  described  in(1,8)  the |
       Tcl_CreateFileHandler manual page.                                      |

       The Tcl_Sleep and Tcl_DoOneEvent  interfaces  are  described  in(1,8)  their |
       respective manual pages.                                                |

       The  easiest way to create a new notifier is to look(1,8,3 Search::Dict) at the code for an |
       existing notifier, such as the files unix/tclUnixNotfy.c or win/tclWin- |
       Notify.c in(1,8) the Tcl source distribution.                                |

EXTERNAL EVENT LOOPS                                                           |
       The  notifier  interfaces are designed so that Tcl can be embedded into |
       applications that have their own private event loops.   In  this  case, |
       the  application  does  not  call  Tcl_DoOneEvent except in(1,8) the case of |
       recursive event loops such as calls  to  the  Tcl  commands  update(7,n)  or |
       vwait.   Most  of  the  time(1,2,n) is spent in(1,8) the external event loop of the |
       application.  In this case the notifier must arrange for  the  external |
       event  loop to call back into Tcl when something happens on the various |
       Tcl event sources.  These callbacks should arrange for appropriate  Tcl |
       events to be placed on the Tcl event queue.                             |

       Because the external event loop is not calling Tcl_DoOneEvent on a reg- |
       ular basis, it is up to the notifier to arrange for Tcl_ServiceEvent to |
       be called whenever events are pending on the Tcl event queue.  The eas- |
       iest way to do this is to invoke Tcl_ServiceAll  at  the  end  of  each |
       callback  from  the  external event loop.  This will ensure that all of |
       the event sources are polled, any queued events are serviced,  and  any |
       pending  idle  handlers  are  processed before returning control to the |
       application.  In addition, event sources that need to poll  for  events |
       can  call  Tcl_SetMaxBlockTime to force the external event loop to call |
       Tcl even if(3,n) no events are available on the system event queue.          |

       As a side effect of processing events detected  in(1,8)  the  main  external |
       event  loop,  Tcl  may invoke Tcl_DoOneEvent to start a recursive event |
       loop in(1,8) commands like vwait.  Tcl_DoOneEvent will invoke  the  external |
       event  loop, which will result in(1,8) callbacks as described in(1,8) the preced- |
       ing paragraph, which will result in(1,8) calls to Tcl_ServiceAll.   However, |
       in(1,8)  these  cases it is undesirable to service events in(1,8) Tcl_ServiceAll. |
       Servicing events there is unnecessary because control will  immediately |
       return  to  the  external event loop and hence to Tcl_DoOneEvent, which |
       can service the events itself.  Furthermore, Tcl_DoOneEvent is supposed |
       to  service  only  a single event, whereas Tcl_ServiceAll normally ser- |
       vices all pending events.  To  handle  this  situation,  Tcl_DoOneEvent |
       sets a flag for Tcl_ServiceAll that causes it to return without servic- |
       ing any events.  This flag is called the service  mode;  Tcl_DoOneEvent |
       restores it to its previous value before it returns.                    |

       In  some cases, however, it may be necessary for Tcl_ServiceAll to ser- |
       vice events even when it has been invoked  from  Tcl_DoOneEvent.   This |
       happens  when  there is yet another recursive event loop invoked via an |
       event handler called by Tcl_DoOneEvent (such as one that is part  of  a |
       native  widget).  In this case, Tcl_DoOneEvent may not have a chance to |
       service events so Tcl_ServiceAll must service them all.  Any  recursive |
       event loop that calls an external event loop rather than Tcl_DoOneEvent |
       must reset(1,7,1 tput) the service  mode  so  that  all  events  get  processed  in(1,8) |
       Tcl_ServiceAll.  This is done by invoking the Tcl_SetServiceMode proce- |
       dure.  If Tcl_SetServiceMode is passed TCL_SERVICE_NONE, then calls  to |
       Tcl_ServiceAll  will  return immediately without processing any events. |
       If Tcl_SetServiceMode is passed TCL_SERVICE_ALL, then calls to Tcl_Ser- |
       viceAll  will behave normally.  Tcl_SetServiceMode returns the previous |
       value of the service mode, which should be restored when the  recursive |
       loop  exits.   Tcl_GetServiceMode returns the current value of the ser- |
       vice mode.

       Tcl_CreateFileHandler,        Tcl_DeleteFileHandler,         Tcl_Sleep,
       Tcl_DoOneEvent, Thread(3)

       event,  notifier, event queue(1,3), event sources, file(1,n) events, timer, idle,
       service mode, threads

Tcl                                   8.1                          Notifier(3)

References for this manual (incoming links)