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. |
|
|
||
| _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.
why not directly initialize this to the final name here? e.g. "mpl_blit_" + uuid.uuid4().hex
There was a problem hiding this comment.
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.
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.
In a pinch we could hardcode a uuid, they are universally unique after all...
|
Just some minor points, but mostly looks good. |
Co-authored-by: Tim Hoffmann <2836374+timhoffm@users.noreply.github.com>
PR Summary
Closes #13293. (possibly?) Use
tk.callto 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_PhotoPutBlockis 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
pytestpasses).flake8on changed files to check).flake8-docstringsandpydocstyle<4and 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).