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_WaitForEvent,  Tcl_AlertNotifier,   Tcl_SetTimer,   Tcl_ServiceAll,
       Tcl_ServiceEvent,  Tcl_GetServiceMode, Tcl_SetServiceMode, Tcl_Service-
       ModeHook, 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 se-
							  tupProc,  checkProc,
							  or deleteProc.

       const Tcl_Time *timePtr (in)			  Indicates the	 maxi-
							  mum  amount  of time
							  to   wait   for   an
							  event.     This   is
							  specified as an  in-
							  terval  (how long to
							  wait),  not  an  ab-
							  solute 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_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_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_SER-
							  VICE_NONE	    or
							  TCL_SERVICE_ALL.

       Tcl_NotifierProcs* notifierProcPtr (in)		  Structure  of	 func-
							  tion	 pointers  de-
							  scribing    notifier
							  procedures  that are
							  to replace the  ones
							  installed in the ex-
							  ecutable.   See  RE-
							  PLACING 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  pro-
       vided  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  im-
	      plements the Tcl_CreateTimerHandler procedure and	the after com-
	      mand,  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_Set-
	      MaxBlockTime, Tcl_QueueEvent, and	Tcl_DeleteEvents are used pri-
	      marily by	event sources.

       [2]    The event	queue: for non-threaded	applications, there is a  sin-
	      gle queue	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	appro-
	      priate 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  ser-
	      vicing  at a future time.	 Threaded applications work in a simi-
	      lar 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  ap-
	      plication	 enters	 a loop	that waits for events to occur,	places
	      them on the event	queue, and then	processes them.	 Most applica-
	      tions 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 applica-
       tion).  The procedures Tcl_WaitForEvent and Tcl_SetTimer	 are  normally
       implemented  by	Tcl, but may be	replaced with new versions to retarget
       the notifier (the Tcl_InitNotifier, Tcl_AlertNotifier,  Tcl_FinalizeNo-
       tifier,	Tcl_Sleep,  Tcl_CreateFileHandler,  and	 Tcl_DeleteFileHandler
       must also be replaced; see CREATING A NEW NOTIFIER below	for  details).
       The  procedures	Tcl_ServiceAll,	 Tcl_ServiceEvent, Tcl_GetServiceMode,
       and Tcl_SetServiceMode are provided to help connect Tcl's event loop to
       an external event loop such as Motif's.

