Provided by: tcl8.6-doc_8.6.14+dfsg-1build1_all bug

NAME

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

SYNOPSIS

       #include <tcl.h>

       void
       Tcl_CreateEventSource(setupProc, checkProc, clientData)

       void
       Tcl_DeleteEventSource(setupProc, checkProc, clientData)

       void
       Tcl_SetMaxBlockTime(timePtr)

       void
       Tcl_QueueEvent(evPtr, position)

       void
       Tcl_ThreadQueueEvent(threadId, evPtr, position)

       void
       Tcl_ThreadAlert(threadId)

       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)

       void
       Tcl_ServiceModeHook(mode)

       void
       Tcl_SetNotifier(notifierProcPtr)

ARGUMENTS

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

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

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

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

       Tcl_Event *evPtr (in)                              An event to add to the event queue.  The  storage  for
                                                          the event must have been allocated by the caller using
                                                          Tcl_Alloc or ckalloc.

       Tcl_QueuePosition position (in)                    Where   to   add   the   new   event   in  the  queue:
                                                          TCL_QUEUE_TAIL, TCL_QUEUE_HEAD, or TCL_QUEUE_MARK.

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

       Tcl_EventDeleteProc *deleteProc (in)               Procedure  to  invoke  for  each   queued   event   in
                                                          Tcl_DeleteEvents.

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

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

       Tcl_NotifierProcs* notifierProcPtr (in)            Structure of  function  pointers  describing  notifier
                                                          procedures  that  are to replace the ones installed in
                                                          the  executable.   See  REPLACING  THE  NOTIFIER   for
                                                          details.
________________________________________________________________________________________________________________

INTRODUCTION

       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 Tcl's event loop with some other event loop,
       such as one provided by an application in which Tcl is embedded.  Each of these tasks is described  in  a
       separate section below.

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

       [1]    Event sources: these represent the ways in 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 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,  and  eventually  notify  higher-level  software  that they have occurred.  The
              procedures Tcl_CreateEventSource, Tcl_DeleteEventSource, and Tcl_SetMaxBlockTime,  Tcl_QueueEvent,
              and Tcl_DeleteEvents are used primarily by event sources.

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

       [3]    The  event  loop:  in order to detect and process events, the application enters a loop that waits
              for events to occur, places them on the event queue, and then processes them.   Most  applications
              will  do  this  by  calling  the procedure Tcl_DoOneEvent, which is described in 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 a Motif application).   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_FinalizeNotifier,  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 of events it is OK to process
       and also whether or not to block if no events are ready.  Tcl_DoOneEvent does the following things:

       [1]    Check the event queue to see if it contains any events that can be serviced.  If so,  service  the
              first  possible  event,  remove  it  from  the  queue,  and  return.   It  does  this  by  calling
              Tcl_ServiceEvent and passing in the flags argument.

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

       [3]    Call  Tcl_WaitForEvent.   This  procedure  is  implemented differently 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 timePtr specifies an interval other than 0.  Tcl_WaitForEvent  returns
              when  something  has  happened,  such as a file 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 each event source.  The check procedure 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 to see if it contains any events that can be serviced.  If so, service the
              first possible event, remove it from the queue, and return.

       [6]    See if 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  blocking  was
              requested by the caller.

