summaryrefslogtreecommitdiffstats
path: root/generic/tclNotify.c
diff options
context:
space:
mode:
Diffstat (limited to 'generic/tclNotify.c')
-rw-r--r--generic/tclNotify.c118
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;
}
}