Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | [Bug 3508771]: Cygwin notifier for handling win32 events |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | descendants | both | core-8-5-branch |
Files: | files | file ages | folders |
SHA1: |
b14932f43b3c05183e965122071266a0 |
User & Date: | jan.nijtmans 2012-06-23 07:10:06 |
Context
2012-06-24
| ||
06:00 | some wrong versions check-in: eefe38655e user: jan.nijtmans tags: core-8-5-branch | |
2012-06-23
| ||
07:27 | [Bug 3508771]: Cygwin notifier for handling win32 events check-in: eb701a2be1 user: jan.nijtmans tags: trunk | |
07:10 | [Bug 3508771]: Cygwin notifier for handling win32 events check-in: b14932f43b user: jan.nijtmans tags: core-8-5-branch | |
06:59 | [Bug 3508771]: Cygwin notifier for handling win32 events check-in: 0741b45cd7 user: jan.nijtmans tags: core-8-4-branch | |
2012-06-22
| ||
18:38 | FilesystemRecord structs no longer need refcounting. check-in: 8e03b0f1c9 user: dgp tags: core-8-5-branch | |
Changes
Changes to ChangeLog.
1 2 3 4 5 6 7 | 2012-06-21 Jan Nijtmans <[email protected]> * win/tclWinReg.c: [Bug #3362446]: registry keys command fails * tests/registry.test: with 8.5/8.6 * library/reg/pkgIndex.tcl: registry version to 1.2.2 2012-06-11 Don Porter <[email protected]> | > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 | 2012-06-23 Jan Nijtmans <[email protected]> * unix/tclUnixNotfy.c: [Bug 3508771]: Cygwin notifier for handling win32 events. 2012-06-21 Jan Nijtmans <[email protected]> * win/tclWinReg.c: [Bug #3362446]: registry keys command fails * tests/registry.test: with 8.5/8.6 * library/reg/pkgIndex.tcl: registry version to 1.2.2 2012-06-11 Don Porter <[email protected]> |
︙ | ︙ |
Changes to unix/configure.
︙ | ︙ | |||
6996 6997 6998 6999 7000 7001 7002 7003 7004 7005 7006 7007 7008 7009 | fi echo "$as_me:$LINENO: result: $ac_cv_cygwin" >&5 echo "${ECHO_T}$ac_cv_cygwin" >&6 if test "$ac_cv_cygwin" = "no"; then { { echo "$as_me:$LINENO: error: ${CC} is not a cygwin compiler." >&5 echo "$as_me: error: ${CC} is not a cygwin compiler." >&2;} { (exit 1); exit 1; }; } fi ;; dgux*) SHLIB_CFLAGS="-K PIC" SHLIB_LD='${CC} -G' SHLIB_LD_LIBS="" SHLIB_SUFFIX=".so" | > > > > > > > > > > | 6996 6997 6998 6999 7000 7001 7002 7003 7004 7005 7006 7007 7008 7009 7010 7011 7012 7013 7014 7015 7016 7017 7018 7019 | fi echo "$as_me:$LINENO: result: $ac_cv_cygwin" >&5 echo "${ECHO_T}$ac_cv_cygwin" >&6 if test "$ac_cv_cygwin" = "no"; then { { echo "$as_me:$LINENO: error: ${CC} is not a cygwin compiler." >&5 echo "$as_me: error: ${CC} is not a cygwin compiler." >&2;} { (exit 1); exit 1; }; } fi if test "x${TCL_THREADS}" = "x0"; then { { echo "$as_me:$LINENO: error: CYGWIN compile is only supported with --enable-threads" >&5 echo "$as_me: error: CYGWIN compile is only supported with --enable-threads" >&2;} { (exit 1); exit 1; }; } fi if test ! -f "../win/tcldde12.dll" -a ! -f "../win/tk84.dll"; then { { echo "$as_me:$LINENO: error: Please configure and make the ../win directory first." >&5 echo "$as_me: error: Please configure and make the ../win directory first." >&2;} { (exit 1); exit 1; }; } fi ;; dgux*) SHLIB_CFLAGS="-K PIC" SHLIB_LD='${CC} -G' SHLIB_LD_LIBS="" SHLIB_SUFFIX=".so" |
︙ | ︙ |
Changes to unix/tcl.m4.
︙ | ︙ | |||
1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 | ], [], ac_cv_cygwin=no, ac_cv_cygwin=yes) ) if test "$ac_cv_cygwin" = "no"; then AC_MSG_ERROR([${CC} is not a cygwin compiler.]) fi ;; dgux*) SHLIB_CFLAGS="-K PIC" SHLIB_LD='${CC} -G' SHLIB_LD_LIBS="" SHLIB_SUFFIX=".so" DL_OBJS="tclLoadDl.o" | > > > > > > | 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 | ], [], ac_cv_cygwin=no, ac_cv_cygwin=yes) ) if test "$ac_cv_cygwin" = "no"; then AC_MSG_ERROR([${CC} is not a cygwin compiler.]) fi if test "x${TCL_THREADS}" = "x0"; then AC_MSG_ERROR([CYGWIN compile is only supported with --enable-threads]) fi if test ! -f "../win/tcldde12.dll" -a ! -f "../win/tk84.dll"; then AC_MSG_ERROR([Please configure and make the ../win directory first.]) fi ;; dgux*) SHLIB_CFLAGS="-K PIC" SHLIB_LD='${CC} -G' SHLIB_LD_LIBS="" SHLIB_SUFFIX=".so" DL_OBJS="tclLoadDl.o" |
︙ | ︙ |
Changes to unix/tclUnixNotfy.c.
︙ | ︙ | |||
95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 | 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 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. */ #endif } ThreadSpecificData; static Tcl_ThreadDataKey dataKey; | > > > > > > > | 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 | 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. */ #ifdef __CYGWIN__ void *event; /* Any other thread alerts a notifier * that an event is ready to be processed * by sending this event. */ void *hwnd; /* Messaging window. */ #else /* !__CYGWIN__ */ Tcl_Condition waitCV; /* Any other thread alerts a notifier that an * event is ready to be processed by signaling * this condition variable. */ #endif /* __CYGWIN__ */ int eventReady; /* True if an event is ready to be processed. * Used as condition flag together with waitCV * above. */ #endif } ThreadSpecificData; static Tcl_ThreadDataKey dataKey; |
︙ | ︙ | |||
200 201 202 203 204 205 206 207 208 209 210 211 212 213 | * Returns a handle to the notifier state for this thread. * * Side effects: * None. * *---------------------------------------------------------------------- */ ClientData Tcl_InitNotifier(void) { ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); #ifdef TCL_THREADS | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 | * Returns a handle to the notifier state for this thread. * * Side effects: * None. * *---------------------------------------------------------------------- */ #if defined(TCL_THREADS) && defined(__CYGWIN__) typedef struct { void *hwnd; unsigned int *message; int wParam; int lParam; int time; int x; int y; } MSG; typedef struct { 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 *); #endif ClientData Tcl_InitNotifier(void) { ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); #ifdef TCL_THREADS |
︙ | ︙ | |||
304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 | } } /* * Clean up any synchronization objects in the thread local storage. */ Tcl_ConditionFinalize(&(tsdPtr->waitCV)); Tcl_MutexUnlock(¬ifierMutex); #endif } /* *---------------------------------------------------------------------- | > > > > | 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 | } } /* * Clean up any synchronization objects in the thread local storage. */ #ifdef __CYGWIN__ CloseHandle(tsdPtr->event); #else /* __CYGWIN__ */ Tcl_ConditionFinalize(&(tsdPtr->waitCV)); #endif /* __CYGWIN__ */ Tcl_MutexUnlock(¬ifierMutex); #endif } /* *---------------------------------------------------------------------- |
︙ | ︙ | |||
337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 | Tcl_AlertNotifier( ClientData clientData) { #ifdef TCL_THREADS ThreadSpecificData *tsdPtr = (ThreadSpecificData *) clientData; Tcl_MutexLock(¬ifierMutex); tsdPtr->eventReady = 1; Tcl_ConditionNotify(&tsdPtr->waitCV); Tcl_MutexUnlock(¬ifierMutex); #endif } /* *---------------------------------------------------------------------- * | > > > > | 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 | Tcl_AlertNotifier( ClientData clientData) { #ifdef TCL_THREADS ThreadSpecificData *tsdPtr = (ThreadSpecificData *) clientData; Tcl_MutexLock(¬ifierMutex); tsdPtr->eventReady = 1; #ifdef __CYGWIN__ PostMessageW(tsdPtr->hwnd, 1024, 0, 0); #else Tcl_ConditionNotify(&tsdPtr->waitCV); #endif Tcl_MutexUnlock(¬ifierMutex); #endif } /* *---------------------------------------------------------------------- * |
︙ | ︙ | |||
637 638 639 640 641 642 643 644 645 646 647 648 649 650 | (*filePtr->proc)(filePtr->clientData, mask); } break; } return 1; } /* *---------------------------------------------------------------------- * * Tcl_WaitForEvent -- * * This function is called by Tcl_DoOneEvent to wait for new events on * the message queue. If the block time is 0, then Tcl_WaitForEvent just | > > > > > > > > > > > > > > > > > > > > > > > > > | 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 | (*filePtr->proc)(filePtr->clientData, mask); } break; } return 1; } #if defined(TCL_THREADS) && defined(__CYGWIN__) static DWORD __stdcall NotifierProc( void *hwnd, unsigned int message, void *wParam, void *lParam) { ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); if (message != 1024) { return DefWindowProcW(hwnd, message, wParam, lParam); } /* * Process all of the runnable events. */ tsdPtr->eventReady = 1; Tcl_ServiceAll(); return 0; } #endif /* __CYGWIN__ */ /* *---------------------------------------------------------------------- * * Tcl_WaitForEvent -- * * This function is called by Tcl_DoOneEvent to wait for new events on * the message queue. If the block time is 0, then Tcl_WaitForEvent just |
︙ | ︙ | |||
665 666 667 668 669 670 671 672 673 674 675 676 677 678 | { FileHandler *filePtr; FileHandlerEvent *fileEvPtr; int mask; Tcl_Time vTime; #ifdef TCL_THREADS int waitForFiles; #else /* * Impl. notes: timeout & timeoutPtr are used if, and only if threads are * not enabled. They are the arguments for the regular select() used when * the core is not thread-enabled. */ | > > > | 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 | { FileHandler *filePtr; FileHandlerEvent *fileEvPtr; int mask; Tcl_Time vTime; #ifdef TCL_THREADS int waitForFiles; # ifdef __CYGWIN__ MSG msg; # endif #else /* * Impl. notes: timeout & timeoutPtr are used if, and only if threads are * not enabled. They are the arguments for the regular select() used when * the core is not thread-enabled. */ |
︙ | ︙ | |||
752 753 754 755 756 757 758 759 760 761 762 763 764 765 | tsdPtr->pollState = POLL_WANT; timePtr = NULL; } else { waitForFiles = (tsdPtr->numFdBits > 0); tsdPtr->pollState = 0; } if (waitForFiles) { /* * Add the ThreadSpecificData structure of this thread to the list of * ThreadSpecificData structures of all threads that are waiting on * file events. */ | > > > > > > > > > > > > > > > > > > > > > > > | 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 | tsdPtr->pollState = POLL_WANT; timePtr = NULL; } else { waitForFiles = (tsdPtr->numFdBits > 0); tsdPtr->pollState = 0; } #ifdef __CYGWIN__ if (!tsdPtr->hwnd) { WNDCLASS class; class.style = 0; class.cbClsExtra = 0; class.cbWndExtra = 0; class.hInstance = TclWinGetTclInstance(); class.hbrBackground = NULL; class.lpszMenuName = NULL; class.lpszClassName = L"TclNotifier"; class.lpfnWndProc = NotifierProc; class.hIcon = NULL; class.hCursor = NULL; RegisterClassW(&class); 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 if (waitForFiles) { /* * Add the ThreadSpecificData structure of this thread to the list of * ThreadSpecificData structures of all threads that are waiting on * file events. */ |
︙ | ︙ | |||
777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 | } FD_ZERO(&(tsdPtr->readyMasks.readable)); FD_ZERO(&(tsdPtr->readyMasks.writable)); FD_ZERO(&(tsdPtr->readyMasks.exceptional)); if (!tsdPtr->eventReady) { Tcl_ConditionWait(&tsdPtr->waitCV, ¬ifierMutex, timePtr); } tsdPtr->eventReady = 0; if (waitForFiles && tsdPtr->onList) { /* * Remove the ThreadSpecificData structure of this thread from the * waiting list. Alert the notifier thread to recompute its select * masks - skipping this caused a hang when trying to close a pipe * which the notifier thread was still doing a select on. | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 | } FD_ZERO(&(tsdPtr->readyMasks.readable)); FD_ZERO(&(tsdPtr->readyMasks.writable)); FD_ZERO(&(tsdPtr->readyMasks.exceptional)); if (!tsdPtr->eventReady) { #ifdef __CYGWIN__ if (!PeekMessageW(&msg, NULL, 0, 0, 0)) { DWORD timeout; if (timePtr) { timeout = timePtr->sec * 1000 + timePtr->usec / 1000; } else { timeout = 0xFFFFFFFF; } Tcl_MutexUnlock(¬ifierMutex); MsgWaitForMultipleObjects(1, &tsdPtr->event, 0, timeout, 1279); Tcl_MutexLock(¬ifierMutex); } #else Tcl_ConditionWait(&tsdPtr->waitCV, ¬ifierMutex, timePtr); #endif } tsdPtr->eventReady = 0; #ifdef __CYGWIN__ while (PeekMessageW(&msg, NULL, 0, 0, 0)) { /* * 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) { TranslateMessage(&msg); DispatchMessageW(&msg); } } ResetEvent(tsdPtr->event); #endif if (waitForFiles && tsdPtr->onList) { /* * Remove the ThreadSpecificData structure of this thread from the * waiting list. Alert the notifier thread to recompute its select * masks - skipping this caused a hang when trying to close a pipe * which the notifier thread was still doing a select on. |
︙ | ︙ | |||
1038 1039 1040 1041 1042 1043 1044 | if (tsdPtr->nextPtr) { tsdPtr->nextPtr->prevPtr = tsdPtr->prevPtr; } tsdPtr->nextPtr = tsdPtr->prevPtr = NULL; tsdPtr->onList = 0; tsdPtr->pollState = 0; } | > > > | > | 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 | if (tsdPtr->nextPtr) { tsdPtr->nextPtr->prevPtr = tsdPtr->prevPtr; } tsdPtr->nextPtr = tsdPtr->prevPtr = NULL; tsdPtr->onList = 0; tsdPtr->pollState = 0; } #ifdef __CYGWIN__ PostMessageW(tsdPtr->hwnd, 1024, 0, 0); #else /* __CYGWIN__ */ Tcl_ConditionNotify(&tsdPtr->waitCV); #endif /* __CYGWIN__ */ } } Tcl_MutexUnlock(¬ifierMutex); /* * Consume the next byte from the notifier pipe if the pipe was * readable. Note that there may be multiple bytes pending, but to |
︙ | ︙ |