EmbarkStudios / EmbarkStudios/puffin

puffin_egui deadlock if new_frame is called from another thread

Open
#197 1 comment 0 reactions 0 assignees View on GitHub
bug
Dominant language
Rust
Stars
1.7k
Forks
111
Avg merge
2h 50m
Merged PRs (30d)
1

Description

I'm running into a deadlock in `puffin_egui` if `new_frame()` is called from a thread other than the UI thread.
I built a sampling profiler that runs in a single thread, manually creates `ThreadProfiler` instances for all threads running in the process, and samples their stack traces at intervals, so I'm calling `new_frame` from that thread rather than my UI thread.

Here puffin takes the `GlobalFrameView` lock and holds it across the UI function call:
https://github.com/EmbarkStudios/puffin/blob/0dd10b2d4d67416fe340716b7bd0fa0ab4138491/puffin_egui/src/lib.rs#L117-L130

The profiler ui call itself contains profiling calls, which calls `ThreadProfiler::end_scope` internally, which tries to take the `GlobalProfiler` lock. So you have a nested `GlobalFrameView` lock -> `GlobalProfiler` lock acquisition in the UI.

`GlobalProfiler::lock().new_frame()` has the `GlobalProfiler` locked and calls the sink function here, which tries to lock the `GlobalFrameView`: https://github.com/EmbarkStudios/puffin/blob/0dd10b2d4d67416fe340716b7bd0fa0ab4138491/puffin/src/profile_view.rs#L259

This mismatched lock order triggers a deadlock.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.