-
-
Notifications
You must be signed in to change notification settings - Fork 7.9k
Make Tkagg blit thread safe #18565
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Make Tkagg blit thread safe #18565
Conversation
@xzores can you install matplotlib from this PR and see if it prevents your crashes?
|
I found another way. I don't really want to undo my code, so I will have no way to test. |
I'm always happy to be wrong about this sort of thing 😄 I assume that |
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 :))? |
It was a bit tricky to ensure that the right arguments connect with the right call to |
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. |
The stderr spam will probably look familiar to some:
It can be silenced by adding an |
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
ef900b6
to
fd97233
Compare
@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. |
@@ -44,6 +44,28 @@ def _restore_foreground_window_at_end(): | |||
_c_internal_utils.Win32_SetForegroundWindow(foreground) | |||
|
|||
|
|||
_blit_args = {} | |||
# Initialize to a non-empty string that is not a Tcl command | |||
_blit_tcl_name = "29345091836409813" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why not directly initialize this to the final name here? e.g. "mpl_blit_" + uuid.uuid4().hex
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I love this idea, I always thought the initial name was tacky but for some reason I never came up with this fix!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In a pinch we could hardcode a uuid, they are universally unique after all...
Just some minor points, but mostly looks good. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
conditional on handling the comments above.
Co-authored-by: Tim Hoffmann <2836374+timhoffm@users.noreply.github.com>
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 howTk_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
pytest
passes).flake8
on changed files to check).flake8-docstrings
andpydocstyle<4
and runflake8 --docstring-convention=all
).doc/users/next_whats_new/
(follow instructions in README.rst there).doc/api/next_api_changes/
(follow instructions in README.rst there).