OSDN Git Service

Please enter the commit message for your changes. Lines starting
[eos/base.git] / util / src / TclTk / tcl8.6.4 / generic / tclAsync.c
diff --git a/util/src/TclTk/tcl8.6.4/generic/tclAsync.c b/util/src/TclTk/tcl8.6.4/generic/tclAsync.c
deleted file mode 100644 (file)
index 14804e4..0000000
+++ /dev/null
@@ -1,355 +0,0 @@
-/*
- * 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.
- *
- * 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.
- */
-
-#include "tclInt.h"
-
-/* Forward declaration */
-struct ThreadSpecificData;
-
-/*
- * 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. */
-    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. */
-} 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. */
-    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;
-\f
-/*
- *----------------------------------------------------------------------
- *
- * TclFinalizeAsync --
- *
- *     Finalizes the mutex in the thread local data structure for the async
- *     subsystem.
- *
- * Results:
- *     None.
- *
- * Side effects:
- *     Forgets knowledge of the mutex should it have been created.
- *
- *----------------------------------------------------------------------
- */
-
-void
-TclFinalizeAsync(void)
-{
-    ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
-
-    if (tsdPtr->asyncMutex != NULL) {
-       Tcl_MutexFinalize(&tsdPtr->asyncMutex);
-    }
-}
-\f
-/*
- *----------------------------------------------------------------------
- *
- * 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.
- *
- * Results:
- *     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.
- *
- *----------------------------------------------------------------------
- */
-
-Tcl_AsyncHandler
-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);
-
-    asyncPtr = ckalloc(sizeof(AsyncHandler));
-    asyncPtr->ready = 0;
-    asyncPtr->nextPtr = NULL;
-    asyncPtr->proc = proc;
-    asyncPtr->clientData = clientData;
-    asyncPtr->originTsd = tsdPtr;
-    asyncPtr->originThrdId = Tcl_GetCurrentThread();
-
-    Tcl_MutexLock(&tsdPtr->asyncMutex);
-    if (tsdPtr->firstHandler == NULL) {
-       tsdPtr->firstHandler = asyncPtr;
-    } else {
-       tsdPtr->lastHandler->nextPtr = asyncPtr;
-    }
-    tsdPtr->lastHandler = asyncPtr;
-    Tcl_MutexUnlock(&tsdPtr->asyncMutex);
-    return (Tcl_AsyncHandler) asyncPtr;
-}
-\f
-/*
- *----------------------------------------------------------------------
- *
- * 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.
- *
- * Results:
- *     None.
- *
- * Side effects:
- *     The handler gets marked for invocation later.
- *
- *----------------------------------------------------------------------
- */
-
-void
-Tcl_AsyncMark(
-    Tcl_AsyncHandler async)            /* Token for handler. */
-{
-    AsyncHandler *token = (AsyncHandler *) async;
-
-    Tcl_MutexLock(&token->originTsd->asyncMutex);
-    token->ready = 1;
-    if (!token->originTsd->asyncActive) {
-       token->originTsd->asyncReady = 1;
-       Tcl_ThreadAlert(token->originThrdId);
-    }
-    Tcl_MutexUnlock(&token->originTsd->asyncMutex);
-}
-\f
-/*
- *----------------------------------------------------------------------
- *
- * Tcl_AsyncInvoke --
- *
- *     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.
- *
- * Side effects:
- *     Depends on the handlers that are active.
- *
- *----------------------------------------------------------------------
- */
-
-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. */
-{
-    AsyncHandler *asyncPtr;
-    ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
-
-    Tcl_MutexLock(&tsdPtr->asyncMutex);
-
-    if (tsdPtr->asyncReady == 0) {
-       Tcl_MutexUnlock(&tsdPtr->asyncMutex);
-       return code;
-    }
-    tsdPtr->asyncReady = 0;
-    tsdPtr->asyncActive = 1;
-    if (interp == NULL) {
-       code = 0;
-    }
-
-    /*
-     * 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.
-     */
-
-    while (1) {
-       for (asyncPtr = tsdPtr->firstHandler; asyncPtr != NULL;
-               asyncPtr = asyncPtr->nextPtr) {
-           if (asyncPtr->ready) {
-               break;
-           }
-       }
-       if (asyncPtr == NULL) {
-           break;
-       }
-       asyncPtr->ready = 0;
-       Tcl_MutexUnlock(&tsdPtr->asyncMutex);
-       code = asyncPtr->proc(asyncPtr->clientData, interp, code);
-       Tcl_MutexLock(&tsdPtr->asyncMutex);
-    }
-    tsdPtr->asyncActive = 0;
-    Tcl_MutexUnlock(&tsdPtr->asyncMutex);
-    return code;
-}
-\f
-/*
- *----------------------------------------------------------------------
- *
- * Tcl_AsyncDelete --
- *
- *     Frees up all the state for an asynchronous handler. The handler should
- *     never be used again.
- *
- * Results:
- *     None.
- *
- * Side effects:
- *     The state associated with the handler is deleted.
- *
- *     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
- *     themselves.  I.e. a handler created by one should not be
- *     deleted by some other thread.
- *
- *----------------------------------------------------------------------
- */
-
-void
-Tcl_AsyncDelete(
-    Tcl_AsyncHandler async)            /* Token for handler to delete. */
-{
-    ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
-    AsyncHandler *asyncPtr = (AsyncHandler *) async;
-    AsyncHandler *prevPtr, *thisPtr;
-
-    /*
-     * Assure early handling of the constraint
-     */
-
-    if (asyncPtr->originThrdId != Tcl_GetCurrentThread()) {
-       Tcl_Panic("Tcl_AsyncDelete: async handler deleted by the wrong thread");
-    }
-
-    /*
-     * If we come to this point when TSD's for the current
-     * thread have already been garbage-collected, we are
-     * in the _serious_ trouble. OTOH, we tolerate calling
-     * with already cleaned-up handler list (should we?).
-     */
-
-    Tcl_MutexLock(&tsdPtr->asyncMutex);
-    if (tsdPtr->firstHandler != NULL) {
-       prevPtr = thisPtr = tsdPtr->firstHandler;
-       while (thisPtr != NULL && thisPtr != asyncPtr) {
-           prevPtr = thisPtr;
-           thisPtr = thisPtr->nextPtr;
-       }
-       if (thisPtr == NULL) {
-           Tcl_Panic("Tcl_AsyncDelete: cannot find async handler");
-       }
-       if (asyncPtr == tsdPtr->firstHandler) {
-           tsdPtr->firstHandler = asyncPtr->nextPtr;
-       } else {
-           prevPtr->nextPtr = asyncPtr->nextPtr;
-       }
-       if (asyncPtr == tsdPtr->lastHandler) {
-           tsdPtr->lastHandler = prevPtr;
-       }
-    }
-    Tcl_MutexUnlock(&tsdPtr->asyncMutex);
-    ckfree(asyncPtr);
-}
-\f
-/*
- *----------------------------------------------------------------------
- *
- * 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.
- *
- * Results:
- *     The return value is 1 whenever a handler is ready and is 0 when no
- *     handlers are ready.
- *
- * Side effects:
- *     None.
- *
- *----------------------------------------------------------------------
- */
-
-int
-Tcl_AsyncReady(void)
-{
-    ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
-    return tsdPtr->asyncReady;
-}
-
-int *
-TclGetAsyncReadyPtr(void)
-{
-    ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
-    return &(tsdPtr->asyncReady);
-}
-\f
-/*
- * Local Variables:
- * mode: c
- * c-basic-offset: 4
- * fill-column: 78
- * End:
- */