Skip site navigation (1)Skip section navigation (2)

FreeBSD Manual Pages

  
 
  

home | help
Notifier(3)		     Tcl Library Procedures		     Notifier(3)

________________________________________________________________________________

NAME
     Tcl_CreateEventSource,	 Tcl_DeleteEventSource,     Tcl_SetMaxBlockTime,
     Tcl_QueueEvent,  Tcl_ThreadQueueEvent,   Tcl_ThreadAlert,	 Tcl_GetCurrent-
     Thread, Tcl_DeleteEvents, Tcl_InitNotifier, Tcl_FinalizeNotifier, Tcl_Wait-
     ForEvent,	 Tcl_AlertNotifier,   Tcl_SetTimer,   Tcl_ServiceAll,	Tcl_Ser-
     viceEvent,  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  oc-
							curred	 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  neces-
							sary.

     Tcl_Event *evPtr (in)				An  event  to add to the
							event queue.  The  stor-
							age  for  the event must
							have been  allocated  by
							the caller using Tcl_Al-
							loc 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  no-
							tifier	procedures  that
							are to replace the  ones
							installed  in  the  exe-
							cutable.  See  REPLACING
							THE   NOTIFIER	for  de-
							tails.
________________________________________________________________________________

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  gen-
	    erated.   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_CreateFileHan-
	    dler 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_Dele-
	    teEventSource,   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 applica-
	    tion 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 retar-
     geted 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_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  appli-
	    cation  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 addi-
     tional 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 argu-
     ments 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 informa-
     tion 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_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 al-
     ready  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  struc-
     ture 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 addi-
     tional 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 defini-
     tion:

	    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  se-
			     ries 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  re-
     turn 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  sev-
     eral  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 al-
     located by the event source (using Tcl_Alloc or the Tcl macro ckalloc)  be-
     fore  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 sep-
     arate 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_Thread-
     QueueEvent.  Tcl_ThreadQueueEvent accepts as an argument a Tcl_ThreadId ar-
     gument, which uniquely identifies a thread in a Tcl application.  To obtain
     the Tcl_ThreadId for the current thread, use the Tcl_GetCurrentThread  pro-
     cedure.  (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 pro-
     cedure 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 man-
     aged 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_Cre-
     ateEventSource  for  the event source to be deleted.  If no such source ex-
     ists, 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 inter-
     preter.  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 re-
     sponsible 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 informa-
     tion (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, includ-
     ing 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 un-
     wind  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 in-
     finite.

     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_Set-
     MaxBlockTime 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  inter-
     face is needed because Tcl_WaitForEvent is not invoked when there is an ex-
     ternal  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 in-
     stance, uses this hook to create a communication window).

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

     The  Tcl_Sleep and Tcl_DoOneEvent interfaces are described in their respec-
     tive manual pages.

     The easiest way to create a new notifier is to look at the code for an  ex-
     isting  notifier,	such  as  the files unix/tclUnixNotfy.c or win/tclWinNo-
     tify.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_Noti-
     fierProcs	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  ap-
     plications  that have their own private event loops.  In this case, the ap-
     plication 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 com-
     mands 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  it-
     self.   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_SER-
     VICE_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(3),	    Tcl_DeleteFileHandler(3),	   Tcl_Sleep(3),
     Tcl_DoOneEvent(3), Thread(3)

KEYWORDS
     event, notifier, event queue, event sources, file events, timer, idle, ser-
     vice mode, threads

Tcl				       8.1			     Notifier(3)

Want to link to this manual page? Use this URL:
<https://man.freebsd.org/cgi/man.cgi?query=Tcl_GetServiceMode.tcl86&sektion=3&manpath=FreeBSD+Ports+15.1.quarterly>

home | help