Notifier.3
上传用户:rrhhcc
上传日期:2015-12-11
资源大小:54129k
文件大小:27k
- '"
- '" Copyright (c) 1998-1999 Scriptics Corporation
- '" Copyright (c) 1995-1997 Sun Microsystems, Inc.
- '"
- '" See the file "license.terms" for information on usage and redistribution
- '" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
- '"
- '" RCS: @(#) $Id: Notifier.3,v 1.9.2.1 2004/11/25 15:28:37 vasiljevic Exp $
- '"
- .so man.macros
- .TH Notifier 3 8.1 Tcl "Tcl Library Procedures"
- .BS
- .SH NAME
- Tcl_CreateEventSource, Tcl_DeleteEventSource, Tcl_SetMaxBlockTime, Tcl_QueueEvent, Tcl_ThreadQueueEvent, Tcl_ThreadAlert, Tcl_GetCurrentThread, Tcl_DeleteEvents, Tcl_InitNotifier, Tcl_FinalizeNotifier, Tcl_WaitForEvent, Tcl_AlertNotifier, Tcl_SetTimer, Tcl_ServiceAll, Tcl_ServiceEvent, Tcl_GetServiceMode, Tcl_SetServiceMode - the event queue and notifier interfaces
- .SH SYNOPSIS
- .nf
- fB#include <tcl.h>fR
- .sp
- void
- fBTcl_CreateEventSourcefR(fIsetupProc, checkProc, clientDatafR)
- .sp
- void
- fBTcl_DeleteEventSourcefR(fIsetupProc, checkProc, clientDatafR)
- .sp
- void
- fBTcl_SetMaxBlockTimefR(fItimePtrfR)
- .sp
- void
- fBTcl_QueueEventfR(fIevPtr, positionfR)
- .VS 8.1
- .sp
- void
- fBTcl_ThreadQueueEventfR(fIthreadId, evPtr, positionfR)
- .sp
- void
- fBTcl_ThreadAlertfR(fIthreadIdfR)
- .sp
- Tcl_ThreadId
- fBTcl_GetCurrentThreadfR()
- .sp
- void
- fBTcl_DeleteEventsfR(fIdeleteProc, clientDatafR)
- .sp
- ClientData
- fBTcl_InitNotifierfR()
- .sp
- void
- fBTcl_FinalizeNotifierfR(fIclientDatafR)
- .sp
- int
- fBTcl_WaitForEventfR(fItimePtrfR)
- .sp
- void
- fBTcl_AlertNotifierfR(fIclientDatafR)
- .sp
- void
- fBTcl_SetTimerfR(fItimePtrfR)
- .sp
- int
- fBTcl_ServiceAllfR()
- .sp
- int
- fBTcl_ServiceEventfR(fIflagsfR)
- .sp
- int
- fBTcl_GetServiceModefR()
- .sp
- int
- fBTcl_SetServiceModefR(fImodefR)
- .VE
- .SH ARGUMENTS
- .AS Tcl_EventDeleteProc milliseconds
- .AP Tcl_EventSetupProc *setupProc in
- Procedure to invoke to prepare for event wait in fBTcl_DoOneEventfR.
- .AP Tcl_EventCheckProc *checkProc in
- Procedure for fBTcl_DoOneEventfR to invoke after waiting for
- events. Checks to see if any events have occurred and, if so,
- queues them.
- .AP ClientData clientData in
- Arbitrary one-word value to pass to fIsetupProcfR, fIcheckProcfR, or
- fIdeleteProcfR.
- .AP 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 fBTcl_WaitForEventfR
- is NULL, it means there is no maximum wait time: wait forever if
- necessary.
- .AP 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 fBTcl_AllocfR or fBckallocfR.
- .AP Tcl_QueuePosition position in
- Where to add the new event in the queue: fBTCL_QUEUE_TAILfR,
- fBTCL_QUEUE_HEADfR, or fBTCL_QUEUE_MARKfR.
- .AP Tcl_ThreadId threadId in
- A unique identifier for a thread.
- .AP Tcl_EventDeleteProc *deleteProc in
- Procedure to invoke for each queued event in fBTcl_DeleteEventsfR.
- .AP int flags in
- What types of events to service. These flags are the same as those
- passed to fBTcl_DoOneEventfR.
- .VS 8.1
- .AP int mode in
- Indicates whether events should be serviced by fBTcl_ServiceAllfR.
- Must be one of fBTCL_SERVICE_NONEfR or fBTCL_SERVICE_ALLfR.
- .VE
- .BE
- .SH INTRODUCTION
- .PP
- 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.
- .PP
- 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:
- .IP [1]
- Event sources: these represent the ways in which events can be
- generated. For example, there is a timer event source that implements
- the fBTcl_CreateTimerHandlerfR procedure and the fBafterfR
- command, and there is a file event source that implements the
- fBTcl_CreateFileHandlerfR 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
- fBTcl_CreateEventSourcefR, fBTcl_DeleteEventSourcefR,
- and fBTcl_SetMaxBlockTimefR, fBTcl_QueueEventfR, and
- fBTcl_DeleteEventsfR are used primarily by event sources.
- .IP [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.
- .VS 8.1
- Threaded applications work in a
- similar manner, except that there is a separate event queue for
- each thread containing a Tcl interpreter.
- fBTcl_QueueEventfR is used (primarily
- by event sources) to add events to the event queue and
- fBTcl_DeleteEventsfR is used to remove events from the queue without
- processing them. In a threaded application, fBTcl_QueueEventfR adds
- an event to the current thread's queue, and fBTcl_ThreadQueueEventfR
- adds an event to a queue in a specific thread.
- .IP [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 fBTcl_DoOneEventfR, which is described in a
- separate manual entry.
- .PP
- 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 fBTcl_WaitForEventfR and
- fBTcl_SetTimerfR are normally implemented by Tcl, but may be
- replaced with new versions to retarget the notifier (the
- fBTcl_InitNotifierfR, fBTcl_AlertNotifierfR,
- fBTcl_FinalizeNotifierfR, fBTcl_SleepfR,
- fBTcl_CreateFileHandlerfR, and fBTcl_DeleteFileHandlerfR must
- also be replaced; see CREATING A NEW NOTIFIER below for details).
- The procedures fBTcl_ServiceAllfR, fBTcl_ServiceEventfR,
- fBTcl_GetServiceModefR, and fBTcl_SetServiceModefR are provided
- to help connect Tcl's event loop to an external event loop such as
- Motif's.
- .SH "NOTIFIER BASICS"
- .VE
- .PP
- The easiest way to understand how the notifier works is to consider
- what happens when fBTcl_DoOneEventfR is called.
- fBTcl_DoOneEventfR is passed a fIflagsfR argument that indicates
- what sort of events it is OK to process and also whether or not to
- block if no events are ready. fBTcl_DoOneEventfR does the following
- things:
- .IP [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
- .VS 8.1
- from the queue, and return. It does this by calling
- fBTcl_ServiceEventfR and passing in the fIflagsfR argument.
- .VE
- .IP [2]
- Prepare to block for an event. To do this, fBTcl_DoOneEventfR
- invokes a fIsetup procedurefR in each event source.
- The event source will perform event-source specific initialization and
- .VS 8.1
- possibly call fBTcl_SetMaxBlockTimefR to limit how long
- .VE
- fBTcl_WaitForEventfR will block if no new events occur.
- .IP [3]
- Call fBTcl_WaitForEventfR. 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 fItimePtrfR specifies
- an interval other than 0.
- fBTcl_WaitForEventfR returns when something has happened,
- such as a file becoming readable or the interval given by fItimePtrfR
- expiring. If there are no events for fBTcl_WaitForEventfR to
- wait for, so that it would block forever, then it returns immediately
- and fBTcl_DoOneEventfR returns 0.
- .IP [4]
- Call a fIcheck procedurefR 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.
- .IP [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.
- .IP [6]
- See if there are idle callbacks pending. If so, invoke all of them and
- return.
- .IP [7]
- Either return 0 to indicate that no events were ready, or go back to
- step [2] if blocking was requested by the caller.
- .SH "CREATING A NEW EVENT SOURCE"
- .PP
- 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.
- .PP
- The procedure fBTcl_CreateEventSourcefR creates a new event source.
- Its arguments specify the setup procedure and check procedure for
- the event source.
- fISetupProcfR should match the following prototype:
- .CS
- typedef void Tcl_EventSetupProc(
- ClientData fIclientDatafR,
- int fIflagsfR);
- .CE
- The fIclientDatafR argument will be the same as the fIclientDatafR
- argument to fBTcl_CreateEventSourcefR; it is typically used to
- point to private information managed by the event source.
- The fIflagsfR argument will be the same as the fIflagsfR
- argument passed to fBTcl_DoOneEventfR except that it will never
- be 0 (fBTcl_DoOneEventfR replaces 0 with fBTCL_ALL_EVENTSfR).
- fIFlagsfR indicates what kinds of events should be considered;
- if the bit corresponding to this event source isn't set, the event
- source should return immediately without doing anything. For
- example, the file event source checks for the fBTCL_FILE_EVENTSfR
- bit.
- .PP
- fISetupProcfR'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 fBTcl_CreateFileHandlerfR; 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 fBTcl_SetMaxBlockTimefR to force the application to wake
- up after a specified time even if no events have occurred.
- .VS 8.1
- If no event source calls fBTcl_SetMaxBlockTimefR
- then fBTcl_WaitForEventfR will wait as long as necessary for an
- event to occur; otherwise, it will only wait as long as the shortest
- interval passed to fBTcl_SetMaxBlockTimefR 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
- fBTcl_SetMaxBlockTimefR with a 0 block time so that
- fBTcl_WaitForEventfR does not block if there is no new data on the X
- connection.
- .VE
- The fItimePtrfR argument to fBTcl_WaitForEventfR points to
- a structure that describes a time interval in seconds and
- microseconds:
- .CS
- typedef struct Tcl_Time {
- long fIsecfR;
- long fIusecfR;
- } Tcl_Time;
- .CE
- The fIusecfR field should be less than 1000000.
- .PP
- .VS 8.1
- Information provided to fBTcl_SetMaxBlockTimefR
- is only used for the next call to fBTcl_WaitForEventfR; it is
- discarded after fBTcl_WaitForEventfR returns.
- .VE
- 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.
- .PP
- .VS 8.1
- If the application uses an external event loop rather than
- fBTcl_DoOneEventfR, the event sources may need to call
- fBTcl_SetMaxBlockTimefR at other times. For example, if a new event
- handler is registered that needs to poll for events, the event source
- may call fBTcl_SetMaxBlockTimefR to set the block time to zero to
- force the external event loop to call Tcl. In this case,
- fBTcl_SetMaxBlockTimefR invokes fBTcl_SetTimerfR with the shortest
- interval seen since the last call to fBTcl_DoOneEventfR or
- fBTcl_ServiceAllfR.
- .PP
- In addition to the generic procedure fBTcl_SetMaxBlockTimefR, other
- platform-specific procedures may also be available for
- fIsetupProcfR, if there is additional information needed by
- fBTcl_WaitForEventfR on that platform. For example, on Unix systems
- the fBTcl_CreateFileHandlerfR interface can be used to wait for file events.
- .VE
- .PP
- The second procedure provided by each event source is its check
- procedure, indicated by the fIcheckProcfR argument to
- fBTcl_CreateEventSourcefR. fICheckProcfR must match the
- following prototype:
- .CS
- typedef void Tcl_EventCheckProc(
- ClientData fIclientDatafR,
- int fIflagsfR);
- .CE
- The arguments to this procedure are the same as those for fIsetupProcfR.
- fBCheckProcfR is invoked by fBTcl_DoOneEventfR after it has waited
- for events. Presumably at least one event source is now prepared to
- queue an event. fBTcl_DoOneEventfR 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.
- .PP
- 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 fBTcl_QueueEventfR. The fIevPtrfR 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 fBTcl_EventfR, and the address of this
- structure is used when communicating between the event source and the
- rest of the notifier. A fBTcl_EventfR has the following definition:
- .CS
- typedef struct {
- Tcl_EventProc *fIprocfR;
- struct Tcl_Event *fInextPtrfR;
- } Tcl_Event;
- .CE
- The event source must fill in the fIprocfR field of
- the event before calling fBTcl_QueueEventfR.
- The fInextPtrfR is used to link together the events in the queue
- and should not be modified by the event source.
- .PP
- An event may be added to the queue at any of three positions, depending
- on the fIpositionfR argument to fBTcl_QueueEventfR:
- .IP fBTCL_QUEUE_TAILfR 24
- 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.
- .IP fBTCL_QUEUE_HEADfR 24
- Add the event at the front of the queue, so that it will be serviced
- before all other queued events.
- .IP fBTCL_QUEUE_MARKfR 24
- Add the event at the front of the queue, unless there are other
- events at the front whose position is fBTCL_QUEUE_MARKfR; if so,
- add the new event just after all other fBTCL_QUEUE_MARKfR events.
- This value of fIpositionfR is used to insert an ordered sequence of
- events at the front of the queue, such as a series of
- Enter and Leave events synthesized during a grab or ungrab operation
- in Tk.
- .PP
- .VS 8.1
- When it is time to handle an event from the queue (steps 1 and 4
- above) fBTcl_ServiceEventfR will invoke the fIprocfR specified
- .VE
- in the first queued fBTcl_EventfR structure.
- fIProcfR must match the following prototype:
- .CS
- typedef int Tcl_EventProc(
- Tcl_Event *fIevPtrfR,
- int fIflagsfR);
- .CE
- The first argument to fIprocfR is a pointer to the event, which will
- be the same as the first argument to the fBTcl_QueueEventfR call that
- added the event to the queue.
- The second argument to fIprocfR is the fIflagsfR argument for the
- .VS 8.1
- current call to fBTcl_ServiceEventfR; this is used by the event source
- .VE
- to return immediately if its events are not relevant.
- .PP
- It is up to fIprocfR 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
- .VS 8.1
- should be deferred for processing later; in this case fBTcl_ServiceEventfR
- .VE
- 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
- fIflagsfR argument.
- For example, the file event source will always return 0 if the
- fBTCL_FILE_EVENTSfR bit isn't set in fIflagsfR.
- Another example of deferring events happens in Tk if
- fBTk_RestrictEventsfR has been invoked to defer certain kinds
- of window events.
- .PP
- .VS 8.1
- When fIprocfR returns 1, fBTcl_ServiceEventfR 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 fBTcl_AllocfR or the Tcl macro fBckallocfR)
- before calling fBTcl_QueueEventfR, but it
- will be freed by fBTcl_ServiceEventfR, not by the event source.
- .PP
- Threaded applications work in a
- similar manner, except that there is a separate event queue for
- each thread containing a Tcl interpreter.
- Calling fBTcl_QueueEventfR in a multithreaded application adds
- an event to the current thread's queue.
- To add an event to another thread's queue, use fBTcl_ThreadQueueEventfR.
- fBTcl_ThreadQueueEventfR 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 fBTcl_GetCurrentThreadfR
- 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 fBTcl_ThreadAlertfR to "wake up" that thread's notifier to
- alert it to the new event.
- .PP
- fBTcl_DeleteEventsfR can be used to explicitly remove one or more
- events from the event queue. fBTcl_DeleteEventsfR calls fIprocfR
- 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. fIProcfR should match the following prototype:
- .CS
- typedef int Tcl_EventDeleteProc(
- Tcl_Event *fIevPtrfR,
- ClientData fIclientDatafR);
- .CE
- The fIclientDatafR argument will be the same as the fIclientDatafR
- argument to fBTcl_DeleteEventsfR; it is typically used to point to
- private information managed by the event source. The fIevPtrfR will
- point to the next event in the queue.
- .PP
- fBTcl_DeleteEventSourcefR deletes an event source. The fIsetupProcfR,
- fIcheckProcfR, and fIclientDatafR arguments must exactly match those
- provided to the fBTcl_CreateEventSourcefR for the event source to be deleted.
- If no such source exists, fBTcl_DeleteEventSourcefR has no effect.
- .VE
- .SH "CREATING A NEW NOTIFIER"
- .PP
- The notifier consists of all the procedures described in this manual
- entry, plus fBTcl_DoOneEventfR and fBTcl_SleepfR, which are
- .VS 8.1
- available on all platforms, and fBTcl_CreateFileHandlerfR and
- fBTcl_DeleteFileHandlerfR, which are Unix-specific. Most of these
- procedures are generic, in that they are the same for all notifiers.
- However, eight of the procedures are notifier-dependent:
- fBTcl_InitNotifierfR, fBTcl_AlertNotifierfR, fBTcl_FinalizeNotifierfR,
- fBTcl_SetTimerfR, fBTcl_SleepfR, fBTcl_WaitForEventfR,
- fBTcl_CreateFileHandlerfR and fBTcl_DeleteFileHandlerfR. To
- support a new platform or to integrate Tcl with an
- application-specific event loop, you must write new versions of these
- procedures.
- .PP
- fBTcl_InitNotifierfR initializes the notifier state and returns
- a handle to the notifier state. Tcl calls this
- procedure when initializing a Tcl interpreter. Similarly,
- fBTcl_FinalizeNotifierfR shuts down the notifier, and is
- called by fBTcl_FinalizefR when shutting down a Tcl interpreter.
- .PP
- fBTcl_WaitForEventfR 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 fBTcl_WaitForEventfR is invoked,
- each of the event sources' setup procedure will have been invoked.
- The fItimePtrfR argument to
- fBTcl_WaitForEventfR gives the maximum time to block for an event,
- based on calls to fBTcl_SetMaxBlockTimefR made by setup procedures
- and on other information (such as the fBTCL_DONT_WAITfR bit in
- fIflagsfR).
- .PP
- Ideally, fBTcl_WaitForEventfR 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 fIcheckProcfR procedures.
- However, on some platforms (such as Windows) this isn't possible;
- events may be processed in fBTcl_WaitForEventfR, including queuing
- Tcl_Events and more (for example, callbacks for native widgets may be
- invoked). The return value from fBTcl_WaitForEventfR must be either
- 0, 1, or -1. On platforms such as Windows where events get processed in
- fBTcl_WaitForEventfR, a return value of 1 means that there may be more
- events still pending that haven't been processed. This is a sign to the
- caller that it must call fBTcl_WaitForEventfR again if it wants all
- pending events to be processed. A 0 return value means that calling
- fBTcl_WaitForEventfR again will not have any effect: either this is a
- platform where fBTcl_WaitForEventfR only waits without doing any event
- processing, or fBTcl_WaitForEventfR knows for sure that there are no
- additional events to process (e.g. it returned because the time
- elapsed). Finally, a return value of -1 means that the event loop is
- no longer operational and the application should probably unwind and
- terminate. Under Windows this happens when a WM_QUIT message is received;
- under Unix it happens when fBTcl_WaitForEventfR would have waited
- forever because there were no active event sources and the timeout was
- infinite.
- .PP
- fBTcl_AlertNotifierfR is used in multithreaded applications to allow
- any thread to "wake up" the notifier to alert it to new events on its
- queue. fBTcl_AlertNotifierfR requires as an argument the notifier
- handle returned by fBTcl_InitNotifierfR.
- .PP
- If the notifier will be used with an external event loop, then it must
- also support the fBTcl_SetTimerfR interface. fBTcl_SetTimerfR is
- invoked by fBTcl_SetMaxBlockTimefR whenever the maximum blocking
- time has been reduced. fBTcl_SetTimerfR should arrange for the
- external event loop to invoke fBTcl_ServiceAllfR after the specified
- interval even if no events have occurred. This interface is needed
- because fBTcl_WaitForEventfR isn't invoked when there is an external
- event loop. If the
- notifier will only be used from fBTcl_DoOneEventfR, then
- fBTcl_SetTimerfR need not do anything.
- .PP
- On Unix systems, the file event source also needs support from the
- notifier. The file event source consists of the
- fBTcl_CreateFileHandlerfR and fBTcl_DeleteFileHandlerfR
- procedures, which are described in the fBTcl_CreateFileHandlerfR
- manual page.
- .PP
- The fBTcl_SleepfR and fBTcl_DoOneEventfR interfaces are described
- in their respective manual pages.
- .PP
- The easiest way to create a new notifier is to look at the code
- for an existing notifier, such as the files fBunix/tclUnixNotfy.cfR
- or fBwin/tclWinNotify.cfR in the Tcl source distribution.
- .SH "EXTERNAL EVENT LOOPS"
- .PP
- 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 fBTcl_DoOneEventfR except in the case
- of recursive event loops such as calls to the Tcl commands fBupdatefR
- or fBvwaitfR. 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.
- .PP
- Because the external event loop is not calling fBTcl_DoOneEventfR on
- a regular basis, it is up to the notifier to arrange for
- fBTcl_ServiceEventfR to be called whenever events are pending on the
- Tcl event queue. The easiest way to do this is to invoke
- fBTcl_ServiceAllfR 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
- fBTcl_SetMaxBlockTimefR to force the external event loop to call
- Tcl even if no events are available on the system event queue.
- .PP
- As a side effect of processing events detected in the main external
- event loop, Tcl may invoke fBTcl_DoOneEventfR to start a recursive event
- loop in commands like fBvwaitfR. fBTcl_DoOneEventfR will invoke
- the external event loop, which will result in callbacks as described
- in the preceding paragraph, which will result in calls to
- fBTcl_ServiceAllfR. However, in these cases it is undesirable to
- service events in fBTcl_ServiceAllfR. Servicing events there is
- unnecessary because control will immediately return to the
- external event loop and hence to fBTcl_DoOneEventfR, which can
- service the events itself. Furthermore, fBTcl_DoOneEventfR is
- supposed to service only a single event, whereas fBTcl_ServiceAllfR
- normally services all pending events. To handle this situation,
- fBTcl_DoOneEventfR sets a flag for fBTcl_ServiceAllfR
- that causes it to return without servicing any events.
- This flag is called the fIservice modefR;
- fBTcl_DoOneEventfR restores it to its previous value before it returns.
- .PP
- In some cases, however, it may be necessary for fBTcl_ServiceAllfR
- to service events
- even when it has been invoked from fBTcl_DoOneEventfR. This happens
- when there is yet another recursive event loop invoked via an
- event handler called by fBTcl_DoOneEventfR (such as one that is
- part of a native widget). In this case, fBTcl_DoOneEventfR may not
- have a chance to service events so fBTcl_ServiceAllfR must service
- them all. Any recursive event loop that calls an external event
- loop rather than fBTcl_DoOneEventfR must reset the service mode so
- that all events get processed in fBTcl_ServiceAllfR. This is done
- by invoking the fBTcl_SetServiceModefR procedure. If
- fBTcl_SetServiceModefR is passed fBTCL_SERVICE_NONEfR, then calls
- to fBTcl_ServiceAllfR will return immediately without processing any
- events. If fBTcl_SetServiceModefR is passed fBTCL_SERVICE_ALLfR,
- then calls to fBTcl_ServiceAllfR will behave normally.
- fBTcl_SetServiceModefR returns the previous value of the service
- mode, which should be restored when the recursive loop exits.
- fBTcl_GetServiceModefR returns the current value of the service
- mode.
- .VE
- .SH "SEE ALSO"
- fBTcl_CreateFileHandlerfR, fBTcl_DeleteFileHandlerfR, fBTcl_SleepfR,
- fBTcl_DoOneEventfR, fBThread(3)fR
- .SH KEYWORDS
- event, notifier, event queue, event sources, file events, timer, idle, service mode, threads