tcl7.6 C API - Notifier






NAME

     Tcl_CreateEventSource, Tcl_DeleteEventSource, Tcl_WatchFile,
     Tcl_FileReady,      Tcl_SetMaxBlockTime,     Tcl_QueueEvent,
     Tcl_WaitForEvent - Event sources, the  event  notifier,  and
     the event queue


SYNOPSIS

     #include <tcl.h>

     Tcl_CreateEventSource(setupProc, checkProc, clientData)

     Tcl_DeleteEventSource(setupProc, checkProc, clientData)

     Tcl_WatchFile(file, mask)

     Tcl_SetMaxBlockTime(timePtr)

     int
     Tcl_FileReady(file, mask)

     Tcl_QueueEvent(evPtr, position)

     int
     Tcl_WaitForEvent(timePtr)


ARGUMENTS

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

     Tcl_EventCheckProc   *checkProc   (in)      Procedure    for
                                                 Tcl_DoWhenIdle
                                                 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    and
                                                 checkProc.

     Tcl_File             file         (in)      Generic     file
                                                 handle        as
                                                 returned      by
                                                 Tcl_GetFile.

     int                  mask         (in)      Indicates    the
                                                 events        of
                                                 interest      on
                                                 file:   an OR'ed
                                                 combination   of
                                                 TCL_READABLE,
                                                 TCL_WRITABLE,
                                                 and
                                                 TCL_EXCEPTION.

     Tcl_Time             *timePtr     (in)      Indicates    the
                                                 maximum   amount
                                                 of time to  wait
                                                 for   an  event.
                                                 This  is  speci-
                                                 fied    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 for-
                                                 ever  if  neces-
                                                 sary.

     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.

     int                  flags        (in)      A  copy  of  the
                                                 flags   argument
                                                 passed        to
                                                 Tcl_DoOneEvent.





