]> mj.ucw.cz Git - ursary.git/commitdiff
Recover from PulseAudio failures. Important :)
authorMartin Mares <mj@ucw.cz>
Sun, 9 Nov 2014 16:57:58 +0000 (17:57 +0100)
committerMartin Mares <mj@ucw.cz>
Sun, 9 Nov 2014 23:37:26 +0000 (00:37 +0100)
nocturn.c
pulse-ucw.c
ut.c

index 12ea9c185ca83c5f343bda92001320344b28b137..96044e915c190460164ecba0a524a33056d1335b 100644 (file)
--- a/nocturn.c
+++ b/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);
 }
index b94ec8fa382377f047da18b6cc64b8bd463fe924..3ccb70de3e5ce34d9a570a352ad53564c0d7823b 100644 (file)
@@ -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/ut.c b/ut.c
index 9495b1a32e08dbe81263a2fd75cadfb07d3eafbd..825584841cefe0062f9a2558a0a8fa8b37185356 100644 (file)
--- a/ut.c
+++ b/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;
     }