tcl7.6 C API - Async






NAME

     Tcl_AsyncCreate,       Tcl_AsyncMark,       Tcl_AsyncInvoke,
     Tcl_AsyncDelete - handle asynchronous events


SYNOPSIS

     #include <tcl.h>

     Tcl_AsyncHandler
     Tcl_AsyncCreate(proc, clientData)

     Tcl_AsyncMark(async)

     int
     Tcl_AsyncInvoke(interp, code)

     Tcl_AsyncDelete(async)

     int
     Tcl_AsyncReady()


ARGUMENTS

     Tcl_AsyncProc      *proc        (in)      Procedure       to
                                               invoke  to  handle
                                               an    asynchronous
                                               event.

     ClientData         clientData   (in)      One-word value  to
                                               pass to proc.

     Tcl_AsyncHandler   async        (in)      Token  for   asyn-
                                               chronous     event
                                               handler.

     Tcl_Interp         *interp      (in)      Tcl interpreter in
                                               which  command was
                                               being    evaluated
                                               when  handler  was
                                               invoked,  or  NULL
                                               if   handler   was
                                               invoked when there
                                               was no interpreter
                                               active.

     int                code         (in)      Completion    code
                                               from  command that
                                               just completed  in
                                               interp,  or  0  if
                                               interp is NULL.




DESCRIPTION

     These procedures provide a safe mechanism for  dealing  with
     asynchronous  events such as signals.  If an event such as a
     signal occurs while a Tcl script is being evaluated then  it
     isn't  safe  to  take  any substantive action to process the
     event.  For example, it isn't safe to evaluate a Tcl  script
     since  the  interpreter  may  already  be  in  the middle of
     evaluating a script; it may not even  be  safe  to  allocate
     memory,  since  a  memory allocation could have been in pro-
     gress when the event occurred.  The only safe approach is to
     set  a  flag indicating that the event occurred, then handle
     the event later when the  world  has  returned  to  a  clean
     state, such as after the current Tcl command completes.

     Tcl_AsyncCreate creates an asynchronous handler and  returns
     a  token  for  it.  The asynchronous handler must be created
     before any occurrences of the asynchronous event that it  is
     intended  to  handle  (it is not safe to create a handler at
     the time of an event).  When an  asynchronous  event  occurs
     the  code  that detects the event (such as a signal handler)
     should call Tcl_AsyncMark with the token  for  the  handler.
     Tcl_AsyncMark will mark the handler as ready to execute, but
     it will not invoke the handler immediately.  Tcl  will  call
     the  proc  associated with the handler later, when the world
     is in a safe state, and proc can then carry out the  actions
     associated  with  the  asynchronous event.  Proc should have
     arguments and result that match the type Tcl_AsyncProc:
          typedef int Tcl_AsyncProc(
            ClientData clientData,
            Tcl_Interp *interp,
            int code);
     The clientData will be the same as the  clientData  argument
     passed  to Tcl_AsyncCreate when the handler was created.  If
     proc is invoked just after a command has completed execution
     in an interpreter, then interp will identify the interpreter
     in which the command was evaluated and code will be the com-
     pletion code returned by that command.  The command's result
     will be present in interp->result.  When proc returns, what-
     ever  it  leaves  in  interp->result will be returned as the
     result of the command and the integer value returned by proc
     will be used as the new completion code for the command.

     It is also possible for proc to be invoked  when  no  inter-
     preter is active.  This can happen, for example, if an asyn-
     chronous event occurs while the application is  waiting  for
     interactive  input  or an X event.  In this case interp will
     be NULL and code will be 0, and the return value  from  proc
     will be ignored.

     The procedure Tcl_AsyncInvoke is called to invoke all of the
     handlers  that are ready.  The procedure Tcl_AsyncReady will
     return  non-zero  whenever  any  asynchronous  handlers  are
     ready;   it can be checked to avoid calls to Tcl_AsyncInvoke
     when there are no ready handlers.  Tcl calls  Tcl_AsyncReady
     after each command is evaluated and calls Tcl_AsyncInvoke if
     needed.   Applications  may  also  call  Tcl_AsyncInvoke  at
     interesting  times for that application.  For example, Tcl's
     event handler calls  Tcl_AsyncReady  after  each  event  and
     calls  Tcl_AsyncInvoke if needed.  The interp and code argu-
     ments to Tcl_AsyncInvoke have the same meaning as for  proc:
     they  identify  the active interpreter, if any, and the com-
     pletion code from the command that just completed.

     Tcl_AsyncDelete removes an asynchronous handler so that  its
     proc  will never be invoked again.  A handler can be deleted
     even when ready, and it will still not be invoked.

     If multiple handlers become active at  the  same  time,  the
     handlers  are invoked in the order they were created (oldest
     handler first).   The  code  and  interp->result  for  later
     handlers reflect the values returned by earlier handlers, so
     that the most recently created handler has  last  say  about
     the  interpreter's  result  and  completion  code.   If  new
     handlers  become  ready  while   handlers   are   executing,
     Tcl_AsyncInvoke  will  invoke  them  all;   at each point it
     invokes the highest-priority (oldest) ready handler, repeat-
     ing  this  over and over until there are no longer any ready
     handlers.



WARNING

     It is almost always a bad idea  for  an  asynchronous  event
     handler  to modify interp->result or return a code different
     from its code argument.  This sort of behavior  can  disrupt
     the  execution  of scripts in subtle ways and result in bugs
     that are extremely difficult to track down.  If an asynchro-
     nous  event  handler  needs  to evaluate Tcl scripts then it
     should first save interp->result  plus  the  values  of  the
     variables  errorInfo  and  errorCode  (this can be done, for
     example, by storing them  in  dynamic  strings).   When  the
     asynchronous  handler  is finished it should restore interp-
     >result, errorInfo, and errorCode, and return the code argu-
     ment.



KEYWORDS

     asynchronous event, handler, signal