mirror of
https://github.com/rivo/tview.git
synced 2026-04-26 21:35:54 +03:00
[GH-ISSUE #784] Deadlock when waiting for draw inside goroutines #576
Labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
starred/tview#576
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Originally created by @vaaleyard on GitHub (Dec 20, 2022).
Original GitHub issue: https://github.com/rivo/tview/issues/784
So, I have a scenario where I need to wait for something to happen to be able to continue the code. Take the code below as an example:
With "true" as input, I'd like to get "3" when printing the counter right after executing the goroutine, but it prints "0", because the goroutine didn't finished. In order to make this, the first thing I thought is to create a waiting group to wait for this goroutine. So, I did this:
But this ends in a deadlock, and I don't know why. How can I achieve this?
Disclaimer: I've created this code purely to simulate my scenario, I know it's weird.
@rivo commented on GitHub (Dec 21, 2022):
The deadlock happens because your "Process" callback function blocks the workflow by not returning right away. When you call
QueueUpdateDraw(), somewhere it still waits for this callback to finally finish so everything can keep going. From the Wiki:It's hard to tell from this example what you really want to achieve. But if you want to kick off some concurrent process when the user clicks on the "Process" button, you might want to wrap it all in a goroutine:
(Also, you should synchronize access to the
inputvariable, to avoid race conditions. Or use channels instead.)@vaaleyard commented on GitHub (Dec 26, 2022):
Hi @rivo , thanks for your response. With your idea, I've wrapped all of it in a goroutine and it worked.
What I wanted to do is to draw an animated array and display a widget after it's finished. The code is here.
Thank you for your time.
@spacez320 commented on GitHub (Jan 7, 2024):
For anyone stumbling on this, the wrapping of callback functions in a goroutine also seems to work for keystroke handler functions in tview.Table. For example (trying to simplify from the actual code):
Feel free to yell at me if anything above deserves it, but the main point is that the callback function on the main thread should return right away and a goroutine works well for that.
Thanks for the help and hard work @rivo .
Edit: Added the call to
QueueUpdateDrawwhich is necessary when updating primitives in goroutines.@spacez320 commented on GitHub (Jan 11, 2024):
@digitallyserviced Thanks for the suggestion. Unfortunately wrapping
interrupt <- truein aselectto make it non-blocking doesn't really work very well because it looks like sometimes the interrupt doesn't actually successfully send, so the updating goroutine doesn't consistently stop updating as intended.