CREATING A NEW EVENT SOURCE

       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 and check procedures described above, plus an additional procedure that
       is invoked when an event is removed from the event queue for servicing.

       The  procedure  Tcl_CreateEventSource  creates  a  new  event  source.   Its  arguments specify the setup
       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 information 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 the bit
       corresponding to this event source is not set, the event source should return immediately  without  doing
       anything.  For example, the file 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 a platform-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_SetMaxBlockTime to force the application to wake up after a specified time even  if  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 procedure  for  the  X
       event source looks to see if there are events already queued.  If there are, it calls Tcl_SetMaxBlockTime
       with  a 0 block time so that Tcl_WaitForEvent does not block if there is no new data on the X connection.
       The timePtr argument to Tcl_WaitForEvent points to a structure that describes a time interval in  seconds
       and microseconds:

              typedef struct Tcl_Time {
                  long sec;
                  long usec;
              } Tcl_Time;

       The usec field should be less 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 an event wait is done each of the event sources'
       setup 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 a new event handler is registered that needs to
       poll for events, the event source may call Tcl_SetMaxBlockTime to set the block time 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 platform-specific procedures may also  be
       available  for setupProc, if 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 events.

       The second procedure provided by each event source is its check procedure,  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  an  event.   Tcl_DoOneEvent  calls each of the event sources in turn, so they all have a chance to
       queue any events that are ready.  The check procedure does two things.  First, it must see if any  events
       have triggered.  Different event sources do this in 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 information 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 structure  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;
                  struct Tcl_Event *nextPtr;
              } Tcl_Event;

       The  event source must fill in the proc field of the event before calling Tcl_QueueEvent.  The nextPtr is
       used to link together the events in the queue and should not be modified by the event source.

       An event may be added to the queue 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, 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, so that it will be serviced  before  all
                               other queued events.

       TCL_QUEUE_MARK          Add  the  event  at  the front of the queue, unless there are other events at the
                               front whose position is TCL_QUEUE_MARK;  if 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, such as a series of Enter and Leave
                               events synthesized during a grab or ungrab operation in Tk.

       When  it is time to handle an event from the queue (steps 1 and 4 above) Tcl_ServiceEvent will invoke the
       proc specified in 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 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 is the flags argument
       for the current call to Tcl_ServiceEvent;  this is used by the event source to return immediately if  its
       events are not relevant.

       It  is  up  to  proc  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, it may return 0 to indicate that the event should be deferred for processing later;
       in this case Tcl_ServiceEvent will go on to the next event in the queue 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 event source will always return 0 if  the
       TCL_FILE_EVENTS  bit  is  not  set  in  flags.   Another  example  of  deferring  events happens in Tk if
       Tk_RestrictEvents has been invoked to defer certain kinds of window events.

       When proc returns 1, Tcl_ServiceEvent will remove the event from the event queue 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  a  similar manner, except that there is a separate event queue for each
       thread containing a Tcl interpreter.  Calling Tcl_QueueEvent in a multithreaded application adds an event
       to the current thread's queue.  To add an event to  another  thread's  queue,  use  Tcl_ThreadQueueEvent.
       Tcl_ThreadQueueEvent  accepts  as an argument a Tcl_ThreadId argument, which uniquely identifies a thread
       in 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,  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 for each event in the queue, deleting those for with the procedure returns 1.
       Events for which the procedure returns 0 are  left  in  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 the queue.

       Tcl_DeleteEventSource deletes an event source.  The setupProc, checkProc, 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.

