summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog6
-rw-r--r--macosx/tkMacOSXNotify.c400
2 files changed, 214 insertions, 192 deletions
diff --git a/ChangeLog b/ChangeLog
index 95e8be2..16146ef 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2005-04-28 Donal K. Fellows <donal.k.fellows@manchester.ac.uk>
+
+ * macosx/tkMacOSXNotify.c (TkMacOSXWaitForEvent): Fix for typo in
+ waitTime computation. [Bug 1191097]
+ (AlertNotifier): Factor out the core of the notifier alerting code.
+
2005-04-25 Daniel Steffen <das@users.sourceforge.net>
* macosx/tkMacOSXNotify.c: sync with tclUnixNotfy.c changes since
diff --git a/macosx/tkMacOSXNotify.c b/macosx/tkMacOSXNotify.c
index 5dd6743..abf83b4 100644
--- a/macosx/tkMacOSXNotify.c
+++ b/macosx/tkMacOSXNotify.c
@@ -4,7 +4,7 @@
* This file contains the implementation of a merged
* Carbon/select-based notifier, which is the lowest-level part
* of the Tcl event loop. This file works together with
- * ../generic/tclNotify.c.
+ * generic/tclNotify.c.
*
* Copyright (c) 1995-1997 Sun Microsystems, Inc.
* Copyright 2001, Apple Computer, Inc.
@@ -12,7 +12,7 @@
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * RCS: @(#) $Id: tkMacOSXNotify.c,v 1.9 2005/04/26 00:46:53 das Exp $
+ * RCS: @(#) $Id: tkMacOSXNotify.c,v 1.10 2005/04/28 08:37:01 dkf Exp $
*/
#include "tclInt.h"
@@ -79,7 +79,7 @@ typedef struct SelectMasks {
typedef struct ThreadSpecificData {
FileHandler *firstFileHandlerPtr;
/* Pointer to head of file handler list. */
-
+
SelectMasks checkMasks; /* This structure is used to build up the masks
* to be used in the next call to select.
* Bits are set in response to calls to
@@ -90,25 +90,25 @@ typedef struct ThreadSpecificData {
int numFdBits; /* Number of valid bits in checkMasks
* (one more than highest fd for which
* Tcl_WatchFile has been called). */
- int isMainLoop; /* Is this the main Carbon Loop (in which case
- * we will call RNE in the actual wait... */
+ int isMainLoop; /* Is this the main Carbon Loop (in which case
+ * we will call RNE in the actual wait... */
int onList; /* True if it is in this list */
unsigned int pollState; /* pollState is used to implement a polling
* handshake between each thread and the
* notifier thread. Bits defined below. */
struct ThreadSpecificData *nextPtr, *prevPtr;
- /* All threads that are currently waiting on
- * an event have their ThreadSpecificData
- * structure on a doubly-linked listed formed
- * from these pointers. You must hold the
- * notifierMutex lock before accessing these
- * fields. */
- Tcl_Condition waitCV; /* Any other thread alerts a notifier
+ /* All threads that are currently waiting on
+ * an event have their ThreadSpecificData
+ * structure on a doubly-linked listed formed
+ * from these pointers. You must hold the
+ * notifierMutex lock before accessing these
+ * fields. */
+ Tcl_Condition waitCV; /* Any other thread alerts a notifier
* that an event is ready to be processed
* by signaling this condition variable. */
- int eventReady; /* True if an event is ready to be processed.
- * Used as condition flag together with
- * waitCV above. */
+ int eventReady; /* True if an event is ready to be processed.
+ * Used as condition flag together with
+ * waitCV above. */
} ThreadSpecificData;
static Tcl_ThreadDataKey dataKey;
@@ -184,27 +184,29 @@ static Tcl_ThreadId notifierThread;
* Static routines defined in this file.
*/
-static void NotifierThreadProc _ANSI_ARGS_((ClientData clientData));
-static int FileHandlerEventProc _ANSI_ARGS_((Tcl_Event *evPtr,
- int flags));
-
-void TkMacOSXSetTimer(Tcl_Time *timePtr);
-void TkMacOSXCreateFileHandler(int fd, int mask, Tcl_FileProc *proc, ClientData clientData);
-void TkMacOSXDeleteFileHandler(int fd);
-int TkMacOSXWaitForEvent(Tcl_Time *timePtr);
-void TkMacOSXAlertNotifier(ClientData clientData);
-ClientData TkMacOSXInitNotifier();
-void TkMacOSXFinalizeNotifier(ClientData clientData);
-void TkMacOSXServiceModeHook(int mode);
-EventRef TkMacOSXCreateFakeEvent ();
+static void NotifierThreadProc(ClientData clientData);
+static int FileHandlerEventProc(Tcl_Event *evPtr, int flags);
+static void AlertNotifier(ThreadSpecificData *tsdPtr);
+
+/* DKF: Should these be static? */
+void TkMacOSXSetTimer(Tcl_Time *timePtr);
+void TkMacOSXCreateFileHandler(int fd, int mask, Tcl_FileProc *proc,
+ ClientData clientData);
+void TkMacOSXDeleteFileHandler(int fd);
+int TkMacOSXWaitForEvent(Tcl_Time *timePtr);
+void TkMacOSXAlertNotifier(ClientData clientData);
+ClientData TkMacOSXInitNotifier();
+void TkMacOSXFinalizeNotifier(ClientData clientData);
+void TkMacOSXServiceModeHook(int mode);
+EventRef TkMacOSXCreateFakeEvent();
/*
*----------------------------------------------------------------------
*
* Tk_MacOSXSetupTkNotifier --
*
* Replaces the Tcl notifier (from tclUnixNotfy.c) with
- * the Mac notifier that melds the Unix select based notifer
- * with the Carbon event handling side of the Tk notifier.
+ * the Mac notifier that melds the Unix select based notifer
+ * with the Carbon event handling side of the Tk notifier.
*
* Results:
* Replaces the notifier callbacks with MacOS X specific ones.
@@ -220,14 +222,14 @@ Tk_MacOSXSetupTkNotifier()
{
EventQueueRef mainEventQueue;
Tcl_NotifierProcs macNotifierProcs = {
- TkMacOSXSetTimer,
- TkMacOSXWaitForEvent,
- TkMacOSXCreateFileHandler,
- TkMacOSXDeleteFileHandler,
- TkMacOSXInitNotifier,
- TkMacOSXFinalizeNotifier,
- TkMacOSXAlertNotifier,
- TkMacOSXServiceModeHook
+ TkMacOSXSetTimer,
+ TkMacOSXWaitForEvent,
+ TkMacOSXCreateFileHandler,
+ TkMacOSXDeleteFileHandler,
+ TkMacOSXInitNotifier,
+ TkMacOSXFinalizeNotifier,
+ TkMacOSXAlertNotifier,
+ TkMacOSXServiceModeHook
};
/*
@@ -235,7 +237,7 @@ Tk_MacOSXSetupTkNotifier()
*/
TclFinalizeNotifier();
-
+
Tcl_SetNotifier(&macNotifierProcs);
/* HACK ALERT: There is a bug in Jaguar where when it goes to make
@@ -245,9 +247,9 @@ Tk_MacOSXSetupTkNotifier()
* the main thread. Calling GetMainEventQueue will force this to
* happen.
*/
-
+
mainEventQueue = GetMainEventQueue();
-
+
/*
* Tcl_SetNotifier doesn't call the TclInitNotifier
* so we call it now. If we don't do this the
@@ -288,16 +290,16 @@ TkMacOSXInitNotifier()
Tcl_MutexLock(&notifierMutex);
if (notifierCount == 0) {
if (Tcl_CreateThread(&notifierThread, NotifierThreadProc, NULL,
- TCL_THREAD_STACK_DEFAULT, TCL_THREAD_NOFLAGS) != TCL_OK) {
+ TCL_THREAD_STACK_DEFAULT, TCL_THREAD_NOFLAGS) != TCL_OK) {
Tcl_Panic("Tcl_InitNotifier: unable to start notifier thread");
}
}
notifierCount++;
-
+
if (GetCurrentEventLoop() == GetMainEventLoop()) {
- tsdPtr->isMainLoop = 1;
+ tsdPtr->isMainLoop = 1;
} else {
- tsdPtr->isMainLoop = 0;
+ tsdPtr->isMainLoop = 0;
}
/*
@@ -349,7 +351,7 @@ TkMacOSXFinalizeNotifier(clientData)
Tcl_Panic("Tcl_FinalizeNotifier: notifier pipe not initialized");
}
- /*
+ /*
* Send "q" message to the notifier thread so that it will
* terminate. The notifier will return from its call to select()
* and notice that a "q" message has arrived, it will then close
@@ -402,20 +404,49 @@ TkMacOSXAlertNotifier(clientData)
ThreadSpecificData *tsdPtr = (ThreadSpecificData *) clientData;
Tcl_MutexLock(&notifierMutex);
tsdPtr->eventReady = 1;
+ AlertNotifier(tsdPtr);
+ Tcl_MutexUnlock(&notifierMutex);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * AlertNotifier --
+ *
+ * The core of the notifier alerting scheme. Either we wake up
+ * the main event loop and stuff the event to it, or we signal
+ * the thread's condition variable. Note that callers are
+ * responsible for locking the right mutexes, managing the rest
+ * of the notifier state, etc. The thread to alert is determined
+ * by whose tsdPtr we actually have as our argument. The only
+ * expected callers are TkMacOSXAlertNotifier() and
+ * NotifierThreadProc(), both of which take appropriate
+ * precautions.
+ *
+ * Results:
+ * none
+ *
+ * Side effects:
+ * A notifier is alerted.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+AlertNotifier(tsdPtr)
+ ThreadSpecificData *tsdPtr;
+{
if (tsdPtr->isMainLoop) {
- OSErr err;
-
- /* We need to wake up the main loop, and let it have the event. */
- EventRef fakeEvent = TkMacOSXCreateFakeEvent();
- EventQueueRef mainEventQueue = GetMainEventQueue();
-
- err = PostEventToQueue(mainEventQueue, fakeEvent,
- kEventPriorityHigh);
- ReleaseEvent(fakeEvent);
+ /* We need to wake up the main loop, and let it have the event. */
+ EventRef fakeEvent = TkMacOSXCreateFakeEvent();
+ EventQueueRef mainEventQueue = GetMainEventQueue();
+ OSErr err;
+
+ err = PostEventToQueue(mainEventQueue, fakeEvent, kEventPriorityHigh);
+ ReleaseEvent(fakeEvent);
} else {
- Tcl_ConditionNotify(&tsdPtr->waitCV);
+ Tcl_ConditionNotify(&tsdPtr->waitCV);
}
- Tcl_MutexUnlock(&notifierMutex);
}
/*
@@ -445,7 +476,6 @@ TkMacOSXSetTimer(timePtr)
* because the only event loop is via Tcl_DoOneEvent, which passes
* timeout values to Tcl_WaitForEvent.
*/
-
}
/*
@@ -502,7 +532,7 @@ TkMacOSXCreateFileHandler(fd, mask, proc, clientData)
FileHandler *filePtr;
for (filePtr = tsdPtr->firstFileHandlerPtr; filePtr != NULL;
- filePtr = filePtr->nextPtr) {
+ filePtr = filePtr->nextPtr) {
if (filePtr->fd == fd) {
break;
}
@@ -522,20 +552,20 @@ TkMacOSXCreateFileHandler(fd, mask, proc, clientData)
* Update the check masks for this file.
*/
- if ( mask & TCL_READABLE ) {
- FD_SET( fd, &(tsdPtr->checkMasks.readable) );
+ if (mask & TCL_READABLE) {
+ FD_SET(fd, &(tsdPtr->checkMasks.readable));
} else {
- FD_CLR( fd, &(tsdPtr->checkMasks.readable) );
+ FD_CLR(fd, &(tsdPtr->checkMasks.readable));
}
- if ( mask & TCL_WRITABLE ) {
- FD_SET( fd, &(tsdPtr->checkMasks.writable) );
+ if (mask & TCL_WRITABLE) {
+ FD_SET(fd, &(tsdPtr->checkMasks.writable));
} else {
- FD_CLR( fd, &(tsdPtr->checkMasks.writable) );
+ FD_CLR(fd, &(tsdPtr->checkMasks.writable));
}
- if ( mask & TCL_EXCEPTION ) {
- FD_SET( fd, &(tsdPtr->checkMasks.exceptional) );
+ if (mask & TCL_EXCEPTION) {
+ FD_SET(fd, &(tsdPtr->checkMasks.exceptional));
} else {
- FD_CLR( fd, &(tsdPtr->checkMasks.exceptional) );
+ FD_CLR(fd, &(tsdPtr->checkMasks.exceptional));
}
if (tsdPtr->numFdBits <= fd) {
tsdPtr->numFdBits = fd+1;
@@ -586,13 +616,13 @@ TkMacOSXDeleteFileHandler(fd)
*/
if (filePtr->mask & TCL_READABLE) {
- FD_CLR( fd, &(tsdPtr->checkMasks.readable) );
+ FD_CLR(fd, &(tsdPtr->checkMasks.readable));
}
if (filePtr->mask & TCL_WRITABLE) {
- FD_CLR( fd, &(tsdPtr->checkMasks.writable) );
+ FD_CLR(fd, &(tsdPtr->checkMasks.writable));
}
if (filePtr->mask & TCL_EXCEPTION) {
- FD_CLR( fd, &(tsdPtr->checkMasks.exceptional) );
+ FD_CLR(fd, &(tsdPtr->checkMasks.exceptional));
}
/*
@@ -602,9 +632,9 @@ TkMacOSXDeleteFileHandler(fd)
if (fd+1 == tsdPtr->numFdBits) {
tsdPtr->numFdBits = 0;
for (i = fd-1; i >= 0; i--) {
- if ( FD_ISSET( i, &(tsdPtr->checkMasks.readable) )
- || FD_ISSET( i, &(tsdPtr->checkMasks.writable) )
- || FD_ISSET( i, &(tsdPtr->checkMasks.exceptional ) ) ) {
+ if (FD_ISSET(i, &(tsdPtr->checkMasks.readable))
+ || FD_ISSET(i, &(tsdPtr->checkMasks.writable))
+ || FD_ISSET(i, &(tsdPtr->checkMasks.exceptional))) {
tsdPtr->numFdBits = i+1;
break;
}
@@ -669,7 +699,7 @@ FileHandlerEventProc(evPtr, flags)
tsdPtr = TCL_TSD_INIT(&dataKey);
for (filePtr = tsdPtr->firstFileHandlerPtr; filePtr != NULL;
- filePtr = filePtr->nextPtr) {
+ filePtr = filePtr->nextPtr) {
if (filePtr->fd != fileEvPtr->fd) {
continue;
}
@@ -733,24 +763,24 @@ TkMacOSXWaitForEvent(timePtr)
* forever.
*/
- if (timePtr) {
+ if (timePtr != NULL) {
/* TIP #233 (Virtualized Time). Is virtual time in effect ?
* And do we actually have something to scale ? If yes to both
* then we call the handler to do this scaling */
- myTime.sec = timePtr->sec;
+ myTime.sec = timePtr->sec;
myTime.usec = timePtr->usec;
if (myTime.sec != 0 || myTime.usec != 0) {
- Tcl_ScaleTimeProc* tclScaleTimeProcPtr;
- ClientData tclTimeClientData;
- Tcl_QueryTimeProc(NULL, &tclScaleTimeProcPtr, &tclTimeClientData);
-
+ Tcl_ScaleTimeProc* tclScaleTimeProcPtr;
+ ClientData tclTimeClientData;
+
+ Tcl_QueryTimeProc(NULL, &tclScaleTimeProcPtr, &tclTimeClientData);
(*tclScaleTimeProcPtr) (&myTime, tclTimeClientData);
}
myTimePtr = &myTime;
} else {
- myTimePtr = NULL;
+ myTimePtr = NULL;
}
/*
@@ -778,46 +808,45 @@ TkMacOSXWaitForEvent(timePtr)
}
if (waitForFiles) {
- /*
- * Add the ThreadSpecificData structure of this thread to the list
- * of ThreadSpecificData structures of all threads that are waiting
- * on file events.
- */
-
-
- tsdPtr->nextPtr = waitingListPtr;
- if (waitingListPtr) {
- waitingListPtr->prevPtr = tsdPtr;
- }
- tsdPtr->prevPtr = 0;
- waitingListPtr = tsdPtr;
+ /*
+ * Add the ThreadSpecificData structure of this thread to the list
+ * of ThreadSpecificData structures of all threads that are waiting
+ * on file events.
+ */
+
+ tsdPtr->nextPtr = waitingListPtr;
+ if (waitingListPtr) {
+ waitingListPtr->prevPtr = tsdPtr;
+ }
+ tsdPtr->prevPtr = 0;
+ waitingListPtr = tsdPtr;
tsdPtr->onList = 1;
-
+
write(triggerPipe, "", 1);
}
- FD_ZERO( &(tsdPtr->readyMasks.readable) );
- FD_ZERO( &(tsdPtr->readyMasks.writable) );
- FD_ZERO( &(tsdPtr->readyMasks.exceptional) );
+ FD_ZERO(&(tsdPtr->readyMasks.readable));
+ FD_ZERO(&(tsdPtr->readyMasks.writable));
+ FD_ZERO(&(tsdPtr->readyMasks.exceptional));
if (!tsdPtr->eventReady) {
- if (!tsdPtr->isMainLoop) {
- Tcl_ConditionWait(&tsdPtr->waitCV, &notifierMutex, myTimePtr);
- } else {
- OSErr err;
- EventRef eventRef;
- EventTime waitTime;
-
- if (timePtr == NULL) {
- waitTime = kEventDurationForever;
- } else {
- waitTime = myTimePtr->sec * kEventDurationSecond
- + myTimePtr->usec * kEventDurationMicrosecond;
- }
- Tcl_MutexUnlock(&notifierMutex);
- err = ReceiveNextEvent(0, NULL, waitTime, false, &eventRef);
- Tcl_MutexLock(&notifierMutex);
- }
+ if (!tsdPtr->isMainLoop) {
+ Tcl_ConditionWait(&tsdPtr->waitCV, &notifierMutex, myTimePtr);
+ } else {
+ OSErr err;
+ EventRef eventRef;
+ EventTime waitTime;
+
+ if (myTimePtr == NULL) {
+ waitTime = kEventDurationForever;
+ } else {
+ waitTime = myTimePtr->sec * kEventDurationSecond
+ + myTimePtr->usec * kEventDurationMicrosecond;
+ }
+ Tcl_MutexUnlock(&notifierMutex);
+ err = ReceiveNextEvent(0, NULL, waitTime, false, &eventRef);
+ Tcl_MutexLock(&notifierMutex);
+ }
}
tsdPtr->eventReady = 0;
@@ -829,35 +858,34 @@ TkMacOSXWaitForEvent(timePtr)
* which the notifier thread was still doing a select on.
*/
- if (tsdPtr->prevPtr) {
- tsdPtr->prevPtr->nextPtr = tsdPtr->nextPtr;
- } else {
- waitingListPtr = tsdPtr->nextPtr;
- }
- if (tsdPtr->nextPtr) {
- tsdPtr->nextPtr->prevPtr = tsdPtr->prevPtr;
- }
- tsdPtr->nextPtr = tsdPtr->prevPtr = NULL;
+ if (tsdPtr->prevPtr) {
+ tsdPtr->prevPtr->nextPtr = tsdPtr->nextPtr;
+ } else {
+ waitingListPtr = tsdPtr->nextPtr;
+ }
+ if (tsdPtr->nextPtr) {
+ tsdPtr->nextPtr->prevPtr = tsdPtr->prevPtr;
+ }
+ tsdPtr->nextPtr = tsdPtr->prevPtr = NULL;
tsdPtr->onList = 0;
write(triggerPipe, "", 1);
}
-
/*
* Queue all detected file events before returning.
*/
for (filePtr = tsdPtr->firstFileHandlerPtr; (filePtr != NULL);
- filePtr = filePtr->nextPtr) {
+ filePtr = filePtr->nextPtr) {
mask = 0;
- if ( FD_ISSET( filePtr->fd, &(tsdPtr->readyMasks.readable) ) ) {
+ if (FD_ISSET(filePtr->fd, &(tsdPtr->readyMasks.readable))) {
mask |= TCL_READABLE;
}
- if ( FD_ISSET( filePtr->fd, &(tsdPtr->readyMasks.writable) ) ) {
+ if (FD_ISSET(filePtr->fd, &(tsdPtr->readyMasks.writable))) {
mask |= TCL_WRITABLE;
}
- if ( FD_ISSET( filePtr->fd, &(tsdPtr->readyMasks.exceptional) ) ) {
+ if (FD_ISSET(filePtr->fd, &(tsdPtr->readyMasks.exceptional))) {
mask |= TCL_EXCEPTION;
}
@@ -871,8 +899,7 @@ TkMacOSXWaitForEvent(timePtr)
*/
if (filePtr->readyMask == 0) {
- fileEvPtr = (FileHandlerEvent *) ckalloc(
- sizeof(FileHandlerEvent));
+ fileEvPtr = (FileHandlerEvent *) ckalloc(sizeof(FileHandlerEvent));
fileEvPtr->header.proc = FileHandlerEventProc;
fileEvPtr->fd = filePtr->fd;
Tcl_QueueEvent((Tcl_Event *) fileEvPtr, TCL_QUEUE_TAIL);
@@ -885,9 +912,9 @@ TkMacOSXWaitForEvent(timePtr)
* Also queue the Mac Events found...
*/
if (tsdPtr->isMainLoop) {
- TkMacOSXCountAndProcessMacEvents();
+ TkMacOSXCountAndProcessMacEvents();
}
-
+
return 0;
}
@@ -966,10 +993,9 @@ NotifierThreadProc(clientData)
*/
while (1) {
-
- FD_ZERO( &readableMask );
- FD_ZERO( &writableMask );
- FD_ZERO( &exceptionalMask );
+ FD_ZERO(&readableMask);
+ FD_ZERO(&writableMask);
+ FD_ZERO(&exceptionalMask);
/*
* Compute the logical OR of the select masks from all the
@@ -978,19 +1004,19 @@ NotifierThreadProc(clientData)
Tcl_MutexLock(&notifierMutex);
timePtr = NULL;
- for (tsdPtr = waitingListPtr; tsdPtr; tsdPtr = tsdPtr->nextPtr) {
- for ( i = tsdPtr->numFdBits-1; i >= 0; --i ) {
- if ( FD_ISSET( i, &(tsdPtr->checkMasks.readable) ) ) {
- FD_SET( i, &readableMask );
+ for (tsdPtr = waitingListPtr; tsdPtr; tsdPtr = tsdPtr->nextPtr) {
+ for (i = tsdPtr->numFdBits-1; i >= 0; --i) {
+ if (FD_ISSET(i, &(tsdPtr->checkMasks.readable))) {
+ FD_SET(i, &readableMask);
}
- if ( FD_ISSET( i, &(tsdPtr->checkMasks.writable) ) ) {
- FD_SET( i, &writableMask );
+ if (FD_ISSET(i, &(tsdPtr->checkMasks.writable))) {
+ FD_SET(i, &writableMask);
}
- if ( FD_ISSET( i, &(tsdPtr->checkMasks.exceptional) ) ) {
- FD_SET( i, &exceptionalMask );
+ if (FD_ISSET(i, &(tsdPtr->checkMasks.exceptional))) {
+ FD_SET(i, &exceptionalMask);
}
}
- if ( tsdPtr->numFdBits > numFdBits ) {
+ if (tsdPtr->numFdBits > numFdBits) {
numFdBits = tsdPtr->numFdBits;
}
if (tsdPtr->pollState & POLL_WANT) {
@@ -1009,48 +1035,48 @@ NotifierThreadProc(clientData)
* Set up the select mask to include the receive pipe.
*/
- if ( receivePipe >= numFdBits ) {
+ if (receivePipe >= numFdBits) {
numFdBits = receivePipe + 1;
}
- FD_SET( receivePipe, &readableMask );
+ FD_SET(receivePipe, &readableMask);
- if ( select( numFdBits, &readableMask, &writableMask,
- &exceptionalMask, timePtr) == -1 ) {
+ if (select(numFdBits, &readableMask, &writableMask, &exceptionalMask,
+ timePtr) == -1) {
/*
* Try again immediately on an error.
*/
continue;
- }
+ }
/*
* Alert any threads that are waiting on a ready file descriptor.
*/
Tcl_MutexLock(&notifierMutex);
- for (tsdPtr = waitingListPtr; tsdPtr; tsdPtr = tsdPtr->nextPtr) {
+ for (tsdPtr = waitingListPtr; tsdPtr; tsdPtr = tsdPtr->nextPtr) {
found = 0;
- for ( i = tsdPtr->numFdBits-1; i >= 0; --i ) {
- if ( FD_ISSET( i, &(tsdPtr->checkMasks.readable) )
- && FD_ISSET( i, &readableMask ) ) {
- FD_SET( i, &(tsdPtr->readyMasks.readable) );
+ for (i = tsdPtr->numFdBits-1; i >= 0; --i) {
+ if (FD_ISSET(i, &(tsdPtr->checkMasks.readable))
+ && FD_ISSET(i, &readableMask)) {
+ FD_SET(i, &(tsdPtr->readyMasks.readable));
found = 1;
}
- if ( FD_ISSET( i, &(tsdPtr->checkMasks.writable) )
- && FD_ISSET( i, &writableMask ) ) {
- FD_SET( i, &(tsdPtr->readyMasks.writable) );
+ if (FD_ISSET(i, &(tsdPtr->checkMasks.writable))
+ && FD_ISSET(i, &writableMask)) {
+ FD_SET(i, &(tsdPtr->readyMasks.writable));
found = 1;
}
- if ( FD_ISSET( i, &(tsdPtr->checkMasks.exceptional) )
- && FD_ISSET( i, &exceptionalMask ) ) {
- FD_SET( i, &(tsdPtr->readyMasks.exceptional) );
+ if (FD_ISSET(i, &(tsdPtr->checkMasks.exceptional))
+ && FD_ISSET(i, &exceptionalMask)) {
+ FD_SET(i, &(tsdPtr->readyMasks.exceptional));
found = 1;
}
}
-
- if (found || (tsdPtr->pollState & POLL_DONE)) {
- tsdPtr->eventReady = 1;
+
+ if (found || (tsdPtr->pollState & POLL_DONE)) {
+ tsdPtr->eventReady = 1;
if (tsdPtr->onList) {
/*
* Remove the ThreadSpecificData structure of this
@@ -1058,7 +1084,7 @@ NotifierThreadProc(clientData)
* continuously spining on select until the other
* threads runs and services the file event.
*/
-
+
if (tsdPtr->prevPtr) {
tsdPtr->prevPtr->nextPtr = tsdPtr->nextPtr;
} else {
@@ -1071,30 +1097,18 @@ NotifierThreadProc(clientData)
tsdPtr->onList = 0;
tsdPtr->pollState = 0;
}
- if (tsdPtr->isMainLoop) {
- OSErr err;
-
- /* We need to wake up the main loop, and let it have the event. */
- EventRef fakeEvent = TkMacOSXCreateFakeEvent();
- EventQueueRef mainEventQueue = GetMainEventQueue();
-
- err = PostEventToQueue(mainEventQueue, fakeEvent,
- kEventPriorityHigh);
- ReleaseEvent(fakeEvent);
- } else {
- Tcl_ConditionNotify(&tsdPtr->waitCV);
- }
- }
- }
+ AlertNotifier(tsdPtr);
+ }
+ }
Tcl_MutexUnlock(&notifierMutex);
-
+
/*
* Consume the next byte from the notifier pipe if the pipe was
* readable. Note that there may be multiple bytes pending, but
* to avoid a race condition we only read one at a time.
*/
- if ( FD_ISSET( receivePipe, &readableMask ) ) {
+ if (FD_ISSET(receivePipe, &readableMask)) {
i = read(receivePipe, buf, 1);
if ((i == 0) || ((i == 1) && (buf[0] == 'q'))) {
@@ -1120,23 +1134,25 @@ NotifierThreadProc(clientData)
Tcl_ConditionNotify(&notifierCV);
Tcl_MutexUnlock(&notifierMutex);
- Tcl_ExitThread (0);
+ Tcl_ExitThread(0);
}
-
+
EventRef
-TkMacOSXCreateFakeEvent ()
+TkMacOSXCreateFakeEvent()
{
- EventKind eKind;
- EventClass eClass;
- EventTime eTime;
- EventRef eventRef;
+ EventKind eKind;
+ EventClass eClass;
+ EventTime eTime;
+ EventRef eventRef;
EventAttributes flags;
+
eClass = kEventClassWish;
eKind = 0xffff;
eTime = GetLastUserEventTime() + 0.001;
flags = kEventAttributeUserEvent;
if (CreateEvent(NULL,eClass,eKind,eTime,flags,&eventRef) != noErr) {
- fprintf(stderr,"CreateEvent failed\n");
+ /* DKF: Printing to stderr? Leaked debug code here? */
+ fprintf(stderr, "CreateEvent failed\n");
return NULL;
}
return eventRef;