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

Make Tkagg blit thread safe by richardsheridan · Pull Request #18565 · matplotlib/matplotlib · GitHub

Repository navigation

Make Tkagg blit thread safe - #18565

Merged
timhoffm merged 19 commits into
matplotlib:masterfrom
richardsheridan:tk_blit_thread_safe
Nov 2, 2020
Merged

timhoffm merged 19 commits into
matplotlib:masterfrom
richardsheridan:tk_blit_thread_safe

Conversation

richardsheridan commented Sep 24, 2020 •
edited
Loading

Copy link
Copy Markdown
Contributor

PR Summary

Closes #13293. (possibly?) Use tk.call to invoke tkinter's cross-thread signalling when necessary to safely blit from threads. A small amount of architectural changes were made in the hopes of attaining actual CPU parallelism with threads, but that was unsuccessful because of how Tk_PhotoPutBlock is written upstream.

Nevertheless this will prevent some silent crashes.

Downsides: I haven't done any work to prevent data races, and users that misuse the Tcl event system may run into issues discussed in python/cpython#21299

Needs a test.

PR Checklist

  • Has pytest style unit tests (and pytest passes).
  • Is Flake 8 compliant (run flake8 on changed files to check).
  • New features are documented, with examples if plot related.
  • Documentation is sphinx and numpydoc compliant (the docs should build without error).
  • Conforms to Matplotlib style conventions (install flake8-docstrings and pydocstyle<4 and run flake8 --docstring-convention=all).
  • New features have an entry in doc/users/next_whats_new/ (follow instructions in README.rst there).
  • API changes documented in doc/api/next_api_changes/ (follow instructions in README.rst there).

Copy link
Copy Markdown
Contributor Author

@xzores can you install matplotlib from this PR and see if it prevents your crashes?

pip install git+https://github.com/richardsheridan/matplotlib.git@tk_blit_thread_safe

xzores commented Sep 24, 2020

Copy link
Copy Markdown

pip install git+https://github.com/richardsheridan/matplotlib.git@tk_blit_thread_safe

I found another way. I don't really want to undo my code, so I will have no way to test.

richardsheridan changed the title Tk blit thread safe Make Tkagg blit thread safe Sep 24, 2020

Copy link
Copy Markdown
Member

I'm always happy to be wrong about this sort of thing 😄

I assume that mpl_tk_blit can go away now?

tacaswell added this to the v3.4.0 milestone Sep 25, 2020

anntzer commented Sep 25, 2020

Copy link
Copy Markdown
Contributor

Indeed, this appears to work. But I think the logic should go into _backend_tk.blit instead, so that it also works for tkcairo (and mplcairo.tk :))?

richardsheridan commented Sep 25, 2020 •
edited
Loading

Copy link
Copy Markdown
Contributor Author

It was a bit tricky to ensure that the right arguments connect with the right call to _tkagg.blit. Unfortunately PhotoImage is a kind of incomplete widget that doesn't have a register method or parent widget attribute, so it is necessary to pass in some other, unrelated widget.If anyone can think of a smarter way to get to the root widget, I'm open to it! nm i thought of one

richardsheridan marked this pull request as ready for review September 25, 2020 20:35

Copy link
Copy Markdown
Contributor Author

My test creates some stderr spam from a ttk widget being destroyed late, but I can't for the life of me figure out how to fix it. It would also be nice to get coverage on the code where bbox is not none, but I don't think it should block this PR.

Copy link
Copy Markdown
Contributor Author

The stderr spam will probably look familiar to some:

can't invoke "event" command: application has been destroyed
    while executing
"event generate $w <<ThemeChanged>>"
    (procedure "ttk::ThemeChanged" line 6)
    invoked from within
"ttk::ThemeChanged"

It can be silenced by adding an update_idletasks as per #9956 but I will try a bit more to see if we can avoid that route.

Copy link
Copy Markdown
Contributor Author

Some interesting failures on travis. I'm not sure what webagg has to do with anything, but some segfaults happen on py38 that don't happen on py37. Possibly I can guard that section of the test from running on the deprecated backend = 'wx'?

current status: doesn't crash but also doesn't draw
when called from a thread
current status: Prone to races and hard-to-diagnose timeouts

(see python/cpython#21299)
current status: Relies on tkinter arcana, untested
current status: Relies on tkinter arcana, untested
drawing from a thread produces an intolerable flicker unless blank and blit are called from the same event in the main thread

Copy link
Copy Markdown
Contributor Author

@tacaswell @anntzer This PR is consistently green on CI now, if you want to have another look.

I left it up to some other enterprising hacker to fix wx or macosx if they need it and make a separate PR.

Comment thread lib/matplotlib/backends/_backend_tk.py Outdated

_blit_args = {}
# Initialize to a non-empty string that is not a Tcl command
_blit_tcl_name = "29345091836409813"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

why not directly initialize this to the final name here? e.g. "mpl_blit_" + uuid.uuid4().hex

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

I love this idea, I always thought the initial name was tacky but for some reason I never came up with this fix!

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

Just a quick question, didn't we have a bug report come by recently because we were using one of the uuid functions, which was using a "weak" shasum algorithm, so their security-restricted system couldn't compute it?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

In a pinch we could hardcode a uuid, they are universally unique after all...

Comment thread lib/matplotlib/backends/_backend_tk.py Outdated

anntzer commented Oct 27, 2020

Copy link
Copy Markdown
Contributor

Just some minor points, but mostly looks good.

anntzer left a comment •
edited
Loading

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

conditional on handling the comments above.

Comment thread lib/matplotlib/backends/_backend_tk.py Outdated
Comment thread lib/matplotlib/backends/_backend_tk.py Outdated
Comment thread lib/matplotlib/backends/_backend_tk.py Outdated
Comment thread lib/matplotlib/backends/_backend_tk.py Outdated
richardsheridan and others added 2 commits October 27, 2020 09:55
Co-authored-by: Tim Hoffmann <2836374+timhoffm@users.noreply.github.com>
timhoffm merged commit 59bfcfa into matplotlib:master Nov 2, 2020
richardsheridan deleted the tk_blit_thread_safe branch November 2, 2020 16:17
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

FigureCanvasTkAgg.draw() silently crashes in threaded application

7 participants


Back | FazBrowse Home | New Git URL