CREATING A NEW NOTIFIER

       The  notifier  consists  of  all  the  procedures described in 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 that they are the same for all
       notifiers.  However, none of the procedures are notifier-dependent: Tcl_InitNotifier,  Tcl_AlertNotifier,
       Tcl_FinalizeNotifier,      Tcl_SetTimer,      Tcl_Sleep,     Tcl_WaitForEvent,     Tcl_CreateFileHandler,
       Tcl_DeleteFileHandler and Tcl_ServiceModeHook.  To support a new platform or to  integrate  Tcl  with  an
       application-specific event loop, you must write 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 the notifier; it is responsible for waiting for an
       “interesting” event to occur or for a given time to elapse.  Before Tcl_WaitForEvent is invoked, each  of
       the  event  sources'  setup  procedure  will have been invoked.  The timePtr argument to Tcl_WaitForEvent
       gives the maximum time to block for an event,  based  on  calls  to  Tcl_SetMaxBlockTime  made  by  setup
       procedures and on other information (such as the TCL_DONT_WAIT bit in flags).

       Ideally,  Tcl_WaitForEvent  should  only  wait  for an event to occur; it should not actually process the
       event in any way.  Later on, the event sources will process the raw events and create Tcl_Events  on  the
       event  queue  in  their  checkProc  procedures.  However, on some platforms (such as Windows) this is not
       possible; events may be processed  in  Tcl_WaitForEvent,  including  queuing  Tcl_Events  and  more  (for
       example,  callbacks  for  native widgets may be invoked).  The return value from Tcl_WaitForEvent must be
       either 0, 1, or -1.  On platforms such as Windows where  events  get  processed  in  Tcl_WaitForEvent,  a
       return  value  of 1 means that there may be more events still pending that have not been processed.  This
       is a sign to the caller that it must call Tcl_WaitForEvent again if 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 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_WaitForEvent would have waited forever because there were  no
       active event sources and the timeout was infinite.

       Tcl_AlertNotifier  is used in 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  has  been
       reduced.   Tcl_SetTimer  should  arrange  for  the external event loop to invoke Tcl_ServiceAll after the
       specified interval even if no events have occurred.  This interface is needed because Tcl_WaitForEvent is
       not invoked when there is an external event loop.  If the notifier will only be used from Tcl_DoOneEvent,
       then Tcl_SetTimer need not do anything.

       Tcl_ServiceModeHook is called by the platform-independent portion of the notifier when client code  makes
       a  call  to  Tcl_SetServiceMode.  This hook is provided to support operating systems that require special
       event handling when the application is in a modal loop (the Windows notifier,  for  instance,  uses  this
       hook to create a communication window).

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

       The Tcl_Sleep and Tcl_DoOneEvent interfaces are described in their respective manual pages.

       The  easiest  way  to  create a new notifier is to look at the code for an existing notifier, such as the
       files unix/tclUnixNotfy.c or win/tclWinNotify.c in the Tcl source distribution.

REPLACING THE NOTIFIER

       A notifier that has been written according to the conventions above can also be installed  in  a  running
       process  in  place  of  the standard notifier.  This mechanism is used so that a single executable can be
       used (with the standard notifier) as a stand-alone program and reused (with a replacement notifier  in  a
       loadable extension) as an extension to another program, such as a Web browser plugin.

       To  do  this, the extension makes a call to Tcl_SetNotifier passing a pointer to a Tcl_NotifierProcs data
       structure.  The structure has the following layout:

              typedef struct Tcl_NotifierProcs {
                  Tcl_SetTimerProc *setTimerProc;
                  Tcl_WaitForEventProc *waitForEventProc;
                  Tcl_CreateFileHandlerProc *createFileHandlerProc;
                  Tcl_DeleteFileHandlerProc *deleteFileHandlerProc;
                  Tcl_InitNotifierProc *initNotifierProc;
                  Tcl_FinalizeNotifierProc *finalizeNotifierProc;
                  Tcl_AlertNotifierProc *alertNotifierProc;
                  Tcl_ServiceModeHookProc *serviceModeHookProc;
              } Tcl_NotifierProcs;

       Following the call to Tcl_SetNotifier, the pointers given  in  the  Tcl_NotifierProcs  structure  replace
       whatever notifier had been installed in the process.

       It is extraordinarily unwise to replace a running notifier. Normally, Tcl_SetNotifier should be called at
       process initialization time before the first call to Tcl_InitNotifier.

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  the  case  of
       recursive  event  loops  such as calls to the Tcl commands update or vwait.  Most of the time is spent in
       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  regular  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  easiest  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 no events are available on the system event queue.

       As  a  side  effect  of  processing  events  detected  in  the  main  external event loop, Tcl may invoke
       Tcl_DoOneEvent to start a recursive event loop in commands like vwait.  Tcl_DoOneEvent  will  invoke  the
       external  event  loop, which will result in callbacks as described in the preceding paragraph, which will
       result in calls to Tcl_ServiceAll.  However, in these cases  it  is  undesirable  to  service  events  in
       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 services all
       pending events.  To handle this situation, Tcl_DoOneEvent sets a flag for Tcl_ServiceAll that  causes  it
       to return without servicing 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 service 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 the service
       mode so that all events get processed in Tcl_ServiceAll.  This is done by invoking the Tcl_SetServiceMode
       procedure.  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_ServiceAll 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 service mode.

SEE ALSO

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

KEYWORDS

       event, notifier, event queue, event sources, file events, timer, idle, service mode, threads

Tcl                                                    8.1                                        Notifier(3tcl)