Merge pull request #2866 from Jay-716/pa-reconnect
pulseaudio: reconnect context when pulseaudio server restarts
This commit is contained in:
commit
ddad6ce136
|
@ -22,6 +22,7 @@ class AudioBackend {
|
|||
static void sourceInfoCb(pa_context*, const pa_source_info* i, int, void* data);
|
||||
static void serverInfoCb(pa_context*, const pa_server_info*, void*);
|
||||
static void volumeModifyCb(pa_context*, int, void*);
|
||||
void connectContext();
|
||||
|
||||
pa_threaded_mainloop* mainloop_;
|
||||
pa_mainloop_api* mainloop_api_;
|
||||
|
|
|
@ -28,16 +28,7 @@ AudioBackend::AudioBackend(std::function<void()> on_updated_cb, private_construc
|
|||
}
|
||||
pa_threaded_mainloop_lock(mainloop_);
|
||||
mainloop_api_ = pa_threaded_mainloop_get_api(mainloop_);
|
||||
context_ = pa_context_new(mainloop_api_, "waybar");
|
||||
if (context_ == nullptr) {
|
||||
throw std::runtime_error("pa_context_new() failed.");
|
||||
}
|
||||
if (pa_context_connect(context_, nullptr, PA_CONTEXT_NOFAIL, nullptr) < 0) {
|
||||
auto err =
|
||||
fmt::format("pa_context_connect() failed: {}", pa_strerror(pa_context_errno(context_)));
|
||||
throw std::runtime_error(err);
|
||||
}
|
||||
pa_context_set_state_callback(context_, contextStateCb, this);
|
||||
connectContext();
|
||||
if (pa_threaded_mainloop_start(mainloop_) < 0) {
|
||||
throw std::runtime_error("pa_mainloop_run() failed.");
|
||||
}
|
||||
|
@ -61,6 +52,19 @@ std::shared_ptr<AudioBackend> AudioBackend::getInstance(std::function<void()> on
|
|||
return std::make_shared<AudioBackend>(on_updated_cb, tag);
|
||||
}
|
||||
|
||||
void AudioBackend::connectContext() {
|
||||
context_ = pa_context_new(mainloop_api_, "waybar");
|
||||
if (context_ == nullptr) {
|
||||
throw std::runtime_error("pa_context_new() failed.");
|
||||
}
|
||||
pa_context_set_state_callback(context_, contextStateCb, this);
|
||||
if (pa_context_connect(context_, nullptr, PA_CONTEXT_NOFAIL, nullptr) < 0) {
|
||||
auto err =
|
||||
fmt::format("pa_context_connect() failed: {}", pa_strerror(pa_context_errno(context_)));
|
||||
throw std::runtime_error(err);
|
||||
}
|
||||
}
|
||||
|
||||
void AudioBackend::contextStateCb(pa_context *c, void *data) {
|
||||
auto backend = static_cast<AudioBackend *>(data);
|
||||
switch (pa_context_get_state(c)) {
|
||||
|
@ -80,7 +84,13 @@ void AudioBackend::contextStateCb(pa_context *c, void *data) {
|
|||
nullptr, nullptr);
|
||||
break;
|
||||
case PA_CONTEXT_FAILED:
|
||||
backend->mainloop_api_->quit(backend->mainloop_api_, 1);
|
||||
// When pulseaudio server restarts, the connection is "failed". Try to reconnect.
|
||||
// pa_threaded_mainloop_lock is already acquired in callback threads.
|
||||
// So there is no need to lock it again.
|
||||
if (backend->context_ != nullptr) {
|
||||
pa_context_disconnect(backend->context_);
|
||||
}
|
||||
backend->connectContext();
|
||||
break;
|
||||
case PA_CONTEXT_CONNECTING:
|
||||
case PA_CONTEXT_AUTHORIZING:
|
||||
|
|
Loading…
Reference in New Issue