| Ticket UUID: | 1348333 | |||
| Title: | 8.5 text widget creates to many timers | |||
| Type: | Bug | Version: | 8.6.18, 9.0.5, 9.1b1 | |
| Submitter: | kjnash | Created on: | 2005-11-04 14:46:25 | |
| Subsystem: | 69. Events | Assigned To: | oehhar | |
| Priority: | 8 | Severity: | Minor | |
| Status: | Closed | Last Modified: | 2026-10-28 17:33:19 | |
| Resolution: | Fixed | Closed By: | oehhar | |
| Closed on: | 2026-10-28 17:33:19 | |||
| Description: |
# Tk 8.5 cannot cope with a large number of 'idletasks' delayed actions, and # it hangs, consuming most of the system's CPU - even though it is able to # process the same actions if they are split by update commands. # # ActiveTcl 8.5 beta 3 (tcl_patchLevel 8.5a2) and ActiveTcl 8.5 beta 4 (8.5a4, # threaded) both have this problem. # # Tk 8.4 does not have this problem: ActiveTcl 8.4.11.2 (8.4.11, threaded) and # ActiveTcl 8.4.9.0 (8.4.9) tested. # # The attached script creates and maps a large number of text widgets, with # the option of using update after each widget is created, and (separately) # after it is mapped. # Mapping a large number of widgets gives Tk 8.5 a problem. # Creation of a large number of unmapped widgets also gives Tk 8.5 a problem. # The numbers of widgets, though large, are not perversely large - I have apps # with more than 150 widgets - and Tk 8.4 has no problem with much larger # numbers. # 100 widgets: OK always. # 144 to 900 widgets: OK in 8.4 always; fails in Tk 8.5 if updates are not # switched on. | |||
| User Comments: |
oehhar added on 2026-10-28 17:33:19:
CI clean! Merged to:
THanks Serhiy! Harald oehhar added on 2026-10-27 12:08:21: Great analysis, thanks! We will see tomorrow. Take care, Harald serhiy.storchaka added on 2026-10-27 11:17:59: Thank you, Harald. Unfortunately 20×20 does not catch the bug: without the fix all 400 widgets are synchronized at once. On my machine it needs about 600 text widgets to catch the bug, but 900 is a better bet for slower or faster machines. The failure on CI was probably due to the limited screen size: 30×30 text widgets of the default font need about 600×690 pixels, so on a small screen the toplevel is clipped, and pack unmaps the frames which do not fit. An unmapped text widget never completes its line metrics update (in 8.6 and 9.0 too), so one clipped row leaves exactly 30 widgets pending. I reproduced this on Linux and on Windows with wm maxsize: 30 pending with one row clipped, 90 with three. Reducing the font size should fix it: with -font {TkFixedFont -8} 30×30 widgets need 480×540 pixels on Linux and 360×420 on Windows, and the test still fails without the fix (900 pending) and passes with it. Done in [e283698b64], which now has the core-text-metrics-after-redraw tag. The 10 seconds timeout happens only when the test fails. When it passes, it takes 0.1 s on my machine (0.3 s on the Windows VM). oehhar added on 2026-10-27 09:00:10: Unfortunately, MacOS and MS-Win still show the test failure:
==== textDisp-41.1 many text widgets complete their line metrics update - bug 1348333 FAILED
==== Contents of test case:
for {set i 0} {$i < 30} {incr i} {
pack [frame .tt.f$i]
for {set j 0} {$j < 30} {incr j} {
text .tt.f$i.t$j -height 1 -width 2
.tt.f$i.t$j insert end $i$j
pack .tt.f$i.t$j -side left
}
}
# Without the fix, no widget gets synchronized at all. Allow up to 10
# seconds for slow machines.
for {set n 0} {$n < 100} {incr n} {
pause 100
set pending 0
foreach f [winfo children .tt] {
foreach t [winfo children $f] {
incr pending [$t pendingsync]
}
}
if {$pending == 0} {
break
}
}
set pending
---- Result was:
30
---- Result should have been (exact matching):
0
==== textDisp-41.1 FAILED
I ran the test locally and it succeeded. I have printed the final value of n on my machine. It is 11. That is 1 second. It is also curious, that the result is exactly 30 on both platforms. Shall I try to just give more time? We are not happy to have tests which take a long time, as this makes running the test suite more time consuming... Or perhaps reduce the text widget matrix to 20x20 ? This reduces n to 5 on my machine. I try this with commit [f2efd36d]. Thanks for all, Harald oehhar added on 2026-10-26 08:53:05: Ah, the CI run was on the wrong checkin. Will restart CI. Sorry for the wrong message, Harald oehhar added on 2026-10-26 08:52:00: Hi Serhiy, CI results are here: https://github.com/tcltk/tk/actions?query=branch%3Acore-text-metrics-after-redraw MS-Windows and Mac-OS test error:
==== textDisp-41.1 many text widgets complete their line metrics update - bug 1348333 FAILED
==== Contents of test case:
for {set i 0} {$i < 30} {incr i} {
pack [frame .tt.f$i]
for {set j 0} {$j < 30} {incr j} {
text .tt.f$i.t$j -height 1 -width 2
.tt.f$i.t$j insert end $i$j
pack .tt.f$i.t$j -side left
}
}
after 1000 {set ::done 1}
vwait ::done
set pending 0
foreach f [winfo children .tt] {
foreach t [winfo children $f] {
incr pending [$t pendingsync]
}
}
set pending
---- Result was:
30
---- Result should have been (exact matching):
0
==== textDisp-41.1 FAILED
I was not able to reproduce locally. Is it still a timing issue? Thanks for all, Harald serhiy.storchaka added on 2026-10-24 08:51:16: CI failed only in the new test textDisp-41.1 on Windows and macOS: it waited one second, which was not enough on the slower CI machines (30 of 900 widgets were still waiting). It now waits up to 10 seconds ([1f9685c952]); without the fix no widget gets synchronized at all, so the test still detects the bug. textWind-17.10 passed everywhere. oehhar added on 2026-10-23 17:19:44: Thanks, great! Highly appreciated! Lets wait for CI.. Harald nemethi (claiming to be Csaba Nemethi) added on 2026-10-23 17:09:56: I don't see any arguments against merging the text-metrics-after-redraw branch into main, core-9-0-branch, and core-8-6-branch. oehhar added on 2026-10-23 16:36:54: Great, Csaba. Thanks for the test! There is no merge->yes opinion from your side, but anyway. If CI is ok we will merge again. Thansk for all, Harald nemethi (claiming to be Csaba Nemethi) added on 2026-10-23 16:22:27: I can confirm that with branch text-metrics-after-redraw merged into main, the text tests pass on macOS, too. oehhar added on 2026-10-23 13:57:54: Thanks, great. I had tested the test on MS-Win before merging to main and it did not hang. I saw the beautiful big text widget matrix for a second. I activated CI. Lets see, if this passes. And of cause, Csabas opinion would be great... Thanks for all, Harald serhiy.storchaka added on 2026-10-23 13:44:44: Sorry for the hang: I tested the previous fix only on Linux, where textWind-17.10 passes. Now I test all fixes on Linux and Windows. In that test, [update] in a -create script runs while the redisplay is still pending, and the when-idle handler of the fix kept registering itself again, so [update] never returned. New fix on branch text-metrics-after-redraw ([009b2c8f09]): the line metrics update waits without a timer or a when-idle handler, and DisplayText() restarts it after the redisplay. The text tests pass on Linux and Windows 11, with no hang. Could someone please test it on macOS? oehhar added on 2026-10-23 13:19:22: Thanks, Jan. It was a try. Sorry, Harald jan.nijtmans added on 2026-10-23 12:48:43: It turns out that backout out the 'fix' makes everything pass again. So, I took the action to revert this on trunk. Sorry :-( jan.nijtmans added on 2026-10-23 12:34:46: Same problem can also be seen in the CI build: https://github.com/tcltk/tk/actions/runs/39913119911/job/120280442353 textTag.test textWind.test Error: The action 'Run Tests' has timed out after 20 minutes. It's the textWind-17.10 testcase hanging jan.nijtmans added on 2026-10-23 12:19:50: Unfortunately, I'm seeing a hang in textWind-17.10, both on Windows and on MacOS. So, I did a bisect: $ fossil bisect chart 1 BAD 2026-10-23 09:20:10 6d6d38074ea28fcb 4 BAD 2026-10-23 08:42:11 bdb7edf927982f35 5 BAD 2026-10-22 18:23:16 fb166f9f73106ab2 6 BAD 2026-10-22 17:32:35 4b3b840a41badb6a 3 GOOD 2026-10-22 15:14:16 51a8eab8eee4e121 CURRENT 2 GOOD 2026-10-21 15:23:43 b8fb1d6c114cce4a So, this clearly points to this ticket :-( Please don't backport this to 9.0 yet! oehhar added on 2026-10-22 17:40:47: Fix is effective. Merged to main by commit [4b3b840a41]. I feel incompetent on this one. Csaba, what do you think? Will merge to core-9-0 if main CI is clean. Thanks for all, Serhiy! Harald serhiy.storchaka added on 2026-09-24 10:57:12:
Still reproducible in 8.6 and 9.x with the attached script when The cause is what hobbs found: while a redisplay is pending, Fix on text-metrics-idle-wait: wait for the redisplay in an idle handler instead of polling. Test textDisp-38.1. vincentdarley added on 2006-04-03 00:39:16: Logged In: YES user_id=32170 Note: timers are only used because of the bug in Tk that 'after idle' handlers cannot reschedule themselves. The goal here is to do some computation when Tk is idle. It is entirely disconnected from the drawing/redrawing of the text widget for the good reason that the computation is referring to things that are not (currently) to be drawn, but are needed to know the correct size of the scrollbar, etc. Anything that hooks into redraw mechanisms won't help, therefore, because once the visible portion of the text widget is ok, no more redraw handlers are going to be called. So, what we want is a _robust_ 'compute when idle' mechanism, which allows idle computation to schedule more, future, idle computation. I don't know how to achieve that with the current Tcl, Tk APIs. hobbs added on 2006-03-31 07:37:47: Logged In: YES user_id=72656 Looking more into this, the actual problem is resource starvation. With the number of text widgets and the short timer time (1), the event queue never empties. If I up the time to 10, I can view 400 (20x20 grid) OK, but then 900 (30x30 grid) still has resource starvation issues. I think this timer stuff needs to be integrted into some deferred redraw handling. hobbs added on 2006-03-31 06:39:38: Logged In: YES user_id=72656 I have confirmed that the timer handling is broken. Please look into how others use deferred redraw handling. In particular, the enclosed test for a 20x20 text grid (400 widgets) with a printf of the Tcl_CreateTimerHandler point in AsyncUpdateLineMetrics shows that is endlessly called. All the timers should either delete their previous handler, or better yet do the eventuallyredraw handling. vincentdarley added on 2005-11-08 01:07:04: Logged In: YES user_id=32170 I think I do want to use Tcl_CreateTimerHandler, (this isn't for redrawing -- the redrawing side uses the same calls as Tk 8.4). Each text widget should only schedule 2 timers -- one for line height calculations and one for the scrollbar. I just skimmed the code in tkTextDisp.c and it all looks in order (i.e. each widget should never have more than 2 timers active). So, I'm interested to know things like how many timers are active in the reported case. hobbs added on 2005-11-08 00:35:53: Logged In: YES user_id=72656 I don't think you want to use Tcl_CreateTimerHandler, or at least not to schedule without checking what's already scheduled. If you look at the pattern other widgets use, it works on delayed calcuations (like EventuallyRedraw...) that only schedule *1* delayed operation, adjusting the parameters to note what needs to be redrawn if multiple calls for it come in (like increasing a bounding box or something). vincentdarley added on 2005-11-07 18:06:53: Logged In: YES user_id=32170 The text widget uses 'Tcl_CreateTimerHandler' to make various callbacks to do the pixel-line-height calculations. It's not obvious to me what can go wrong with those, but perhaps there's some sort of problem where an increasing queue of events is never handled, because we schedule many of these events just 1 millisecond ahead. This really needs someone who understands the Tcl_CreateTimerHandler mechanism to look into things. hobbs added on 2005-11-05 06:25:29: Logged In: YES user_id=72656 This appears to be a fault in the text widget (some excessive redraws?). If you use an entry instead, it works fine. Also, on Windows, if I just "touch" the "frozen" interface by trying to resize it, it snaps out of whatever weirdness it is in and displays all the text widgets. Repro'd on XP with AT 8.5. kjnash added on 2005-11-04 21:49:02: File Added - 155015: many_text_bug.tcl | |||
Attachments:
- many_text_bug.tcl [download] added by kjnash on 2005-11-04 21:49:02. [details]
