diff options
author | das <das> | 2006-08-21 01:08:03 (GMT) |
---|---|---|
committer | das <das> | 2006-08-21 01:08:03 (GMT) |
commit | d70383944a28777ea679b1e1b4be38c2a42b3960 (patch) | |
tree | 1444f5611d45b011b9c6802f90b77083be59435f /macosx/tclMacOSXNotify.c | |
parent | c8aa816f783a31a2a7a3315813d563c83a73a5d1 (diff) | |
download | tcl-d70383944a28777ea679b1e1b4be38c2a42b3960.zip tcl-d70383944a28777ea679b1e1b4be38c2a42b3960.tar.gz tcl-d70383944a28777ea679b1e1b4be38c2a42b3960.tar.bz2 |
* macosx/tclMacOSXNotify.c (Tcl_WaitForEvent): if the run loop is
already running (e.g. if Tcl_WaitForEvent was called recursively),
re-run it in a custom run loop mode containing only the source for the
notifier thread, otherwise wakeups from other sources added to the
common run loop modes might get lost.
* unix/tclUnixNotfy.c (Tcl_WaitForEvent): on 64-bit Darwin,
pthread_cond_timedwait() appears to have a bug that causes it to wait
forever when passed an absolute time which has already been exceeded by
the system time; as a workaround, when given a very brief timeout, just
do a poll on that platform. [Bug 1457797]
Diffstat (limited to 'macosx/tclMacOSXNotify.c')
-rw-r--r-- | macosx/tclMacOSXNotify.c | 26 |
1 files changed, 24 insertions, 2 deletions
diff --git a/macosx/tclMacOSXNotify.c b/macosx/tclMacOSXNotify.c index 6dfb379..73b1c92 100644 --- a/macosx/tclMacOSXNotify.c +++ b/macosx/tclMacOSXNotify.c @@ -13,7 +13,7 @@ * See the file "license.terms" for information on usage and redistribution of * this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tclMacOSXNotify.c,v 1.9 2006/08/10 12:15:32 dkf Exp $ + * RCS: @(#) $Id: tclMacOSXNotify.c,v 1.10 2006/08/21 01:08:03 das Exp $ */ #include "tclInt.h" @@ -237,6 +237,14 @@ static OSSpinLock notifierLock = 0; static pthread_t notifierThread; /* + * Custom run loop mode containing only the run loop source for the + * notifier thread. + */ + +static const CFStringRef tclEventsOnlyRunLoopMode = + CFSTR("com.tcltk.tclEventsOnlyRunLoopMode"); + +/* * Static routines defined in this file. */ @@ -304,6 +312,7 @@ Tcl_InitNotifier(void) Tcl_Panic("Tcl_InitNotifier: could not create CFRunLoopSource"); } CFRunLoopAddSource(runLoop, runLoopSource, kCFRunLoopCommonModes); + CFRunLoopAddSource(runLoop, runLoopSource, tclEventsOnlyRunLoopMode); tsdPtr->runLoopSource = runLoopSource; tsdPtr->runLoop = runLoop; } @@ -897,14 +906,27 @@ Tcl_WaitForEvent( if (!tsdPtr->eventReady) { CFTimeInterval waitTime; + CFStringRef runLoopMode; if (myTimePtr == NULL) { waitTime = 1.0e10; /* Wait forever, as per CFRunLoop.c */ } else { waitTime = myTimePtr->sec + 1.0e-6 * myTimePtr->usec; } + /* + * If the run loop is already running (e.g. if Tcl_WaitForEvent was + * called recursively), re-run it in a custom run loop mode containing + * only the source for the notifier thread, otherwise wakeups from other + * sources added to the common run loop modes might get lost. + */ + if ((runLoopMode = CFRunLoopCopyCurrentMode(tsdPtr->runLoop))) { + CFRelease(runLoopMode); + runLoopMode = tclEventsOnlyRunLoopMode; + } else { + runLoopMode = kCFRunLoopDefaultMode; + } UNLOCK_NOTIFIER; - CFRunLoopRunInMode(kCFRunLoopDefaultMode, waitTime, TRUE); + CFRunLoopRunInMode(runLoopMode, waitTime, TRUE); LOCK_NOTIFIER; } tsdPtr->eventReady = 0; |