diff options
Diffstat (limited to 'generic/tclNotify.c')
-rw-r--r-- | generic/tclNotify.c | 118 |
1 files changed, 68 insertions, 50 deletions
diff --git a/generic/tclNotify.c b/generic/tclNotify.c index d8de8d8..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.20 2005/11/02 00:55:06 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 @@ -90,7 +95,7 @@ TCL_DECLARE_MUTEX(listLock) */ static void QueueEvent(ThreadSpecificData *tsdPtr, - Tcl_Event* evPtr, Tcl_QueuePosition position); + Tcl_Event *evPtr, Tcl_QueuePosition position); /* *---------------------------------------------------------------------- @@ -128,7 +133,7 @@ TclInitNotifier(void) 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; @@ -176,7 +181,7 @@ TclFinalizeNotifier(void) 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(void) 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,9 +216,8 @@ TclFinalizeNotifier(void) * 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. * *---------------------------------------------------------------------- */ @@ -224,16 +226,7 @@ void 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; } /* @@ -283,7 +276,7 @@ Tcl_CreateEventSource( * 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,7 +297,7 @@ Tcl_CreateEventSource( * 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. * *---------------------------------------------------------------------- @@ -337,7 +330,7 @@ Tcl_DeleteEventSource( } else { prevPtr->nextPtr = sourcePtr->nextPtr; } - ckfree((char *) sourcePtr); + ckfree(sourcePtr); return; } } @@ -360,7 +353,7 @@ Tcl_DeleteEventSource( void Tcl_QueueEvent( - 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 @@ -369,6 +362,7 @@ Tcl_QueueEvent( * TCL_QUEUE_MARK. */ { ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); + QueueEvent(tsdPtr, evPtr, position); } @@ -417,6 +411,8 @@ Tcl_ThreadQueueEvent( if (tsdPtr) { QueueEvent(tsdPtr, evPtr, position); + } else { + ckfree(evPtr); } Tcl_MutexUnlock(&listLock); } @@ -520,29 +516,59 @@ QueueEvent( void Tcl_DeleteEvents( Tcl_EventDeleteProc *proc, /* The function to call. */ - ClientData clientData) /* The type-specific data. */ + 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=NULL, evPtr=tsdPtr->firstEventPtr; evPtr!=NULL; ) { - 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; } + + /* + * 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; } @@ -641,7 +667,7 @@ Tcl_ServiceEvent( */ Tcl_MutexUnlock(&(tsdPtr->queueMutex)); - result = (*proc)(evPtr, flags); + result = proc(evPtr, flags); Tcl_MutexLock(&(tsdPtr->queueMutex)); if (result) { @@ -676,7 +702,7 @@ Tcl_ServiceEvent( } } if (evPtr) { - ckfree((char *) evPtr); + ckfree(evPtr); } Tcl_MutexUnlock(&(tsdPtr->queueMutex)); return 1; @@ -743,9 +769,7 @@ Tcl_SetServiceMode( oldMode = tsdPtr->serviceMode; tsdPtr->serviceMode = mode; - if (tclStubs.tcl_ServiceModeHook) { - tclStubs.tcl_ServiceModeHook(mode); - } + Tcl_ServiceModeHook(mode); return oldMode; } @@ -770,7 +794,7 @@ Tcl_SetServiceMode( void Tcl_SetMaxBlockTime( - Tcl_Time *timePtr) /* Specifies a maximum elapsed time for the + const Tcl_Time *timePtr) /* Specifies a maximum elapsed time for the * next blocking operation in the event * tsdPtr-> */ { @@ -789,11 +813,7 @@ Tcl_SetMaxBlockTime( */ if (!tsdPtr->inTraversal) { - if (tsdPtr->blockTimeSet) { - Tcl_SetTimer(&tsdPtr->blockTime); - } else { - Tcl_SetTimer(NULL); - } + Tcl_SetTimer(&tsdPtr->blockTime); } } @@ -907,7 +927,7 @@ Tcl_DoOneEvent( 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; @@ -936,7 +956,7 @@ Tcl_DoOneEvent( for (sourcePtr = tsdPtr->firstEventSourcePtr; sourcePtr != NULL; sourcePtr = sourcePtr->nextPtr) { if (sourcePtr->checkProc) { - (sourcePtr->checkProc)(sourcePtr->clientData, flags); + sourcePtr->checkProc(sourcePtr->clientData, flags); } } @@ -1046,13 +1066,13 @@ Tcl_ServiceAll(void) 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); } } @@ -1105,9 +1125,7 @@ Tcl_ThreadAlert( 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; } } |