Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Proposed fix for 9e69e2c602: Problem with TIP#609 |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | bug-9e69e2c602 |
Files: | files | file ages | folders |
SHA3-256: |
90712c8996dbf0e445e3580024266e03 |
User & Date: | jan.nijtmans 2024-12-06 10:39:21.051 |
Context
2024-12-07
| ||
13:15 | Fix 9e69e2c602: Problem with TIP#609 check-in: 81c759724b user: jan.nijtmans tags: core-8-branch | |
2024-12-06
| ||
10:39 | Proposed fix for 9e69e2c602: Problem with TIP#... Closed-Leaf check-in: 90712c8996 user: jan.nijtmans tags: bug-9e69e2c602 | |
10:04 | Fix "make dist". $(DISTDIR) part was missing check-in: f92b9869f4 user: jan.nijtmans tags: trunk, main | |
Changes
Changes to generic/tclNotify.c.
︙ | ︙ | |||
53 54 55 56 57 58 59 60 | */ typedef struct ThreadSpecificData { Tcl_Event *firstEventPtr; /* First pending event, or NULL if none. */ Tcl_Event *lastEventPtr; /* Last pending event, or NULL if none. */ Tcl_Event *markerEventPtr; /* Last high-priority event in queue, or NULL * if none. */ Tcl_Mutex queueMutex; /* Mutex to protect access to the previous | > > | > < | 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 | */ typedef struct ThreadSpecificData { Tcl_Event *firstEventPtr; /* First pending event, or NULL if none. */ Tcl_Event *lastEventPtr; /* Last pending event, or NULL if none. */ Tcl_Event *markerEventPtr; /* Last high-priority event in queue, or NULL * if none. */ Tcl_Size eventCount; /* Number of entries, but refer to comments in * Tcl_ServiceEvent(). */ Tcl_Mutex queueMutex; /* Mutex to protect access to the previous * four fields. */ int serviceMode; /* One of TCL_SERVICE_NONE or * TCL_SERVICE_ALL. */ int blockTimeSet; /* 0 means there is no maximum block time: * block forever. */ Tcl_Time blockTime; /* If blockTimeSet is 1, gives the maximum * elapsed time for the next block. */ int inTraversal; /* 1 if Tcl_SetMaxBlockTime is being called * during an event source traversal. */ int initialized; /* 1 if notifier has been initialized. */ EventSource *firstEventSourcePtr; /* Pointer to first event source in list of * event sources for this thread. */ Tcl_ThreadId threadId; /* Thread that owns this notifier instance. */ void *clientData; /* Opaque handle for platform specific * notifier. */ struct ThreadSpecificData *nextPtr; /* Next notifier in global list of notifiers. * Access is controlled by the listLock global * mutex. */ } ThreadSpecificData; static Tcl_ThreadDataKey dataKey; |
︙ | ︙ | |||
182 183 184 185 186 187 188 189 190 191 192 193 194 195 | for (evPtr = tsdPtr->firstEventPtr; evPtr != NULL; ) { hold = evPtr; evPtr = evPtr->nextPtr; Tcl_Free(hold); } tsdPtr->firstEventPtr = NULL; tsdPtr->lastEventPtr = NULL; Tcl_MutexUnlock(&(tsdPtr->queueMutex)); Tcl_MutexLock(&listLock); Tcl_FinalizeNotifier(tsdPtr->clientData); Tcl_MutexFinalize(&(tsdPtr->queueMutex)); for (prevPtrPtr = &firstNotifierPtr; *prevPtrPtr != NULL; | > | 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 | for (evPtr = tsdPtr->firstEventPtr; evPtr != NULL; ) { hold = evPtr; evPtr = evPtr->nextPtr; Tcl_Free(hold); } tsdPtr->firstEventPtr = NULL; tsdPtr->lastEventPtr = NULL; tsdPtr->eventCount = 0; Tcl_MutexUnlock(&(tsdPtr->queueMutex)); Tcl_MutexLock(&listLock); Tcl_FinalizeNotifier(tsdPtr->clientData); Tcl_MutexFinalize(&(tsdPtr->queueMutex)); for (prevPtrPtr = &firstNotifierPtr; *prevPtrPtr != NULL; |
︙ | ︙ | |||
482 483 484 485 486 487 488 | * must have been allocated the caller with * malloc (Tcl_Alloc), and it becomes the * property of the event queue. It will be * freed after the event has been handled. */ int position) /* One of TCL_QUEUE_TAIL, TCL_QUEUE_HEAD, TCL_QUEUE_MARK, * possibly combined with TCL_QUEUE_ALERT_IF_EMPTY */ { | | < < | > | 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 | * must have been allocated the caller with * malloc (Tcl_Alloc), and it becomes the * property of the event queue. It will be * freed after the event has been handled. */ int position) /* One of TCL_QUEUE_TAIL, TCL_QUEUE_HEAD, TCL_QUEUE_MARK, * possibly combined with TCL_QUEUE_ALERT_IF_EMPTY */ { int wasEmpty = 0; Tcl_MutexLock(&(tsdPtr->queueMutex)); if ((position & 3) == TCL_QUEUE_TAIL) { /* * Append the event on the end of the queue. */ evPtr->nextPtr = NULL; if (tsdPtr->firstEventPtr == NULL) { |
︙ | ︙ | |||
526 527 528 529 530 531 532 533 | tsdPtr->markerEventPtr->nextPtr = evPtr; } tsdPtr->markerEventPtr = evPtr; if (evPtr->nextPtr == NULL) { tsdPtr->lastEventPtr = evPtr; } } Tcl_MutexUnlock(&(tsdPtr->queueMutex)); | > > > > | | 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 | tsdPtr->markerEventPtr->nextPtr = evPtr; } tsdPtr->markerEventPtr = evPtr; if (evPtr->nextPtr == NULL) { tsdPtr->lastEventPtr = evPtr; } } if (position & TCL_QUEUE_ALERT_IF_EMPTY) { wasEmpty = (tsdPtr->eventCount <= 0); } tsdPtr->eventCount++; Tcl_MutexUnlock(&(tsdPtr->queueMutex)); return wasEmpty; } /* *---------------------------------------------------------------------- * * Tcl_DeleteEvents -- * |
︙ | ︙ | |||
600 601 602 603 604 605 606 607 608 609 610 611 612 613 | /* * Delete the event data structure. */ hold = evPtr; evPtr = evPtr->nextPtr; Tcl_Free(hold); } else { /* * Event is to be retained. */ prevPtr = evPtr; evPtr = evPtr->nextPtr; | > | 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 | /* * Delete the event data structure. */ hold = evPtr; evPtr = evPtr->nextPtr; Tcl_Free(hold); tsdPtr->eventCount--; } else { /* * Event is to be retained. */ prevPtr = evPtr; evPtr = evPtr->nextPtr; |
︙ | ︙ | |||
643 644 645 646 647 648 649 | * TCL_FILE_EVENTS, TCL_TIMER_EVENTS, or other * flags defined elsewhere. Events not * matching this will be skipped for * processing later. */ { Tcl_Event *evPtr, *prevPtr; Tcl_EventProc *proc; | | > | 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 | * TCL_FILE_EVENTS, TCL_TIMER_EVENTS, or other * flags defined elsewhere. Events not * matching this will be skipped for * processing later. */ { Tcl_Event *evPtr, *prevPtr; Tcl_EventProc *proc; Tcl_Size eventCount; ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); int result; /* * Asynchronous event handlers are considered to be the highest priority * events, and so must be invoked before we process events on the event * queue. */ |
︙ | ︙ | |||
700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 | evPtr->proc = NULL; /* * Release the lock before calling the event function. This allows * other threads to post events if we enter a recursive event loop in * this thread. Note that we are making the assumption that if the * proc returns 0, the event is still in the list. */ Tcl_MutexUnlock(&(tsdPtr->queueMutex)); result = proc(evPtr, flags); Tcl_MutexLock(&(tsdPtr->queueMutex)); if (result) { /* * The event was processed, so remove it from the queue. */ if (tsdPtr->firstEventPtr == evPtr) { | > > > > > > > > | 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 733 734 | evPtr->proc = NULL; /* * Release the lock before calling the event function. This allows * other threads to post events if we enter a recursive event loop in * this thread. Note that we are making the assumption that if the * proc returns 0, the event is still in the list. * * The eventCount is remembered and set to zero that the next * level of Tcl_ServiceEvent() gets an empty condition for the * Tcl_ThreadQueueEvent() to perform optional wakeups. * On exit of the next level, the eventCount is readjusted. */ eventCount = tsdPtr->eventCount; tsdPtr->eventCount = 0; Tcl_MutexUnlock(&(tsdPtr->queueMutex)); result = proc(evPtr, flags); Tcl_MutexLock(&(tsdPtr->queueMutex)); tsdPtr->eventCount += eventCount; if (result) { /* * The event was processed, so remove it from the queue. */ if (tsdPtr->firstEventPtr == evPtr) { |
︙ | ︙ | |||
739 740 741 742 743 744 745 746 747 748 749 750 751 752 | } } else { evPtr = NULL; } } if (evPtr) { Tcl_Free(evPtr); } Tcl_MutexUnlock(&(tsdPtr->queueMutex)); return 1; } else { /* * The event wasn't actually handled, so we have to restore the * proc field to allow the event to be attempted again. | > | 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 | } } else { evPtr = NULL; } } if (evPtr) { Tcl_Free(evPtr); tsdPtr->eventCount--; } Tcl_MutexUnlock(&(tsdPtr->queueMutex)); return 1; } else { /* * The event wasn't actually handled, so we have to restore the * proc field to allow the event to be attempted again. |
︙ | ︙ |