INTRODUCTION

     The procedures described here 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.  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.

     [2]  The event queue:  there is a single queue for the whole
          application,  containing events that have been detected
          but not yet serviced.  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.

     [3]  The procedure Tcl_DoOneEvent:  this is  procedure  that
          is  invoked  by  the application to service events.  It
          works with the event sources and  the  event  queue  to
          detect and handle events, and calls Tcl_WaitForEvent to
          actually wait for an event to occur.

     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 possi-
          ble event, remove it from the queue, and return.

     [2]  Prepare  to  block  for  an   event.    To   do   this,
          Tcl_DoOneEvent  invokes a setup procedure in each event
          source.  The event source  will  call  procedures  like
          Tcl_WatchFile  and Tcl_SetMaxBlockTime to indicate what
          low-level events to look for in Tcl_WaitForEvent.

     [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 (e.g. by  calling  Tcl_FileReady).
          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 possi-
          ble 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.

     The procedures in this file allow  you  to  do  two  things.
     First,  they  allow you to create new event sources, such as
     one for UNIX signals or one to notify when subprocesses have
     exited.   Second,  the procedures can be used to build a new
     version of Tcl_DoOneEvent.  This might be necessary to  sup-
     port  a  new operating system with different low-level event
     reporting mechanisms, or it  might  be  necessary  to  merge
     Tcl's event loop with that of some other toolkit like Xt.



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 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  by  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 isn't 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    provide    information    to
     Tcl_WaitForEvent  about  how to wait for events.  It usually
     does this by calling Tcl_WatchFile  or  Tcl_SetMaxBlockTime.
     For  example,  setupProc  can call Tcl_WatchFile to indicate
     that Tcl_WaitForEvent  should  return  when  the  conditions
     given by the mask argument become true for the file given by
     file.  The UNIX version of Tcl_WaitForEvent uses the  infor-
     mation  passed  to  Tcl_WatchFile  to set the file masks for
     select, which it uses to wait for events.  If  Tcl_WatchFile
     isn't called by any event sources then Tcl_WaitForEvent will
     ignore files while waiting.

     SetupProc can also  invoke  Tcl_SetMaxBlockTime  to  set  an
     upper  bound on how long Tcl_WaitForEvent will block.  If no
     event source calls Tcl_SetMaxBlockTime then Tcl_WaitForEvent
     will  wait as long as necessary for an event to occur;  oth-
     erwise, it will only wait as long as the  shortest  interval
     passed  to  Tcl_SetMaxBlockTime by one of the event sources.
     For example, the timer event source uses this  procedure  to
     limit  the  wait  time to the interval before the next timer
     event is ready.  If an event source knows  that  it  already
     has  events  ready  to report, it can request a zero maximum
     block time.  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_WatchFile      and
     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.

     In addition to  the  generic  procedures  Tcl_WatchFile  and
     Tcl_SetMaxBlockTime,  other platform-specific procedures may
     also be available for  setupProc,  if  there  is  additional
     information needed by Tcl_WaitForEvent on that platform.

     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, but the procedure Tcl_FileReady may be useful for some
     event sources.  It takes as arguments a file identifier file
     and a mask of interesting conditions;   it  returns  another
     mask  indicating  which of those conditions were found to be
     present  on  the  file  during  the  most  recent  call   to
     Tcl_WaitForEvent.   Tcl_WaitForEvent  only  checks a file if
     Tcl_WatchFile was called by at least one event source, so it
     is  possible  for Tcl_FileReady to return 0 even if the file
     is ready.

     If  an  event  source's  check  procedure  detects  that  an
     interesting  event  has occurred, then 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 dynam-
     ically allocated structure containing the event  (see  below
     for  more  information  on  memory management issues).  Each
     event source can define its own event structure  with  what-
     ever information is relevant to that event source.  However,
     the first element of the structure must be  a  structure  of
     type  Tcl_Event,  and  the address of this structure is used
     when communicating between the event source and the rest  of
     the notifier.  A Tcl_Event has the following definition:
          typedef struct Tcl_Event {
              Tcl_EventProc *proc;
              struct Tcl_Event *nextPtr;
          };
     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  posi-
     tions, depending on the position argument to Tcl_QueueEvent:

     TCL_QUEUE_TAIL          Add the event at  the  back  of  the
                             queue,  so  that  all  other pending
                             events will be serviced first.  This
                             is almost always the right place for
                             new events.

     TCL_QUEUE_HEAD          Add the event at the  front  of  the
                             queue,  so  that it will be serviced
                             before all other queued events.

     TCL_QUEUE_MARK          Add the event at the  front  of  the
                             queue, unless there are other events
                             at  the  front  whose  position   is
                             TCL_QUEUE_MARK;   if so, add the new
                             event   just   after    all    other
                             TCL_QUEUE_MARK  events.   This value
                             of position is  used  to  insert  an
                             ordered  sequence  of  events at the
                             front of the queue, such as a series
                             of   Enter  and  Leave  events  syn-
                             thesized during  a  grab  or  ungrab
                             operation in Tk.

     When it is time to handle an event from the queue  (steps  1
     and  5  above) Tcl_DoOneEvent 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_DoOneEvent;  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 can-
     not  be  handled  at  this time, it may return 0 to indicate
     that the event should be deferred for processing later;   in
     this case Tcl_DoOneEvent 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  argu-
     ment.  For example, the file event source will always return
     0 if the TCL_FILE_EVENTS bit isn't 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_DoOneEvent 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_DoOneEvent,  not
     by the event source.



CREATING A NEW NOTIFIER

     The notifier consists of all  the  procedures  described  in
     this  manual entry, plus Tcl_DoOneEvent and Tcl_Sleep.  Most
     of these procedures are generic, in that they are  the  same
     for  all  platforms.   However,  four  of the procedures are
     platform-dependent:       Tcl_WatchFile,      Tcl_FileReady,
     Tcl_WaitForEvent, and Tcl_Sleep.  To support a new platform,
     you  must  write   new   versions   of   these   procedures.
     Tcl_WatchFile  and Tcl_FileReady have already been described
     previously in this document, and Tcl_Sleep is  described  in
     its own manual entry.

     Tcl_WaitForEvent is the lowest-level procedure in the notif-
     ier;   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  setup  pro-
     cedures  will  have  provided information about what to wait
     for by invoking procedures like Tcl_WatchFile.  The  timePtr
     argument to Tcl_WaitForEvent gives the maximum time to block
     for an event, based on calls to Tcl_SetMaxBlockTime made  by
     setup  procedures  and  on  other  information  (such as the
     TCL_DONT_WAIT bit in flags).  Tcl_WaitForEvent uses informa-
     tion  saved  by  Tcl_WatchFile, plus the timePtr argument to
     decide what to wait for and how long to block.   It  returns
     TCL_OK  as  soon as one of the specified events has occurred
     or the given amount of time has elapsed.  However, if  there
     are   no   event   handlers   (neither   Tcl_WatchFile   nor
     Tcl_SetMaxBlockTime has been called since the last  call  to
     Tcl_WaitForEvent),  so  that  the procedure would block for-
     ever,  then  it  returns  immediately  with  a   result   of
     TCL_ERROR.

     The easiest way to create a new notifier is to look  at  the
     code   for   an   existing   notifier,  such  as  the  files
     generic/tclNotify.c and unix/tclUnixNotfy.c.




KEYWORDS

     block time, event notifier, event queue, event sources, file
     events