diff options
Diffstat (limited to 'generic/tclAsync.c')
| -rw-r--r-- | generic/tclAsync.c | 203 |
1 files changed, 102 insertions, 101 deletions
diff --git a/generic/tclAsync.c b/generic/tclAsync.c index ca18f5e..98087c5 100644 --- a/generic/tclAsync.c +++ b/generic/tclAsync.c @@ -1,78 +1,91 @@ -/* +/* * 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. */ #include "tclInt.h" +#include "tclPort.h" /* Forward declaration */ 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. + * 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. */ - 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 */ + + 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. + */ + + int asyncActive; + + 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. @@ -81,7 +94,7 @@ static Tcl_ThreadDataKey dataKey; */ void -TclFinalizeAsync(void) +TclFinalizeAsync() { ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); @@ -96,12 +109,12 @@ TclFinalizeAsync(void) * 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. @@ -110,10 +123,10 @@ TclFinalizeAsync(void) */ Tcl_AsyncHandler -Tcl_AsyncCreate( - Tcl_AsyncProc *proc, /* Procedure to call when handler is - * invoked. */ - ClientData clientData) /* Argument to pass to handler. */ +Tcl_AsyncCreate(proc, clientData) + 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); @@ -142,10 +155,10 @@ Tcl_AsyncCreate( * * 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. @@ -157,8 +170,8 @@ Tcl_AsyncCreate( */ void -Tcl_AsyncMark( - Tcl_AsyncHandler async) /* Token for handler. */ +Tcl_AsyncMark(async) + Tcl_AsyncHandler async; /* Token for handler. */ { AsyncHandler *token = (AsyncHandler *) async; @@ -176,12 +189,13 @@ Tcl_AsyncMark( * * 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. @@ -190,13 +204,14 @@ Tcl_AsyncMark( */ int -Tcl_AsyncInvoke( - 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_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. */ { AsyncHandler *asyncPtr; ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); @@ -214,12 +229,13 @@ Tcl_AsyncInvoke( } /* - * 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. */ @@ -248,8 +264,8 @@ Tcl_AsyncInvoke( * * 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. @@ -268,8 +284,8 @@ Tcl_AsyncInvoke( */ void -Tcl_AsyncDelete( - Tcl_AsyncHandler async) /* Token for handler to delete. */ +Tcl_AsyncDelete(async) + Tcl_AsyncHandler async; /* Token for handler to delete. */ { ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); AsyncHandler *asyncPtr = (AsyncHandler *) async; @@ -280,7 +296,7 @@ Tcl_AsyncDelete( */ if (asyncPtr->originThrdId != Tcl_GetCurrentThread()) { - Tcl_Panic("Tcl_AsyncDelete: async handler deleted by the wrong thread"); + panic("Tcl_AsyncDelete: async handler deleted by the wrong thread"); } /* @@ -298,7 +314,7 @@ Tcl_AsyncDelete( thisPtr = thisPtr->nextPtr; } if (thisPtr == NULL) { - Tcl_Panic("Tcl_AsyncDelete: cannot find async handler"); + panic("Tcl_AsyncDelete: cannot find async handler"); } if (asyncPtr == tsdPtr->firstHandler) { tsdPtr->firstHandler = asyncPtr->nextPtr; @@ -318,13 +334,13 @@ Tcl_AsyncDelete( * * 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. @@ -333,23 +349,8 @@ Tcl_AsyncDelete( */ int -Tcl_AsyncReady(void) +Tcl_AsyncReady() { ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); return tsdPtr->asyncReady; } - -int * -TclGetAsyncReadyPtr(void) -{ - ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); - return &(tsdPtr->asyncReady); -} - -/* - * Local Variables: - * mode: c - * c-basic-offset: 4 - * fill-column: 78 - * End: - */ |
