diff options
Diffstat (limited to 'generic/tclNotify.c')
-rw-r--r-- | generic/tclNotify.c | 201 |
1 files changed, 109 insertions, 92 deletions
diff --git a/generic/tclNotify.c b/generic/tclNotify.c index cb777af..e76bca8 100644 --- a/generic/tclNotify.c +++ b/generic/tclNotify.c @@ -13,13 +13,18 @@ * * See the file "license.terms" for information on usage and redistribution of * this file, and for a DISCLAIMER OF ALL WARRANTIES. - * - * RCS: @(#) $Id: tclNotify.c,v 1.19 2005/07/21 14:38:50 dkf Exp $ */ #include "tclInt.h" -extern TclStubs tclStubs; +/* + * Module-scope struct of notifier hooks that are checked in the default + * notifier functions (for overriding via Tcl_SetNotifier). + */ + +Tcl_NotifierProcs tclNotifierHooks = { + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL +}; /* * For each event source (created with Tcl_CreateEventSource) there is a @@ -89,8 +94,8 @@ TCL_DECLARE_MUTEX(listLock) * Declarations for routines used only in this file. */ -static void QueueEvent _ANSI_ARGS_((ThreadSpecificData *tsdPtr, - Tcl_Event* evPtr, Tcl_QueuePosition position)); +static void QueueEvent(ThreadSpecificData *tsdPtr, + Tcl_Event *evPtr, Tcl_QueuePosition position); /* *---------------------------------------------------------------------- @@ -110,7 +115,7 @@ static void QueueEvent _ANSI_ARGS_((ThreadSpecificData *tsdPtr, */ void -TclInitNotifier() +TclInitNotifier(void) { ThreadSpecificData *tsdPtr; Tcl_ThreadId threadId = Tcl_GetCurrentThread(); @@ -128,7 +133,7 @@ TclInitNotifier() tsdPtr = TCL_TSD_INIT(&dataKey); tsdPtr->threadId = threadId; - tsdPtr->clientData = tclStubs.tcl_InitNotifier(); + tsdPtr->clientData = Tcl_InitNotifier(); tsdPtr->initialized = 1; tsdPtr->nextPtr = firstNotifierPtr; firstNotifierPtr = tsdPtr; @@ -162,7 +167,7 @@ TclInitNotifier() */ void -TclFinalizeNotifier() +TclFinalizeNotifier(void) { ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); ThreadSpecificData **prevPtrPtr; @@ -173,10 +178,10 @@ TclFinalizeNotifier() } Tcl_MutexLock(&(tsdPtr->queueMutex)); - for (evPtr = tsdPtr->firstEventPtr; evPtr != (Tcl_Event *) NULL; ) { + for (evPtr = tsdPtr->firstEventPtr; evPtr != NULL; ) { hold = evPtr; evPtr = evPtr->nextPtr; - ckfree((char *) hold); + ckfree(hold); } tsdPtr->firstEventPtr = NULL; tsdPtr->lastEventPtr = NULL; @@ -184,9 +189,7 @@ TclFinalizeNotifier() Tcl_MutexLock(&listLock); - if (tclStubs.tcl_FinalizeNotifier) { - tclStubs.tcl_FinalizeNotifier(tsdPtr->clientData); - } + Tcl_FinalizeNotifier(tsdPtr->clientData); Tcl_MutexFinalize(&(tsdPtr->queueMutex)); for (prevPtrPtr = &firstNotifierPtr; *prevPtrPtr != NULL; prevPtrPtr = &((*prevPtrPtr)->nextPtr)) { @@ -213,27 +216,17 @@ TclFinalizeNotifier() * None. * * Side effects: - * Overstomps part of the stub vector. This relies on hooks added to the - * default functions in case those are called directly (i.e., not through - * the stub table.) + * Set the tclNotifierHooks global, which is checked in the default + * notifier functions. * *---------------------------------------------------------------------- */ void -Tcl_SetNotifier(notifierProcPtr) - Tcl_NotifierProcs *notifierProcPtr; +Tcl_SetNotifier( + Tcl_NotifierProcs *notifierProcPtr) { -#if !defined(__WIN32__) /* UNIX */ - tclStubs.tcl_CreateFileHandler = notifierProcPtr->createFileHandlerProc; - tclStubs.tcl_DeleteFileHandler = notifierProcPtr->deleteFileHandlerProc; -#endif - tclStubs.tcl_SetTimer = notifierProcPtr->setTimerProc; - tclStubs.tcl_WaitForEvent = notifierProcPtr->waitForEventProc; - tclStubs.tcl_InitNotifier = notifierProcPtr->initNotifierProc; - tclStubs.tcl_FinalizeNotifier = notifierProcPtr->finalizeNotifierProc; - tclStubs.tcl_AlertNotifier = notifierProcPtr->alertNotifierProc; - tclStubs.tcl_ServiceModeHook = notifierProcPtr->serviceModeHookProc; + tclNotifierHooks = *notifierProcPtr; } /* @@ -272,18 +265,18 @@ Tcl_SetNotifier(notifierProcPtr) */ void -Tcl_CreateEventSource(setupProc, checkProc, clientData) - Tcl_EventSetupProc *setupProc; +Tcl_CreateEventSource( + Tcl_EventSetupProc *setupProc, /* Function to invoke to figure out what to * wait for. */ - Tcl_EventCheckProc *checkProc; + Tcl_EventCheckProc *checkProc, /* Function to call after waiting to see what * happened. */ - ClientData clientData; /* One-word argument to pass to setupProc and + ClientData clientData) /* One-word argument to pass to setupProc and * checkProc. */ { ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); - EventSource *sourcePtr = (EventSource *) ckalloc(sizeof(EventSource)); + EventSource *sourcePtr = ckalloc(sizeof(EventSource)); sourcePtr->setupProc = setupProc; sourcePtr->checkProc = checkProc; @@ -304,21 +297,21 @@ Tcl_CreateEventSource(setupProc, checkProc, clientData) * None. * * Side effects: - * The given event source is cancelled, so its function will never again + * The given event source is canceled, so its function will never again * be called. If no such source exists, nothing happens. * *---------------------------------------------------------------------- */ void -Tcl_DeleteEventSource(setupProc, checkProc, clientData) - Tcl_EventSetupProc *setupProc; +Tcl_DeleteEventSource( + Tcl_EventSetupProc *setupProc, /* Function to invoke to figure out what to * wait for. */ - Tcl_EventCheckProc *checkProc; + Tcl_EventCheckProc *checkProc, /* Function to call after waiting to see what * happened. */ - ClientData clientData; /* One-word argument to pass to setupProc and + ClientData clientData) /* One-word argument to pass to setupProc and * checkProc. */ { ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); @@ -337,7 +330,7 @@ Tcl_DeleteEventSource(setupProc, checkProc, clientData) } else { prevPtr->nextPtr = sourcePtr->nextPtr; } - ckfree((char *) sourcePtr); + ckfree(sourcePtr); return; } } @@ -359,16 +352,17 @@ Tcl_DeleteEventSource(setupProc, checkProc, clientData) */ void -Tcl_QueueEvent(evPtr, position) - Tcl_Event* evPtr; /* Event to add to queue. The storage space +Tcl_QueueEvent( + Tcl_Event *evPtr, /* Event to add to queue. The storage space * must have been allocated the caller with * malloc (ckalloc), and it becomes the * property of the event queue. It will be * freed after the event has been handled. */ - Tcl_QueuePosition position; /* One of TCL_QUEUE_TAIL, TCL_QUEUE_HEAD, + Tcl_QueuePosition position) /* One of TCL_QUEUE_TAIL, TCL_QUEUE_HEAD, * TCL_QUEUE_MARK. */ { ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); + QueueEvent(tsdPtr, evPtr, position); } @@ -389,14 +383,14 @@ Tcl_QueueEvent(evPtr, position) */ void -Tcl_ThreadQueueEvent(threadId, evPtr, position) - Tcl_ThreadId threadId; /* Identifier for thread to use. */ - Tcl_Event* evPtr; /* Event to add to queue. The storage space +Tcl_ThreadQueueEvent( + Tcl_ThreadId threadId, /* Identifier for thread to use. */ + Tcl_Event *evPtr, /* Event to add to queue. The storage space * must have been allocated the caller with * malloc (ckalloc), and it becomes the * property of the event queue. It will be * freed after the event has been handled. */ - Tcl_QueuePosition position; /* One of TCL_QUEUE_TAIL, TCL_QUEUE_HEAD, + Tcl_QueuePosition position) /* One of TCL_QUEUE_TAIL, TCL_QUEUE_HEAD, * TCL_QUEUE_MARK. */ { ThreadSpecificData *tsdPtr; @@ -417,6 +411,8 @@ Tcl_ThreadQueueEvent(threadId, evPtr, position) if (tsdPtr) { QueueEvent(tsdPtr, evPtr, position); + } else { + ckfree(evPtr); } Tcl_MutexUnlock(&listLock); } @@ -443,15 +439,15 @@ Tcl_ThreadQueueEvent(threadId, evPtr, position) */ static void -QueueEvent(tsdPtr, evPtr, position) - ThreadSpecificData *tsdPtr; /* Handle to thread local data that indicates +QueueEvent( + ThreadSpecificData *tsdPtr, /* Handle to thread local data that indicates * which event queue to use. */ - Tcl_Event* evPtr; /* Event to add to queue. The storage space + Tcl_Event *evPtr, /* Event to add to queue. The storage space * must have been allocated the caller with * malloc (ckalloc), and it becomes the * property of the event queue. It will be * freed after the event has been handled. */ - Tcl_QueuePosition position; /* One of TCL_QUEUE_TAIL, TCL_QUEUE_HEAD, + Tcl_QueuePosition position) /* One of TCL_QUEUE_TAIL, TCL_QUEUE_HEAD, * TCL_QUEUE_MARK. */ { Tcl_MutexLock(&(tsdPtr->queueMutex)); @@ -518,32 +514,61 @@ QueueEvent(tsdPtr, evPtr, position) */ void -Tcl_DeleteEvents(proc, clientData) - Tcl_EventDeleteProc *proc; /* The function to call. */ - ClientData clientData; /* The type-specific data. */ +Tcl_DeleteEvents( + Tcl_EventDeleteProc *proc, /* The function to call. */ + ClientData clientData) /* The type-specific data. */ { - Tcl_Event *evPtr, *prevPtr, *hold; + Tcl_Event *evPtr; /* Pointer to the event being examined */ + Tcl_Event *prevPtr; /* Pointer to evPtr's predecessor, or NULL if + * evPtr designates the first event in the + * queue for the thread. */ + Tcl_Event *hold; ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); Tcl_MutexLock(&(tsdPtr->queueMutex)); - for (prevPtr = (Tcl_Event *) NULL, evPtr = tsdPtr->firstEventPtr; - evPtr != (Tcl_Event *) NULL; /*EMPTY STEP*/) { - if ((*proc) (evPtr, clientData) == 1) { - if (tsdPtr->firstEventPtr == evPtr) { + + /* + * Walk the queue of events for the thread, applying 'proc' to each to + * decide whether to eliminate the event. + */ + + prevPtr = NULL; + evPtr = tsdPtr->firstEventPtr; + while (evPtr != NULL) { + if (proc(evPtr, clientData) == 1) { + /* + * This event should be deleted. Unlink it. + */ + + if (prevPtr == NULL) { tsdPtr->firstEventPtr = evPtr->nextPtr; } else { prevPtr->nextPtr = evPtr->nextPtr; } - if (evPtr->nextPtr == (Tcl_Event *) NULL) { + + /* + * Update 'last' and 'marker' events if either has been deleted. + */ + + if (evPtr->nextPtr == NULL) { tsdPtr->lastEventPtr = prevPtr; } if (tsdPtr->markerEventPtr == evPtr) { tsdPtr->markerEventPtr = prevPtr; } + + /* + * Delete the event data structure. + */ + hold = evPtr; evPtr = evPtr->nextPtr; - ckfree((char *) hold); + ckfree(hold); } else { + /* + * Event is to be retained. + */ + prevPtr = evPtr; evPtr = evPtr->nextPtr; } @@ -572,8 +597,8 @@ Tcl_DeleteEvents(proc, clientData) */ int -Tcl_ServiceEvent(flags) - int flags; /* Indicates what events should be processed. +Tcl_ServiceEvent( + int flags) /* Indicates what events should be processed. * May be any combination of TCL_WINDOW_EVENTS * TCL_FILE_EVENTS, TCL_TIMER_EVENTS, or other * flags defined elsewhere. Events not @@ -592,7 +617,7 @@ Tcl_ServiceEvent(flags) */ if (Tcl_AsyncReady()) { - (void) Tcl_AsyncInvoke((Tcl_Interp *) NULL, 0); + (void) Tcl_AsyncInvoke(NULL, 0); return 1; } @@ -642,7 +667,7 @@ Tcl_ServiceEvent(flags) */ Tcl_MutexUnlock(&(tsdPtr->queueMutex)); - result = (*proc)(evPtr, flags); + result = proc(evPtr, flags); Tcl_MutexLock(&(tsdPtr->queueMutex)); if (result) { @@ -677,7 +702,7 @@ Tcl_ServiceEvent(flags) } } if (evPtr) { - ckfree((char *) evPtr); + ckfree(evPtr); } Tcl_MutexUnlock(&(tsdPtr->queueMutex)); return 1; @@ -711,7 +736,7 @@ Tcl_ServiceEvent(flags) */ int -Tcl_GetServiceMode() +Tcl_GetServiceMode(void) { ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); @@ -735,8 +760,8 @@ Tcl_GetServiceMode() */ int -Tcl_SetServiceMode(mode) - int mode; /* New service mode: TCL_SERVICE_ALL or +Tcl_SetServiceMode( + int mode) /* New service mode: TCL_SERVICE_ALL or * TCL_SERVICE_NONE */ { int oldMode; @@ -744,9 +769,7 @@ Tcl_SetServiceMode(mode) oldMode = tsdPtr->serviceMode; tsdPtr->serviceMode = mode; - if (tclStubs.tcl_ServiceModeHook) { - tclStubs.tcl_ServiceModeHook(mode); - } + Tcl_ServiceModeHook(mode); return oldMode; } @@ -770,8 +793,8 @@ Tcl_SetServiceMode(mode) */ void -Tcl_SetMaxBlockTime(timePtr) - Tcl_Time *timePtr; /* Specifies a maximum elapsed time for the +Tcl_SetMaxBlockTime( + const Tcl_Time *timePtr) /* Specifies a maximum elapsed time for the * next blocking operation in the event * tsdPtr-> */ { @@ -790,11 +813,7 @@ Tcl_SetMaxBlockTime(timePtr) */ if (!tsdPtr->inTraversal) { - if (tsdPtr->blockTimeSet) { - Tcl_SetTimer(&tsdPtr->blockTime); - } else { - Tcl_SetTimer(NULL); - } + Tcl_SetTimer(&tsdPtr->blockTime); } } @@ -822,8 +841,8 @@ Tcl_SetMaxBlockTime(timePtr) */ int -Tcl_DoOneEvent(flags) - int flags; /* Miscellaneous flag values: may be any +Tcl_DoOneEvent( + int flags) /* Miscellaneous flag values: may be any * combination of TCL_DONT_WAIT, * TCL_WINDOW_EVENTS, TCL_FILE_EVENTS, * TCL_TIMER_EVENTS, TCL_IDLE_EVENTS, or @@ -839,7 +858,7 @@ Tcl_DoOneEvent(flags) */ if (Tcl_AsyncReady()) { - (void) Tcl_AsyncInvoke((Tcl_Interp *) NULL, 0); + (void) Tcl_AsyncInvoke(NULL, 0); return 1; } @@ -908,7 +927,7 @@ Tcl_DoOneEvent(flags) for (sourcePtr = tsdPtr->firstEventSourcePtr; sourcePtr != NULL; sourcePtr = sourcePtr->nextPtr) { if (sourcePtr->setupProc) { - (sourcePtr->setupProc)(sourcePtr->clientData, flags); + sourcePtr->setupProc(sourcePtr->clientData, flags); } } tsdPtr->inTraversal = 0; @@ -937,7 +956,7 @@ Tcl_DoOneEvent(flags) for (sourcePtr = tsdPtr->firstEventSourcePtr; sourcePtr != NULL; sourcePtr = sourcePtr->nextPtr) { if (sourcePtr->checkProc) { - (sourcePtr->checkProc)(sourcePtr->clientData, flags); + sourcePtr->checkProc(sourcePtr->clientData, flags); } } @@ -1010,7 +1029,7 @@ Tcl_DoOneEvent(flags) */ int -Tcl_ServiceAll() +Tcl_ServiceAll(void) { int result = 0; EventSource *sourcePtr; @@ -1032,7 +1051,7 @@ Tcl_ServiceAll() */ if (Tcl_AsyncReady()) { - (void) Tcl_AsyncInvoke((Tcl_Interp *) NULL, 0); + (void) Tcl_AsyncInvoke(NULL, 0); } /* @@ -1047,13 +1066,13 @@ Tcl_ServiceAll() for (sourcePtr = tsdPtr->firstEventSourcePtr; sourcePtr != NULL; sourcePtr = sourcePtr->nextPtr) { if (sourcePtr->setupProc) { - (sourcePtr->setupProc)(sourcePtr->clientData, TCL_ALL_EVENTS); + sourcePtr->setupProc(sourcePtr->clientData, TCL_ALL_EVENTS); } } for (sourcePtr = tsdPtr->firstEventSourcePtr; sourcePtr != NULL; sourcePtr = sourcePtr->nextPtr) { if (sourcePtr->checkProc) { - (sourcePtr->checkProc)(sourcePtr->clientData, TCL_ALL_EVENTS); + sourcePtr->checkProc(sourcePtr->clientData, TCL_ALL_EVENTS); } } @@ -1092,8 +1111,8 @@ Tcl_ServiceAll() */ void -Tcl_ThreadAlert(threadId) - Tcl_ThreadId threadId; /* Identifier for thread to use. */ +Tcl_ThreadAlert( + Tcl_ThreadId threadId) /* Identifier for thread to use. */ { ThreadSpecificData *tsdPtr; @@ -1106,9 +1125,7 @@ Tcl_ThreadAlert(threadId) Tcl_MutexLock(&listLock); for (tsdPtr = firstNotifierPtr; tsdPtr; tsdPtr = tsdPtr->nextPtr) { if (tsdPtr->threadId == threadId) { - if (tclStubs.tcl_AlertNotifier) { - tclStubs.tcl_AlertNotifier(tsdPtr->clientData); - } + Tcl_AlertNotifier(tsdPtr->clientData); break; } } |