summaryrefslogtreecommitdiffstats
path: root/unix/tclUnixNotfy.c
diff options
context:
space:
mode:
Diffstat (limited to 'unix/tclUnixNotfy.c')
-rw-r--r--unix/tclUnixNotfy.c175
1 files changed, 96 insertions, 79 deletions
diff --git a/unix/tclUnixNotfy.c b/unix/tclUnixNotfy.c
index ca95f40..b87af1b 100644
--- a/unix/tclUnixNotfy.c
+++ b/unix/tclUnixNotfy.c
@@ -96,7 +96,7 @@ typedef struct ThreadSpecificData {
* that an event is ready to be processed
* by sending this event. */
void *hwnd; /* Messaging window. */
-#else /* !__CYGWIN__ */
+#else
Tcl_Condition waitCV; /* Any other thread alerts a notifier that an
* event is ready to be processed by signaling
* this condition variable. */
@@ -104,7 +104,7 @@ typedef struct ThreadSpecificData {
int eventReady; /* True if an event is ready to be processed.
* Used as condition flag together with waitCV
* above. */
-#endif
+#endif /* TCL_THREADS */
} ThreadSpecificData;
static Tcl_ThreadDataKey dataKey;
@@ -187,25 +187,12 @@ static Tcl_ThreadId notifierThread;
static void NotifierThreadProc(ClientData clientData);
#endif
static int FileHandlerEventProc(Tcl_Event *evPtr, int flags);
-
+
/*
- *----------------------------------------------------------------------
- *
- * Tcl_InitNotifier --
- *
- * Initializes the platform specific notifier state.
- *
- * Results:
- * Returns a handle to the notifier state for this thread.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------
+ * Import of Windows API when building threaded with Cygwin.
*/
#if defined(TCL_THREADS) && defined(__CYGWIN__)
-
typedef struct {
void *hwnd;
unsigned int *message;
@@ -217,34 +204,60 @@ typedef struct {
} MSG;
typedef struct {
- unsigned int style;
- void *lpfnWndProc;
- int cbClsExtra;
- int cbWndExtra;
- void *hInstance;
- void *hIcon;
- void *hCursor;
- void *hbrBackground;
- void *lpszMenuName;
- void *lpszClassName;
+ unsigned int style;
+ void *lpfnWndProc;
+ int cbClsExtra;
+ int cbWndExtra;
+ void *hInstance;
+ void *hIcon;
+ void *hCursor;
+ void *hbrBackground;
+ void *lpszMenuName;
+ void *lpszClassName;
} WNDCLASS;
-extern unsigned char __stdcall PeekMessageW(MSG *, void *, int, int, int);
-extern unsigned char __stdcall GetMessageW(MSG *, void *, int, int);
-extern unsigned char __stdcall TranslateMessage(const MSG *);
-extern int __stdcall DispatchMessageW(const MSG *);
-extern void __stdcall PostQuitMessage(int);
-extern void * __stdcall CreateWindowExW(void *, void *, void *, DWORD, int, int, int, int, void *, void *, void *, void *);
-extern unsigned char __stdcall DestroyWindow(void *);
-extern unsigned char __stdcall PostMessageW(void *, unsigned int, void *, void *);
-extern void *__stdcall RegisterClassW(const WNDCLASS *);
-extern DWORD __stdcall DefWindowProcW(void *, int, void *, void *);
-extern void *__stdcall CreateEventW(void *, unsigned char, unsigned char, void *);
-extern void __stdcall CloseHandle(void *);
-extern void __stdcall MsgWaitForMultipleObjects(DWORD, void *, unsigned char, DWORD, DWORD);
-extern unsigned char __stdcall ResetEvent(void *);
+extern void __stdcall CloseHandle(void *);
+extern void *__stdcall CreateEventW(void *, unsigned char, unsigned char,
+ void *);
+extern void * __stdcall CreateWindowExW(void *, void *, void *, DWORD, int,
+ int, int, int, void *, void *, void *, void *);
+extern DWORD __stdcall DefWindowProcW(void *, int, void *, void *);
+extern unsigned char __stdcall DestroyWindow(void *);
+extern int __stdcall DispatchMessageW(const MSG *);
+extern unsigned char __stdcall GetMessageW(MSG *, void *, int, int);
+extern void __stdcall MsgWaitForMultipleObjects(DWORD, void *,
+ unsigned char, DWORD, DWORD);
+extern unsigned char __stdcall PeekMessageW(MSG *, void *, int, int, int);
+extern unsigned char __stdcall PostMessageW(void *, unsigned int, void *,
+ void *);
+extern void __stdcall PostQuitMessage(int);
+extern void *__stdcall RegisterClassW(const WNDCLASS *);
+extern unsigned char __stdcall ResetEvent(void *);
+extern unsigned char __stdcall TranslateMessage(const MSG *);
-#endif
+/*
+ * Threaded-cygwin specific functions in this file:
+ */
+
+static DWORD __stdcall NotifierProc(void *hwnd, unsigned int message,
+ void *wParam, void *lParam);
+#endif /* TCL_THREADS && __CYGWIN__ */
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_InitNotifier --
+ *
+ * Initializes the platform specific notifier state.
+ *
+ * Results:
+ * Returns a handle to the notifier state for this thread.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
ClientData
Tcl_InitNotifier(void)
@@ -403,11 +416,11 @@ Tcl_AlertNotifier(
Tcl_MutexLock(&notifierMutex);
tsdPtr->eventReady = 1;
-#ifdef __CYGWIN__
+# ifdef __CYGWIN__
PostMessageW(tsdPtr->hwnd, 1024, 0, 0);
-#else
+# else
Tcl_ConditionNotify(&tsdPtr->waitCV);
-#endif
+# endif /* __CYGWIN__ */
Tcl_MutexUnlock(&notifierMutex);
#endif /* TCL_THREADS */
}
@@ -732,12 +745,12 @@ NotifierProc(
* Process all of the runnable events.
*/
- tsdPtr->eventReady = 1;
+ tsdPtr->eventReady = 1;
Tcl_ServiceAll();
return 0;
}
-#endif /* __CYGWIN__ */
-
+#endif /* TCL_THREADS && __CYGWIN__ */
+
/*
*----------------------------------------------------------------------
*
@@ -768,9 +781,9 @@ Tcl_WaitForEvent(
Tcl_Time vTime;
#ifdef TCL_THREADS
int waitForFiles;
-# ifdef __CYGWIN__
- MSG msg;
-# endif
+# ifdef __CYGWIN__
+ MSG msg;
+# endif /* __CYGWIN__ */
#else
/*
* Impl. notes: timeout & timeoutPtr are used if, and only if threads
@@ -792,8 +805,8 @@ Tcl_WaitForEvent(
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.
+ * we actually have something to scale? If yes to both then we
+ * call the handler to do this scaling.
*/
if (timePtr->sec != 0 || timePtr->usec != 0) {
@@ -807,17 +820,17 @@ Tcl_WaitForEvent(
timeoutPtr = &timeout;
} else if (tsdPtr->numFdBits == 0) {
/*
- * If there are no threads, no timeout, and no fds registered, then
- * there are no events possible and we must avoid deadlock. Note
- * that this is not entirely correct because there might be a
- * signal that could interrupt the select call, but we don't handle
- * that case if we aren't using threads.
+ * If there are no threads, no timeout, and no fds registered,
+ * then there are no events possible and we must avoid deadlock.
+ * Note that this is not entirely correct because there might be a
+ * signal that could interrupt the select call, but we don't
+ * handle that case if we aren't using threads.
*/
return -1;
} else {
timeoutPtr = NULL;
-#endif /* TCL_THREADS */
+#endif /* !TCL_THREADS */
}
#ifdef TCL_THREADS
@@ -828,7 +841,7 @@ Tcl_WaitForEvent(
#ifdef __CYGWIN__
if (!tsdPtr->hwnd) {
- WNDCLASS class;
+ WNDCLASS class;
class.style = 0;
class.cbClsExtra = 0;
@@ -842,24 +855,24 @@ Tcl_WaitForEvent(
class.hCursor = NULL;
RegisterClassW(&class);
- tsdPtr->hwnd = CreateWindowExW(NULL, class.lpszClassName, class.lpszClassName,
- 0, 0, 0, 0, 0, NULL, NULL, TclWinGetTclInstance(), NULL);
+ tsdPtr->hwnd = CreateWindowExW(NULL, class.lpszClassName,
+ class.lpszClassName, 0, 0, 0, 0, 0, NULL, NULL,
+ TclWinGetTclInstance(), NULL);
tsdPtr->event = CreateEventW(NULL, 1 /* manual */,
0 /* !signaled */, NULL);
- }
-
-#endif
+ }
+#endif /* __CYGWIN */
Tcl_MutexLock(&notifierMutex);
if (timePtr != NULL && timePtr->sec == 0 && (timePtr->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]
+ * 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]
*/
|| timePtr->usec < 10
#endif /* __APPLE__ && __LP64__ */
@@ -883,8 +896,8 @@ Tcl_WaitForEvent(
if (waitForFiles) {
/*
* Add the ThreadSpecificData structure of this thread to the list
- * of ThreadSpecificData structures of all threads that are waiting
- * on file events.
+ * of ThreadSpecificData structures of all threads that are
+ * waiting on file events.
*/
tsdPtr->nextPtr = waitingListPtr;
@@ -909,6 +922,7 @@ Tcl_WaitForEvent(
#ifdef __CYGWIN__
if (!PeekMessageW(&msg, NULL, 0, 0, 0)) {
DWORD timeout;
+
if (timePtr) {
timeout = timePtr->sec * 1000 + timePtr->usec / 1000;
} else {
@@ -920,7 +934,7 @@ Tcl_WaitForEvent(
}
#else
Tcl_ConditionWait(&tsdPtr->waitCV, &notifierMutex, timePtr);
-#endif
+#endif /* __CYGWIN__ */
}
tsdPtr->eventReady = 0;
@@ -929,17 +943,20 @@ Tcl_WaitForEvent(
/*
* Retrieve and dispatch the message.
*/
+
DWORD result = GetMessageW(&msg, NULL, 0, 0);
+
if (result == 0) {
PostQuitMessage(msg.wParam);
/* What to do here? */
- } else if (result != (DWORD)-1) {
+ } else if (result != (DWORD) -1) {
TranslateMessage(&msg);
DispatchMessageW(&msg);
}
}
ResetEvent(tsdPtr->event);
-#endif
+#endif /* __CYGWIN__ */
+
if (waitForFiles && tsdPtr->onList) {
/*
* Remove the ThreadSpecificData structure of this thread from the
@@ -1211,9 +1228,9 @@ NotifierThreadProc(
tsdPtr->pollState = 0;
}
#ifdef __CYGWIN__
- PostMessageW(tsdPtr->hwnd, 1024, 0, 0);
-#else /* __CYGWIN__ */
- Tcl_ConditionNotify(&tsdPtr->waitCV);
+ PostMessageW(tsdPtr->hwnd, 1024, 0, 0);
+#else
+ Tcl_ConditionNotify(&tsdPtr->waitCV);
#endif /* __CYGWIN__ */
}
}
@@ -1255,7 +1272,7 @@ NotifierThreadProc(
}
#endif /* TCL_THREADS */
-#endif /* HAVE_COREFOUNDATION */
+#endif /* !HAVE_COREFOUNDATION */
/*
* Local Variables: