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