diff options
Diffstat (limited to 'generic/tclAsync.c')
-rw-r--r-- | generic/tclAsync.c | 177 |
1 files changed, 85 insertions, 92 deletions
diff --git a/generic/tclAsync.c b/generic/tclAsync.c index 49bebfb..ce29235 100644 --- a/generic/tclAsync.c +++ b/generic/tclAsync.c @@ -1,18 +1,17 @@ -/* +/* * tclAsync.c -- * - * This file provides low-level support needed to invoke signal - * handlers in a safe way. The code here doesn't actually handle - * signals, though. This code is based on proposals made by - * Mark Diekhans and Don Libes. + * This file provides low-level support needed to invoke signal handlers + * in a safe way. The code here doesn't actually handle signals, though. + * This code is based on proposals made by Mark Diekhans and Don Libes. * * Copyright (c) 1993 The Regents of the University of California. * Copyright (c) 1994 Sun Microsystems, Inc. * - * See the file "license.terms" for information on usage and redistribution - * of this file, and for a DISCLAIMER OF ALL WARRANTIES. + * See the file "license.terms" for information on usage and redistribution of + * this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tclAsync.c,v 1.7 2004/04/06 22:25:48 dgp Exp $ + * RCS: @(#) $Id: tclAsync.c,v 1.8 2005/07/19 22:45:19 dkf Exp $ */ #include "tclInt.h" @@ -21,72 +20,61 @@ struct ThreadSpecificData; /* - * One of the following structures exists for each asynchronous - * handler: + * One of the following structures exists for each asynchronous handler: */ typedef struct AsyncHandler { - int ready; /* Non-zero means this handler should - * be invoked in the next call to - * Tcl_AsyncInvoke. */ - struct AsyncHandler *nextPtr; /* Next in list of all handlers for - * the process. */ - Tcl_AsyncProc *proc; /* Procedure to call when handler - * is invoked. */ - ClientData clientData; /* Value to pass to handler when it - * is invoked. */ + int ready; /* Non-zero means this handler should be + * invoked in the next call to + * Tcl_AsyncInvoke. */ + struct AsyncHandler *nextPtr; + /* Next in list of all handlers for the + * process. */ + Tcl_AsyncProc *proc; /* Procedure to call when handler is + * invoked. */ + ClientData clientData; /* Value to pass to handler when it is + * invoked. */ struct ThreadSpecificData *originTsd; - /* Used in Tcl_AsyncMark to modify thread- - * specific data from outside the thread - * it is associated to. */ - Tcl_ThreadId originThrdId; /* Origin thread where this token was - * created and where it will be - * yielded. */ + /* Used in Tcl_AsyncMark to modify thread- + * specific data from outside the thread it is + * associated to. */ + Tcl_ThreadId originThrdId; /* Origin thread where this token was created + * and where it will be yielded. */ } AsyncHandler; - typedef struct ThreadSpecificData { /* - * The variables below maintain a list of all existing handlers - * specific to the calling thread. - */ - AsyncHandler *firstHandler; /* First handler defined for process, - * or NULL if none. */ - AsyncHandler *lastHandler; /* Last handler or NULL. */ - - /* - * The variable below is set to 1 whenever a handler becomes ready and - * it is cleared to zero whenever Tcl_AsyncInvoke is called. It can be - * checked elsewhere in the application by calling Tcl_AsyncReady to see - * if Tcl_AsyncInvoke should be invoked. - */ - - int asyncReady; - - /* - * The variable below indicates whether Tcl_AsyncInvoke is currently - * working. If so then we won't set asyncReady again until - * Tcl_AsyncInvoke returns. + * The variables below maintain a list of all existing handlers specific + * to the calling thread. */ - - int asyncActive; - - Tcl_Mutex asyncMutex; /* Thread-specific AsyncHandler linked-list lock */ - + AsyncHandler *firstHandler; /* First handler defined for process, or NULL + * if none. */ + AsyncHandler *lastHandler; /* Last handler or NULL. */ + int asyncReady; /* This is set to 1 whenever a handler becomes + * ready and it is cleared to zero whenever + * Tcl_AsyncInvoke is called. It can be + * checked elsewhere in the application by + * calling Tcl_AsyncReady to see if + * Tcl_AsyncInvoke should be invoked. */ + int asyncActive; /* Indicates whether Tcl_AsyncInvoke is + * currently working. If so then we won't set + * asyncReady again until Tcl_AsyncInvoke + * returns. */ + Tcl_Mutex asyncMutex; /* Thread-specific AsyncHandler linked-list + * lock */ } ThreadSpecificData; static Tcl_ThreadDataKey dataKey; - /* *---------------------------------------------------------------------- * * TclFinalizeAsync -- * - * Finalizes the mutex in the thread local data structure for the - * async subsystem. + * Finalizes the mutex in the thread local data structure for the async + * subsystem. * * Results: - * None. + * None. * * Side effects: * Forgets knowledge of the mutex should it have been created. @@ -110,12 +98,12 @@ TclFinalizeAsync() * Tcl_AsyncCreate -- * * This procedure creates the data structures for an asynchronous - * handler, so that no memory has to be allocated when the handler - * is activated. + * handler, so that no memory has to be allocated when the handler is + * activated. * * Results: - * The return value is a token for the handler, which can be used - * to activate it later on. + * The return value is a token for the handler, which can be used to + * activate it later on. * * Side effects: * Information about the handler is recorded. @@ -125,9 +113,9 @@ TclFinalizeAsync() Tcl_AsyncHandler Tcl_AsyncCreate(proc, clientData) - Tcl_AsyncProc *proc; /* Procedure to call when handler - * is invoked. */ - ClientData clientData; /* Argument to pass to handler. */ + Tcl_AsyncProc *proc; /* Procedure to call when handler is + * invoked. */ + ClientData clientData; /* Argument to pass to handler. */ { AsyncHandler *asyncPtr; ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); @@ -156,10 +144,10 @@ Tcl_AsyncCreate(proc, clientData) * * Tcl_AsyncMark -- * - * This procedure is called to request that an asynchronous handler - * be invoked as soon as possible. It's typically called from - * an interrupt handler, where it isn't safe to do anything that - * depends on or modifies application state. + * This procedure is called to request that an asynchronous handler be + * invoked as soon as possible. It's typically called from an interrupt + * handler, where it isn't safe to do anything that depends on or + * modifies application state. * * Results: * None. @@ -190,13 +178,12 @@ Tcl_AsyncMark(async) * * Tcl_AsyncInvoke -- * - * This procedure is called at a "safe" time at background level - * to invoke any active asynchronous handlers. + * This procedure is called at a "safe" time at background level to + * invoke any active asynchronous handlers. * * Results: - * The return value is a normal Tcl result, which is intended to - * replace the code argument as the current completion code for - * interp. + * The return value is a normal Tcl result, which is intended to replace + * the code argument as the current completion code for interp. * * Side effects: * Depends on the handlers that are active. @@ -206,13 +193,12 @@ Tcl_AsyncMark(async) int Tcl_AsyncInvoke(interp, code) - Tcl_Interp *interp; /* If invoked from Tcl_Eval just after - * completing a command, points to - * interpreter. Otherwise it is - * NULL. */ - int code; /* If interp is non-NULL, this gives - * completion code from command that - * just completed. */ + Tcl_Interp *interp; /* If invoked from Tcl_Eval just after + * completing a command, points to + * interpreter. Otherwise it is NULL. */ + int code; /* If interp is non-NULL, this gives + * completion code from command that just + * completed. */ { AsyncHandler *asyncPtr; ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); @@ -230,13 +216,12 @@ Tcl_AsyncInvoke(interp, code) } /* - * Make one or more passes over the list of handlers, invoking - * at most one handler in each pass. After invoking a handler, - * go back to the start of the list again so that (a) if a new - * higher-priority handler gets marked while executing a lower - * priority handler, we execute the higher-priority handler - * next, and (b) if a handler gets deleted during the execution - * of a handler, then the list structure may change so it isn't + * Make one or more passes over the list of handlers, invoking at most one + * handler in each pass. After invoking a handler, go back to the start of + * the list again so that (a) if a new higher-priority handler gets marked + * while executing a lower priority handler, we execute the higher- + * priority handler next, and (b) if a handler gets deleted during the + * execution of a handler, then the list structure may change so it isn't * safe to continue down the list anyway. */ @@ -265,8 +250,8 @@ Tcl_AsyncInvoke(interp, code) * * Tcl_AsyncDelete -- * - * Frees up all the state for an asynchronous handler. The handler - * should never be used again. + * Frees up all the state for an asynchronous handler. The handler should + * never be used again. * * Results: * None. @@ -310,13 +295,13 @@ Tcl_AsyncDelete(async) * * Tcl_AsyncReady -- * - * This procedure can be used to tell whether Tcl_AsyncInvoke - * needs to be called. This procedure is the external interface - * for checking the thread-specific asyncReady variable. + * This procedure can be used to tell whether Tcl_AsyncInvoke needs to be + * called. This procedure is the external interface for checking the + * thread-specific asyncReady variable. * * Results: - * The return value is 1 whenever a handler is ready and is 0 - * when no handlers are ready. + * The return value is 1 whenever a handler is ready and is 0 when no + * handlers are ready. * * Side effects: * None. @@ -330,3 +315,11 @@ Tcl_AsyncReady() ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); return tsdPtr->asyncReady; } + +/* + * Local Variables: + * mode: c + * c-basic-offset: 4 + * fill-column: 78 + * End: + */ |