NOTIFIER BASICS
       The easiest way to understand how the notifier  works  is  to  consider
       what happens when Tcl_DoOneEvent	is called.  Tcl_DoOneEvent is passed a
       flags  argument	that indicates what sort 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_Ser-
	      viceEvent	and passing in the flags argument.

       [2]    Prepare  to  block for an	event.	To do this, Tcl_DoOneEvent in-
	      vokes 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  differ-
	      ently  on	 different platforms;  it waits	for an event to	occur,
	      based on the information provided	by the event sources.  It  may
	      cause  the application to	block if timePtr specifies an interval
	      other than 0.  Tcl_WaitForEvent returns when something has  hap-
	      pened, 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 im-
	      mediately	and Tcl_DoOneEvent returns 0.

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

       [5]    Check the	event queue 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	infor-
       mation  managed	by  the	 event source.	The flags argument will	be the
       same as the flags argument passed to Tcl_DoOneEvent except that it will
       never be	0 (Tcl_DoOneEvent replaces 0 with TCL_ALL_EVENTS).  Flags  in-
       dicates	what  kinds  of	events should be considered; if	the bit	corre-
       sponding	to this	event source is	not set, the event source  should  re-
       turn  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 plat-
       form-dependent fashion.	For example, under Unix	an event source	 might
       call Tcl_CreateFileHandler; under Windows it might request notification
       with  a	Windows	 event.	  For timer-driven event sources such as timer
       events or any polled event, the event source can	call  Tcl_SetMaxBlock-
       Time to force the application to	wake up	after a	specified time 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_Wait-
       ForEvent	 does  not  block if there is no new data on the X connection.
       The timePtr argument to Tcl_WaitForEvent	points to a structure that de-
       scribes 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 re-
       turns.  The next	time an	event wait is done each	of the event  sources'
       setup  procedures will be called	again, and they	can specify new	infor-
       mation 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 plat-
       form-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	proce-
       dure,  indicated	 by  the  checkProc argument to	Tcl_CreateEventSource.
       CheckProc must match the	following prototype:

	      typedef void Tcl_EventCheckProc(
		      ClientData clientData,
		      int flags);

       The arguments to	this procedure are the same as	those  for  setupProc.
       CheckProc  is invoked by	Tcl_DoOneEvent after it	has waited for events.
       Presumably at least one event source is now prepared to queue 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 informa-
       tion on memory management issues).  Each	event source  can  define  its
       own event structure with	whatever information is	relevant to that event
       source.	 However,  the first element of	the structure must be a	struc-
       ture of type Tcl_Event, and the address of this structure is used  when
       communicating between the event source and the rest of the notifier.  A
       Tcl_Event has the following definition:

	      typedef struct {
		  Tcl_EventProc	*proc;
		  struct Tcl_Event *nextPtr;
	      }	Tcl_Event;

       The  event source must fill in the proc field of	the event before call-
       ing 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 posi-
			       tion 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  in-
			       sert 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  un-
			       grab 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  re-
       moved 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 de-
       fer 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 exam-
       ple of deferring	events happens in Tk if	Tk_RestrictEvents has been in-
       voked 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,	check-
       Proc, and clientData arguments must exactly match those provided	to the
       Tcl_CreateEventSource for the event source to be	deleted.  If  no  such
       source exists, Tcl_DeleteEventSource has	no effect.

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_Final-
       izeNotifier, Tcl_SetTimer, Tcl_Sleep, Tcl_WaitForEvent, Tcl_CreateFile-
       Handler,	 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 ar-
       gument 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_Wait-
       ForEvent, including queuing Tcl_Events and more (for example, callbacks
       for  native  widgets  may be invoked).  The return value	from Tcl_Wait-
       ForEvent	must be	either 0, 1, or	-1.   On  platforms  such  as  Windows
       where  events  get  processed  in 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_Wait-
       ForEvent	again if it wants all pending events to	be processed. A	0  re-
       turn  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  be-
       cause  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  mes-
       sage  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  re-
       duced.	Tcl_SetTimer should arrange for	the external event loop	to in-
       voke Tcl_ServiceAll after the specified interval	even if	no events have
       occurred.  This interface is needed because Tcl_WaitForEvent is not in-
       voked 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 no-
       tifier, for instance, uses this hook to create a	communication window).

       On Unix systems,	the file event source also needs support from the  no-
       tifier.	 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 re-
       spective	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/tclWin-
       Notify.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 noti-
       fier.  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  an-
       other 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  in-
       stalled 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 re-
       cursive 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 applica-
       tion.  In this case the notifier	must arrange for  the  external	 event
       loop  to	 call  back into Tcl when something happens on the various Tcl
       event sources.  These callbacks	should	arrange	 for  appropriate  Tcl
       events to be placed on the Tcl event queue.

       Because the external event loop is not calling Tcl_DoOneEvent on	a reg-
       ular basis, it is up to the notifier to arrange for Tcl_ServiceEvent to
       be called whenever events are pending on	the Tcl	event queue.  The eas-
       iest  way  to  do  this	is to invoke Tcl_ServiceAll at the end of each
       callback	from the external event	loop.  This will ensure	 that  all  of
       the  event  sources are polled, any queued events are serviced, and any
       pending idle handlers are processed before returning control to the ap-
       plication.  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  preced-
       ing  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 ser-
       vices all pending events.  To  handle  this  situation,	Tcl_DoOneEvent
       sets a flag for Tcl_ServiceAll that causes it to	return without servic-
       ing  any	 events.  This flag is called the service mode;	Tcl_DoOneEvent
       restores	it to its previous value before	it returns.

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

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,
       service 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_GetCurrentThread.tcl86&sektion=3&manpath=FreeBSD+Ports+14.3.quarterly>

home | help