-
-
Notifications
You must be signed in to change notification settings - Fork 727
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
fix mpd module hang/crash after suspend #3793
base: master
Are you sure you want to change the base?
fix mpd module hang/crash after suspend #3793
Conversation
@@ -50,7 +50,7 @@ inline int close(FILE* fp, pid_t pid) { | |||
ret = waitpid(pid, &stat, WCONTINUED | WUNTRACED); | |||
|
|||
if (WIFEXITED(stat)) { | |||
spdlog::debug("Cmd exited with code {}", WEXITSTATUS(stat)); | |||
spdlog::trace("Cmd exited with code {}", WEXITSTATUS(stat)); |
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 changed this (and below) to trace since they made debugging with -l debug
very noisy. I'll be happy to revert this and/or open another PR in case we want separation of concerns.
This comment was marked as outdated.
This comment was marked as outdated.
Update: this seemingly has to to with |
cbf546d
to
7d222db
Compare
Still has some hanging problems updating after a wake from sleep. |
I've been having this annoying issue for a while, in which after waking up from a long suspend the MPD module is not updating anymore.
What I think is happening is that once the client goes to sleep the server TCP connection to the client expires (based on the values in
/proc/sys/net/ipv4/tcp_keepalive_*
), the server sends aRST
but the client never receives it because it is asleep.How to reproduce
This can be reproduced by killing the socket(s) on the server using
ss
like soWhen the client wakes, the MPD module will not update anymore.
Second bug
While debugging this, I realized that killing the socket on the client (or just having the connection naturally expire) actually causes waybar to go on an infinite loop and eventually crash:
Results in waybar realizing that the idle connection has died, but reconnection fails, clicking on the mpd icon in waybar causes the crash (last line):
Third bug (somehow unrelated?)
If there are any extra definitions in the waybar config, such as
on-click-middle
, single/right clicking on the mpd icon in waybar has no effect.Fix proposal
I haven't found a way to actually make the client immediately realize that the mpd connection is dead on wake (short of setting a period Idle timer to check the connection?)
unique_connection
if there are any errors when usingIDLE_RUN_NOIDLE_AND_CMD
unique_connection
on errors inIdle::on_io
(e.g. when the connection is killed like shown above (fixes second bug)handlePlayPause
withhandleToggle
(fixes third bug)Reason for the third bug
The reason for the third bug is that when a
waybar::AModule::AModule
is instantiated, depending on the initialization values and the config, it connects a few slots, for example when a module has actions and/or some custom user actions are defined in the configuration,Gdk::BUTTON_PRESS_MASK
is added to the event box and
AModule::handleToggle(GdkEventButton* const& e)
is connected toevent_box_.signal_button_press_event()
(see https://github.com/Alexays/Waybar/blob/master/src/AModule.cpp#L50-L51)handletoggle(e)
callshandleUserEvent(e)
(https://github.com/Alexays/Waybar/blob/master/src/AModule.cpp#L152, https://github.com/Alexays/Waybar/blob/master/src/AModule.cpp#L156), which does its processing and returnstrue
, stopping other handlers from being invoked for the button press event.In the current definition of
waybar::modules::MPD::MPD(...)
,MPD::handlePlayPause
is connected toevent_box_.signal_button_press_event()
(https://github.com/Alexays/Waybar/blob/master/src/modules/mpd/mpd.cpp#L43-L44), but thisis only ever called if there are no user-defined actions (e.g.
on-click-middle
) in the configuration. When there's no user-defined actions in the configuration, in that casehandleToggle()
is never connected inwaybar::AModule::AModule()
, event processing is not stopped by theAModule::handleToggle
call andMPD::handlePlayPause
is actually called.This PR replaces
handlePlayPause
withhandleToggle()
, which handles play/pause/stop and then calls the parenthandleToggle
method.