Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Fix the Cygwin notifier, doing the initialization of the thread-local variables exactly the same as the Unix notifier. |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | descendants | both | bug-5d170b5ca5 |
Files: | files | file ages | folders |
SHA1: |
57e106c650de054ae957b5cddaa4ad82 |
User & Date: | jan.nijtmans 2015-09-02 11:54:58 |
Context
2015-09-03
| ||
09:39 | In StartNotifierThread() don't lock mutex if thread is already started. Fix panic message if thread... check-in: 795a9a8bc0 user: jan.nijtmans tags: bug-5d170b5ca5 | |
2015-09-02
| ||
11:54 | Fix the Cygwin notifier, doing the initialization of the thread-local variables exactly the same as ... check-in: 57e106c650 user: jan.nijtmans tags: bug-5d170b5ca5 | |
09:02 | Merge trunk. Gustaf's latest and greatest fix. check-in: e2f25680d8 user: jan.nijtmans tags: bug-5d170b5ca5 | |
Changes
Changes to unix/tclUnixNotfy.c.
︙ | ︙ | |||
99 100 101 102 103 104 105 | * that an event is ready to be processed * by sending this event. */ void *hwnd; /* Messaging window. */ #else /* !__CYGWIN__ */ pthread_cond_t waitCV; /* Any other thread alerts a notifier that an * event is ready to be processed by signaling * this condition variable. */ | < > | 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 | * that an event is ready to be processed * by sending this event. */ void *hwnd; /* Messaging window. */ #else /* !__CYGWIN__ */ pthread_cond_t waitCV; /* Any other thread alerts a notifier that an * event is ready to be processed by signaling * this condition variable. */ #endif /* __CYGWIN__ */ int waitCVinitialized; /* Variable to flag initialization of the structure */ int eventReady; /* True if an event is ready to be processed. * Used as condition flag together with waitCV * above. */ #endif /* TCL_THREADS */ } ThreadSpecificData; static Tcl_ThreadDataKey dataKey; |
︙ | ︙ | |||
250 251 252 253 254 255 256 | 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 *); /* | | > | 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 | 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 *); /* * Threaded-cygwin specific constants and functions in this file: */ static const WCHAR NotfyClassName[] = L"TclNotifier"; static DWORD __stdcall NotifierProc(void *hwnd, unsigned int message, void *wParam, void *lParam); #endif /* TCL_THREADS && __CYGWIN__ */ #if TCL_THREADS /* *---------------------------------------------------------------------- |
︙ | ︙ | |||
327 328 329 330 331 332 333 | return tclNotifierHooks.initNotifierProc(); } else { ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); #ifdef TCL_THREADS tsdPtr->eventReady = 0; | < > > > > > > > > > > > > > > > > > > > > > > < | 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 | return tclNotifierHooks.initNotifierProc(); } else { ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); #ifdef TCL_THREADS tsdPtr->eventReady = 0; /* * Initialize thread specific condition variable for this thread. */ if (tsdPtr->waitCVinitialized == 0) { #ifdef __CYGWIN__ WNDCLASS class; class.style = 0; class.cbClsExtra = 0; class.cbWndExtra = 0; class.hInstance = TclWinGetTclInstance(); class.hbrBackground = NULL; class.lpszMenuName = NULL; class.lpszClassName = NotfyClassName; 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); #else pthread_cond_init(&tsdPtr->waitCV, NULL); #endif /* __CYGWIN */ tsdPtr->waitCVinitialized = 1; } pthread_mutex_lock(¬ifierInitMutex); #if defined(HAVE_PTHREAD_ATFORK) && !defined(__APPLE__) && !defined(__hpux) /* * Install pthread_atfork handlers to clean up the notifier in the * child of a fork. */ |
︙ | ︙ | |||
399 400 401 402 403 404 405 | pthread_mutex_lock(¬ifierInitMutex); notifierCount--; /* * Check if FinializeNotifier was called without a prior InitNotifier * in this thread. */ | < < | 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 | pthread_mutex_lock(¬ifierInitMutex); notifierCount--; /* * Check if FinializeNotifier was called without a prior InitNotifier * in this thread. */ assert(tsdPtr->waitCVinitialized == 1); /* * If this is the last thread to use the notifier, close the notifier * pipe and wait for the background thread to terminate. */ if (notifierCount == 0) { |
︙ | ︙ | |||
436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 | } /* * Clean up any synchronization objects in the thread local storage. */ #ifdef __CYGWIN__ CloseHandle(tsdPtr->event); #else /* __CYGWIN__ */ pthread_cond_destroy(&tsdPtr->waitCV); #endif /* __CYGWIN__ */ pthread_mutex_unlock(¬ifierInitMutex); #endif /* TCL_THREADS */ } } /* | > > | 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 | } /* * Clean up any synchronization objects in the thread local storage. */ #ifdef __CYGWIN__ DestroyWindow(tsdPtr->hwnd); CloseHandle(tsdPtr->event); #else /* __CYGWIN__ */ pthread_cond_destroy(&tsdPtr->waitCV); #endif /* __CYGWIN__ */ tsdPtr->waitCVinitialized = 0; pthread_mutex_unlock(¬ifierInitMutex); #endif /* TCL_THREADS */ } } /* |
︙ | ︙ | |||
591 592 593 594 595 596 597 | } else { ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); FileHandler *filePtr; /* * Check if InitNotifier was called before in this thread */ | < < | 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 | } else { ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); FileHandler *filePtr; /* * Check if InitNotifier was called before in this thread */ assert(tsdPtr->waitCVinitialized == 1); for (filePtr = tsdPtr->firstFileHandlerPtr; filePtr != NULL; filePtr = filePtr->nextPtr) { if (filePtr->fd == fd) { break; } } if (filePtr == NULL) { |
︙ | ︙ | |||
668 669 670 671 672 673 674 | FileHandler *filePtr, *prevPtr; int i; ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); /* * Check if InitNotifier was called before in this thread */ | < < | 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 | FileHandler *filePtr, *prevPtr; int i; ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); /* * Check if InitNotifier was called before in this thread */ assert(tsdPtr->waitCVinitialized == 1); /* * Find the entry for the given file (and return if there isn't one). */ for (prevPtr = NULL, filePtr = tsdPtr->firstFileHandlerPtr; ; prevPtr = filePtr, filePtr = filePtr->nextPtr) { |
︙ | ︙ | |||
780 781 782 783 784 785 786 | */ tsdPtr = TCL_TSD_INIT(&dataKey); /* * Check if InitNotifier was called before in this thread */ | < < | 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 | */ tsdPtr = TCL_TSD_INIT(&dataKey); /* * Check if InitNotifier was called before in this thread */ assert(tsdPtr->waitCVinitialized == 1); for (filePtr = tsdPtr->firstFileHandlerPtr; filePtr != NULL; filePtr = filePtr->nextPtr) { if (filePtr->fd != fileEvPtr->fd) { continue; } |
︙ | ︙ | |||
885 886 887 888 889 890 891 | int numFound; #endif /* TCL_THREADS */ ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); /* * Check if InitNotifier was called before in this thread */ | < < | 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 | int numFound; #endif /* TCL_THREADS */ ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); /* * Check if InitNotifier was called before in this thread */ assert(tsdPtr->waitCVinitialized == 1); /* * Set up the timeout structure. Note that if there are no events to * check for, we return with a negative result rather than blocking * forever. */ |
︙ | ︙ | |||
934 935 936 937 938 939 940 | /* * Start notifier thread and place this thread on the list of * interested threads, signal the notifier thread, and wait for a * response or a timeout. */ StartNotifierThread(); | < < < < < < < < < < < < < < < < < < < < < < < < | 947 948 949 950 951 952 953 954 955 956 957 958 959 960 | /* * Start notifier thread and place this thread on the list of * interested threads, signal the notifier thread, and wait for a * response or a timeout. */ StartNotifierThread(); pthread_mutex_lock(¬ifierMutex); 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 |
︙ | ︙ | |||
1467 1468 1469 1470 1471 1472 1473 | * waitingListPtr != 0: there are threads currently waiting for events. */ if (atForkInit == 1) { notifierCount = 0; if (notifierThreadRunning == 1) { | < < > | > > > | > | 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 | * waitingListPtr != 0: there are threads currently waiting for events. */ if (atForkInit == 1) { notifierCount = 0; if (notifierThreadRunning == 1) { ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); notifierThreadRunning = 0; close(triggerPipe); triggerPipe = -1; /* * The waitingListPtr might contain event info from multiple * threads, which are invalid here, so setting it to NULL is not * unreasonable. */ waitingListPtr = NULL; /* * The tsdPtr from before the fork is copied as well. But since * we are paranoic, we don't trust its condvar and reset it. */ assert(tsdPtr->waitCVinitialized == 1); #ifdef __CYGWIN__ tsdPtr->hwnd = CreateWindowExW(NULL, NotfyClassName, NotfyClassName, 0, 0, 0, 0, 0, NULL, NULL, TclWinGetTclInstance(), NULL); ResetEvent(tsdPtr->event); #else pthread_cond_destroy(&tsdPtr->waitCV); pthread_cond_init(&tsdPtr->waitCV, NULL); #endif /* * The list of registered event handlers at fork time is in * tsdPtr->firstFileHandlerPtr; */ |
︙ | ︙ |