From 8799f93d28070fff2166b56416affd021e3b11bd Mon Sep 17 00:00:00 2001 From: Martin Mares Date: Sun, 9 Nov 2014 17:57:58 +0100 Subject: [PATCH] Ursary: Recover from PulseAudio failures. Important :) --- ursaryd/nocturn.c | 4 +-- ursaryd/pulse-ucw.c | 2 +- ursaryd/ut.c | 66 +++++++++++++++++++++++++++++++++++++-------- 3 files changed, 58 insertions(+), 14 deletions(-) diff --git a/ursaryd/nocturn.c b/ursaryd/nocturn.c index 12ea9c1..96044e9 100644 --- a/ursaryd/nocturn.c +++ b/ursaryd/nocturn.c @@ -280,7 +280,7 @@ static void noct_sched_write(void) int i = bit_ffs(noct_dirty_ring_val); noct_dirty_ring_val ^= 1U << i; if (i == 8) - noct_do_write(0x50 + i, noct_ring_val[i]); + noct_do_write(0x50, noct_ring_val[i]); else noct_do_write(0x40 + i, noct_ring_val[i]); } @@ -501,5 +501,5 @@ void noct_init(void) // Schedule search for the Nocturn noct_connect_timer.handler = noct_connect; - timer_add_rel(&noct_connect_timer, 0); + timer_add_rel(&noct_connect_timer, 100); } diff --git a/ursaryd/pulse-ucw.c b/ursaryd/pulse-ucw.c index b94ec8f..3ccb70d 100644 --- a/ursaryd/pulse-ucw.c +++ b/ursaryd/pulse-ucw.c @@ -107,7 +107,7 @@ static struct pmain_io *pmain_get_io(int fd) return io; } - struct pmain_io *io = xmalloc(sizeof(*io)); + struct pmain_io *io = xmalloc_zero(sizeof(*io)); io->f.fd = fd; io->f.data = io; clist_add_tail(&pmain_io_list, &io->n); diff --git a/ursaryd/ut.c b/ursaryd/ut.c index 9495b1a..8255848 100644 --- a/ursaryd/ut.c +++ b/ursaryd/ut.c @@ -16,6 +16,7 @@ /*** Interface to PulseAudio ***/ static pa_context *pulse_ctx; +static struct main_timer pulse_connect_timer; static void pulse_dump(void); @@ -102,7 +103,7 @@ struct pulse_sink_input { #define HASH_NODE struct pulse_sink_input #define HASH_PREFIX(x) pulse_sink_input_##x #define HASH_KEY_ATOMIC idx -// #define HASH_WANT_CLEANUP +#define HASH_WANT_CLEANUP #define HASH_WANT_LOOKUP #define HASH_WANT_REMOVE #define HASH_ZERO_FILL @@ -157,7 +158,7 @@ struct pulse_sink { #define HASH_NODE struct pulse_sink #define HASH_PREFIX(x) pulse_sink_##x #define HASH_KEY_ATOMIC idx -// #define HASH_WANT_CLEANUP +#define HASH_WANT_CLEANUP #define HASH_WANT_LOOKUP #define HASH_WANT_REMOVE #define HASH_ZERO_FILL @@ -218,7 +219,7 @@ struct pulse_client { #define HASH_NODE struct pulse_client #define HASH_PREFIX(x) pulse_client_##x #define HASH_KEY_ATOMIC idx -// #define HASH_WANT_CLEANUP +#define HASH_WANT_CLEANUP #define HASH_WANT_LOOKUP #define HASH_WANT_REMOVE #define HASH_ZERO_FILL @@ -258,6 +259,14 @@ static void pulse_client_gone(int idx) schedule_update(); } +static void pulse_shutdown(void) +{ + DBG("Pulse: Shutting down"); + pulse_client_cleanup(); + pulse_sink_cleanup(); + pulse_sink_input_cleanup(); +} + static void pulse_subscribe_done_cb(pa_context *ctx, int success, void *userdata) { pulse_op_done(userdata); @@ -317,8 +326,11 @@ static void pulse_state_cb(pa_context *ctx, void *userdata UNUSED) { PULSE_STATE(PS_OFFLINE); pulse_op_cancel_all(); - // FIXME: Reset all data structures + pulse_shutdown(); + schedule_update(); } + if (state == PA_CONTEXT_FAILED && !timer_is_active(&pulse_connect_timer)) + timer_add_rel(&pulse_connect_timer, 2000); } } @@ -345,19 +357,32 @@ static void pulse_dump(void) HASH_END_FOR; } -static void pulse_init(void) +static void pulse_connect(struct main_timer *t) { - pmain_init(); + DBG("Pulse: Connecting"); + timer_del(t); + clist_init(&pulse_op_list); pulse_client_init(); pulse_sink_init(); pulse_sink_input_init(); + if (pulse_ctx) + pa_context_unref(pulse_ctx); pulse_ctx = pa_context_new(&pmain_api, "ursaryd"); + pa_context_set_state_callback(pulse_ctx, pulse_state_cb, NULL); pa_context_connect(pulse_ctx, NULL, PA_CONTEXT_NOAUTOSPAWN, NULL); } +static void pulse_init(void) +{ + pmain_init(); + + pulse_connect_timer.handler = pulse_connect; + timer_add_rel(&pulse_connect_timer, 0); +} + /*** High-level logic ***/ static struct main_timer update_timer; @@ -485,15 +510,34 @@ static void update_clients(void) static void do_update(struct main_timer *t) { timer_del(t); + if (!noct_is_ready()) + { + DBG("## UPDATE: Nocturn is not ready"); + return; + } + + static bool dead; if (pulse_state != PS_ONLINE) { DBG("## UPDATE: Pulse is not online"); + for (int i=0; i<=8; i++) + noct_set_ring(i, RING_MODE_LEFT, 0); + for (int i=0; i<8; i++) + { + noct_set_button(i, 1); + noct_set_button(i+8, 0); + } + dead = 1; return; } - if (!noct_is_ready()) + if (dead) { - DBG("## UPDATE: Nocturn is not ready"); - return; + DBG("## UPDATE: Waking up from the dead"); + for (int i=0; i<=8; i++) + noct_set_ring(i, RING_MODE_LEFT, 0); + for (int i=0; i<16; i++) + noct_set_button(i, 0); + dead = 0; } DBG("## UPDATE"); @@ -559,7 +603,7 @@ void notify_rotary(int rotary, int delta) { if (pulse_state != PS_ONLINE) { - DBG("## NOTIFY: Pulse is not inline"); + DBG("## NOTIFY: Pulse is not online"); return; } @@ -624,7 +668,7 @@ void notify_button(int button, int on) { if (pulse_state != PS_ONLINE) { - DBG("## NOTIFY: Pulse is not inline"); + DBG("## NOTIFY: Pulse is not online"); return; } -- 2.39.2