Waybar
Waybar copied to clipboard
pulseaudio module freezes if too much mousescroll
I am running Waybar v0.9.13, Sway 1.7 with pipewire-pulse and wireplumber on Debian unstable.
That works fine except that the pulseaudio module freezes when I use the mouse wheel to change the volume. That only happens when I scroll very quickly (so several volume change events per seconds).
I suspect that this could be caused by a race-condition between the pulseaudio thread and the main gtk thread.
Typically, that would be when waybar::modules::Pulseaudio::handleScroll
is executed by the main thread while the pulseaudio thread is processing a waybar::modules::Pulseaudio::volumeModifyCb
in response from a previous volume change.
I am not familiar with the pulseaudio client api but I suspect that most of the code inwaybar::modules::Pulseaudio::handleScroll
and waybar::modules::Pulseaudio::update
should be protected within a pair pa_threaded_mainloop_lock
& pa_threaded_mainloop_unlock
.
PS: for now, I have a workaround. With smooth-scrolling-threshold=2 the rate of volume changes is slower and no freeze occurs (for now).
I added a few pa_threaded_mainloop_lock & pa_threaded_mainloop_unlock in a branch and so far I cannot reproduce the freeze.
You can see what I did in https://github.com/schauveau/Waybar/blob/pulseaudio-lock/src/modules/pulseaudio.cpp
A few notes:
- I added a class to make sure that the lock is properly released if an exception occurs.
- In the functions called by the main thread, a temporary
locker
object is constructed before calling the pulseaudio api but also before reading the variables modified by the callbacks (e.g.monitor_
,volume_
,source_volume_
, ...) - The later is important especially for non-trivial types such as
std::string
(e.g.monitor_
,source_desc
, ...). A fatal error is very likely if astd::string
is read while another thread is modifying it.
Can you open a PR with your fix?