Man Pages

Tcl_QueueEvent(3) - phpMan Tcl_QueueEvent(3) - phpMan

Command: man perldoc info search(apropos)  


Notifier(3)                 Tcl Library Procedures                 Notifier(3)



______________________________________________________________________________________________________________________

NAME
       Tcl_CreateEventSource,   Tcl_DeleteEventSource,   Tcl_SetMaxBlockTime,   Tcl_QueueEvent,  Tcl_ThreadQueueEvent,
       Tcl_ThreadAlert,  Tcl_GetCurrentThread,  Tcl_DeleteEvents,  Tcl_InitNotifier,  Tcl_FinalizeNotifier,  Tcl_Wait-
       ForEvent,  Tcl_AlertNotifier,  Tcl_SetTimer,  Tcl_ServiceAll, Tcl_ServiceEvent, Tcl_GetServiceMode, Tcl_SetSer-
       viceMode - 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.

       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_Dele-
                                                          teEvents.

       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_Ser-
                                                          viceAll.   Must  be  one  of  TCL_SERVICE_NONE  or  TCL_SER-
                                                          VICE_ALL.

       Tcl_NotifierProcs* notifierProcPtr (in)            Structure  of  function  pointers describing notifier proce-
                                                          dures that are to replace the ones  installed  in  the  exe-
                                                          cutable.  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,  con-
              taining  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 guar-
              antees  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  man-
              ner,  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_Dele-
              teEvents  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_Set-
       Timer 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_Delete-
       FileHandler must also be replaced; see CREATING A NEW NOTIFIER below for  details).   The  procedures  Tcl_Ser-
       viceAll,  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_Set-
              MaxBlockTime 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 noti-
       fier 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_Create-
       FileHandler;  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  applica-
       tion  to  wake  up  after  a specified time even if no events have occurred.  If no event source calls Tcl_Set-
       MaxBlockTime 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 proce-
       dures 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 avail-
       able  for setupProc, if there is additional information needed by Tcl_WaitForEvent on that platform.  For exam-
       ple, 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  defi-
       nition:
              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 ser-
                               viced 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  synthe-
                               sized 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  cur-
       rent  thread's  queue.   To  add  an  event  to  another thread's queue, use Tcl_ThreadQueueEvent.  Tcl_Thread-
       QueueEvent accepts as an argument a Tcl_ThreadId argument, which uniquely identifies a thread in a Tcl applica-
       tion.   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-spe-
       cific.  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 "interest-
       ing"  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 infor-
       mation (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 Win-
       dows  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 oper-
       ational  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_Set-
       Timer  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 any-
       thing.

       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  commu-
       nication 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_CreateFileHan-
       dler 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 struc-
       ture.  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 pro-
       cess 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  avail-
       able 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_Ser-
       viceAll.  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_SetSer-
       viceMode  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, Tcl_DeleteFileHandler, Tcl_Sleep, Tcl_DoOneEvent, Thread(3)

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



Tcl                                   8.1                          Notifier(3)