summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog22
-rw-r--r--macosx/tclMacOSXNotify.c26
-rw-r--r--unix/tclUnixNotfy.c14
3 files changed, 58 insertions, 4 deletions
diff --git a/ChangeLog b/ChangeLog
index 3debe51..662137d 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,25 @@
+2006-08-21 Daniel Steffen <das@users.sourceforge.net>
+
+ * 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]
+
+ * generic/tclClock.c (ClockClicksObjCmd): add support for Darwin
+ * generic/tclCmdMZ.c (Tcl_TimeObjCmd): nanosecond resolution timer
+ * generic/tclInt.h: to [clock clicks] and [time]
+ * unix/configure.in (Darwin): when TCL_WIDE_CLICKS defined.
+ * unix/tclUnixTime.c (TclpGetWideClicks, TclpWideClicksToNanoseconds):
+ * unix/configure: autoconf-2.59
+ * unix/tclConfig.h.in: autoheader-2.59
+
2006-08-18 Daniel Steffen <das@users.sourceforge.net>
* unix/tcl.m4 (Darwin): add support for --enable-64bit on x86_64, for
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;
diff --git a/unix/tclUnixNotfy.c b/unix/tclUnixNotfy.c
index 0a405ce..2574015 100644
--- a/unix/tclUnixNotfy.c
+++ b/unix/tclUnixNotfy.c
@@ -10,7 +10,7 @@
* See the file "license.terms" for information on usage and redistribution of
* this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * RCS: @(#) $Id: tclUnixNotfy.c,v 1.31 2006/08/10 12:15:32 dkf Exp $
+ * RCS: @(#) $Id: tclUnixNotfy.c,v 1.32 2006/08/21 01:08:03 das Exp $
*/
#include "tclInt.h"
@@ -740,7 +740,17 @@ Tcl_WaitForEvent(
Tcl_MutexLock(&notifierMutex);
waitForFiles = (tsdPtr->numFdBits > 0);
- if (myTimePtr != NULL && myTimePtr->sec == 0 && myTimePtr->usec == 0) {
+ if (myTimePtr != NULL && myTimePtr->sec == 0 && (myTimePtr->usec == 0
+#if defined(__APPLE__) && defined(__LP64__)
+ /*
+ * 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. [Bug 1457797]
+ */
+ || myTimePtr->usec < 10
+#endif
+ )) {
/*
* Cannot emulate a polling select with a polling condition variable.
* Instead, pretend to wait for files and tell the notifier thread