处理 pulseaudio 服务关闭导致的程序意外终止

This commit is contained in:
2026-02-11 14:38:05 +08:00
parent a69f3bbc64
commit b5c0cfefd7

View File

@@ -27,8 +27,8 @@ struct pulse_context_t {
uint32_t index; uint32_t index;
}; };
static void clean_pulse_context(pulse_context_t *context); static void clean_pulse_context(pulse_context_t *context, bool full_cleanup);
static void init_pulse_context(pulse_context_t *context); static void init_pulse_context(pulse_context_t *context, bool create_loop);
static void state_callback(pa_context *context, void *userdata); static void state_callback(pa_context *context, void *userdata);
static void subscribe_callback(pa_context *context, static void subscribe_callback(pa_context *context,
pa_subscription_event_type_t t, uint32_t index, pa_subscription_event_type_t t, uint32_t index,
@@ -43,7 +43,7 @@ pulse_context_t *init_pulse(GMainContext *context, pulse_notify_t callback) {
pulse_context_t *ctx = p_new(pulse_context_t, 1); pulse_context_t *ctx = p_new(pulse_context_t, 1);
ctx->g_context = context; ctx->g_context = context;
ctx->callback = callback; ctx->callback = callback;
init_pulse_context(ctx); init_pulse_context(ctx, true);
return ctx; return ctx;
} }
@@ -78,26 +78,32 @@ void toggle_pulse_mute(pulse_context_t *context) {
} }
void clean_pulse(pulse_context_t *context) { void clean_pulse(pulse_context_t *context) {
clean_pulse_context(context); clean_pulse_context(context, true);
p_delete(&context); p_delete(&context);
} }
void clean_pulse_context(pulse_context_t *context) { void clean_pulse_context(pulse_context_t *context, bool full_cleanup) {
memset(&context->pulse, 0, sizeof(context->pulse)); memset(&context->pulse, 0, sizeof(context->pulse));
if (context->callback) context->callback(&context->pulse); if (context->callback) context->callback(&context->pulse);
if (context->context) { if (context->context) {
pa_context_set_state_callback(context->context, nullptr, nullptr);
pa_context_set_subscribe_callback(context->context, nullptr, nullptr);
pa_context_disconnect(context->context); pa_context_disconnect(context->context);
pa_context_unref(context->context); pa_context_unref(context->context);
context->context = nullptr; context->context = nullptr;
} }
if (context->loop) pa_glib_mainloop_free(context->loop);
context->pulse.inited = false; context->pulse.inited = false;
context->loop = nullptr; if (full_cleanup && context->loop) {
pa_glib_mainloop_free(context->loop);
context->loop = nullptr;
}
} }
void init_pulse_context(pulse_context_t *context) { void init_pulse_context(pulse_context_t *context, bool create_loop) {
if (context->loop) pa_glib_mainloop_free(context->loop); if (create_loop) {
context->loop = pa_glib_mainloop_new(context->g_context); if (context->loop) pa_glib_mainloop_free(context->loop);
context->loop = pa_glib_mainloop_new(context->g_context);
}
pa_mainloop_api *api = pa_glib_mainloop_get_api(context->loop); pa_mainloop_api *api = pa_glib_mainloop_get_api(context->loop);
context->context = pa_context_new(api, APP_NAME "-audio-status"); context->context = pa_context_new(api, APP_NAME "-audio-status");
pa_context_connect(context->context, nullptr, PA_CONTEXT_NOFAIL, nullptr); pa_context_connect(context->context, nullptr, PA_CONTEXT_NOFAIL, nullptr);
@@ -113,8 +119,8 @@ void state_callback(pa_context *context, void *userdata) {
pa_context_subscribe(context, PA_SUBSCRIPTION_MASK_SINK, nullptr, nullptr); pa_context_subscribe(context, PA_SUBSCRIPTION_MASK_SINK, nullptr, nullptr);
pa_context_get_server_info(context, server_info_callback, ctx); pa_context_get_server_info(context, server_info_callback, ctx);
} else if (state == PA_CONTEXT_FAILED) { } else if (state == PA_CONTEXT_FAILED) {
clean_pulse_context(ctx); clean_pulse_context(ctx, false);
init_pulse_context(ctx); init_pulse_context(ctx, false);
} }
} }