FazBrowse GitHub Viewer | Trending |
URL:
| Home
Tools: [Download Repo ZIP]   [Original HTTPS Page]

tkinter runs a busy-wait loop on interactive Python · Issue #140488 · python/cpython · GitHub

Repository navigation

tkinter runs a busy-wait loop on interactive Python #140488

Open

Description

Bug report

Bug description:

In EventHook in Modules/_tkinter.c, we used to have the following block to run the event loop:

#if defined(WITH_THREAD) || defined(MS_WINDOWS)
        Py_BEGIN_ALLOW_THREADS
        if(tcl_lock)PyThread_acquire_lock(tcl_lock, 1);
        tcl_tstate = event_tstate;
        
        result = Tcl_DoOneEvent(TCL_DONT_WAIT);
        
        tcl_tstate = NULL;
        if(tcl_lock)PyThread_release_lock(tcl_lock);
        if (result == 0)
            Sleep(Tkinter_busywaitinterval);
        Py_END_ALLOW_THREADS
#else
        result = Tcl_DoOneEvent(0);
#endif

in bpo-31370, support for threads-less builds was removed, and this block became

        Py_BEGIN_ALLOW_THREADS
        if(tcl_lock)PyThread_acquire_lock(tcl_lock, 1);
        tcl_tstate = event_tstate;
        
        result = Tcl_DoOneEvent(TCL_DONT_WAIT);
        
        tcl_tstate = NULL;
        if(tcl_lock)PyThread_release_lock(tcl_lock);
        if (result == 0)
            Sleep(Tkinter_busywaitinterval);
        Py_END_ALLOW_THREADS

This is a bit unfortunate, as we now back to running a busy-wait loop. See Guido van Rossum's comment of May 23, 1998: 7bf15648

I guess this block could be

        if (self->threaded) {
            /* Allow other Python threads to run. */
            ENTER_TCL
            result = Tcl_DoOneEvent(0);
            LEAVE_TCL
        }
        else {
            Py_BEGIN_ALLOW_THREADS
            if(tcl_lock)PyThread_acquire_lock(tcl_lock, 1);
            tcl_tstate = tstate;
            result = Tcl_DoOneEvent(TCL_DONT_WAIT);
            tcl_tstate = NULL;
            if(tcl_lock)PyThread_release_lock(tcl_lock);
            if (result == 0)
                Sleep(Tkinter_busywaitinterval);
            Py_END_ALLOW_THREADS
        }

in analogy with the event loop in _tkinter_tkapp_mainloop_impl. As self->threaded is true in most builds, this would avoid the busy-wait loop.

I am happy to submit a PR, but I'll wait until PR #140147 is in to avoid unnecessary complications to this code.

CPython versions tested on:

CPython main branch

Operating systems tested on:

macOS

Activity

  1. serhiy-storchaka commented on Jun 29, 2026

    Member

    @mdehoon, #148819 is merged. Note EventHook must stay polling on Windows since stdin isn't a Tcl file handler there, unlike mainloop.

  2. mdehoon commented on Jul 1, 2026

    ContributorAuthor

    @mdehoon, #148819 is merged.

    OK I can try and submit a PR for this issue.

    Note EventHook must stay polling on Windows since stdin isn't a Tcl file handler there, unlike mainloop.

    Yes, you're right.

  3. serhiy-storchaka commented on Jul 15, 2026

    Member

    @mdehoon, gentle ping.

  4. mdehoon commented on Jul 16, 2026

    ContributorAuthor

    @serhiy-storchaka

    Could you have a look at PR #152841 first, which is a trivial patch removing some dead code?

    The reason is for the current issue, we will need to move threaded out of TkappObject and make it a single static variable, as in EventHook we won't have a TkappObject *self argument like in _tkinter_tkapp_mainloop_impl.

    Logically it also makes sense for threaded to be a single static variable, as it is tied to the installed Tcl/Tk being threaded or not, as opposed to a particular TkappObject.

    The dead code in PR #152841 also refers to the threaded variable, so I'd like to move it out of the way first.

  5. serhiy-storchaka commented on Jul 17, 2026

    Member

    I prefer first to apply backportable fixes, and only after that drop support of non-threaded Tcl in main.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions


      Back | FazBrowse Home | New Git URL