summaryrefslogtreecommitdiffstats
path: root/generic/tclAsync.c
diff options
context:
space:
mode:
Diffstat (limited to 'generic/tclAsync.c')
-rw-r--r--generic/tclAsync.c207
1 files changed, 103 insertions, 104 deletions
diff --git a/generic/tclAsync.c b/generic/tclAsync.c
index 98087c5..f210004 100644
--- a/generic/tclAsync.c
+++ b/generic/tclAsync.c
@@ -1,91 +1,78 @@
-/*
+/*
* 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.
- */
- 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.
+ * The variables below maintain a list of all existing handlers specific
+ * to the calling thread.
*/
-
- 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 */
-
+ 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.
@@ -94,7 +81,7 @@ static Tcl_ThreadDataKey dataKey;
*/
void
-TclFinalizeAsync()
+TclFinalizeAsync(void)
{
ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
@@ -109,12 +96,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.
@@ -123,10 +110,10 @@ 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_AsyncCreate(
+ 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);
@@ -155,10 +142,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.
@@ -170,8 +157,8 @@ Tcl_AsyncCreate(proc, clientData)
*/
void
-Tcl_AsyncMark(async)
- Tcl_AsyncHandler async; /* Token for handler. */
+Tcl_AsyncMark(
+ Tcl_AsyncHandler async) /* Token for handler. */
{
AsyncHandler *token = (AsyncHandler *) async;
@@ -189,13 +176,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.
@@ -204,14 +190,13 @@ 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_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. */
{
AsyncHandler *asyncPtr;
ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
@@ -229,13 +214,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.
*/
@@ -251,7 +235,7 @@ Tcl_AsyncInvoke(interp, code)
}
asyncPtr->ready = 0;
Tcl_MutexUnlock(&tsdPtr->asyncMutex);
- code = (*asyncPtr->proc)(asyncPtr->clientData, interp, code);
+ code = asyncPtr->proc(asyncPtr->clientData, interp, code);
Tcl_MutexLock(&tsdPtr->asyncMutex);
}
tsdPtr->asyncActive = 0;
@@ -264,8 +248,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.
@@ -276,7 +260,7 @@ Tcl_AsyncInvoke(interp, code)
* Failure to locate the handler in current thread private list
* of async handlers will result in panic; exception: the list
* is already empty (potential trouble?).
- * Consequently, threads should create and delete handlers
+ * Consequently, threads should create and delete handlers
* themselves. I.e. a handler created by one should not be
* deleted by some other thread.
*
@@ -284,8 +268,8 @@ Tcl_AsyncInvoke(interp, code)
*/
void
-Tcl_AsyncDelete(async)
- Tcl_AsyncHandler async; /* Token for handler to delete. */
+Tcl_AsyncDelete(
+ Tcl_AsyncHandler async) /* Token for handler to delete. */
{
ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
AsyncHandler *asyncPtr = (AsyncHandler *) async;
@@ -296,7 +280,7 @@ Tcl_AsyncDelete(async)
*/
if (asyncPtr->originThrdId != Tcl_GetCurrentThread()) {
- panic("Tcl_AsyncDelete: async handler deleted by the wrong thread");
+ Tcl_Panic("Tcl_AsyncDelete: async handler deleted by the wrong thread");
}
/*
@@ -314,7 +298,7 @@ Tcl_AsyncDelete(async)
thisPtr = thisPtr->nextPtr;
}
if (thisPtr == NULL) {
- panic("Tcl_AsyncDelete: cannot find async handler");
+ Tcl_Panic("Tcl_AsyncDelete: cannot find async handler");
}
if (asyncPtr == tsdPtr->firstHandler) {
tsdPtr->firstHandler = asyncPtr->nextPtr;
@@ -334,13 +318,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.
@@ -349,8 +333,23 @@ Tcl_AsyncDelete(async)
*/
int
-Tcl_AsyncReady()
+Tcl_AsyncReady(void)
{
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:
+ */