chiark / gitweb /
disobedience now detects disconnection within ~1s
authorrjk@greenend.org.uk <>
Sun, 30 Sep 2007 13:56:11 +0000 (14:56 +0100)
committerrjk@greenend.org.uk <>
Sun, 30 Sep 2007 13:56:11 +0000 (14:56 +0100)
disobedience/disobedience.c
doc/disorder_protocol.5.in
lib/eclient.c
lib/eclient.h
server/server.c

index b45b0071277251ff17989c99620c722e3a596862..3c3fae6b6346f669e4d2890694c6fd1f7e3a1209 100644 (file)
@@ -59,6 +59,9 @@ int volume_l, volume_r;                 /* volume */
 double goesupto = 10;                   /* volume upper bound */
 int choosealpha;                        /* break up choose by letter */
 
+/** @brief True if a NOP is in flight */
+static int nop_in_flight;
+
 static const disorder_eclient_log_callbacks gdisorder_log_callbacks = {
   log_connected,
   log_completed,
@@ -375,6 +378,24 @@ static gboolean heartbeat(gpointer attribute((unused)) data) {
   return TRUE;
 }
 
+/** @brief Called when a NOP completes */
+static void nop_completed(void attribute((unused)) *v) {
+  nop_in_flight = 0;
+}
+
+/** @brief Called from time to time to arrange for a NOP to be sent
+ *
+ * At most one NOP remains in flight at any moment.  If the client is not
+ * currently connected then no NOP is sent.
+ */
+static gboolean maybe_send_nop(gpointer attribute((unused)) data) {
+  if(!nop_in_flight && disorder_eclient_connected(client)) {
+    nop_in_flight = 1;
+    disorder_eclient_nop(client, nop_completed, 0);
+  }
+  return TRUE;                          /* keep call me please */
+}
+
 /* main -------------------------------------------------------------------- */
 
 static const struct option options[] = {
@@ -463,6 +484,12 @@ int main(int argc, char **argv) {
   gtk_widget_show_all(toplevel);
   /* set initial control button visibility/usability */
   control_update();
+  /* issue a NOP every so often */
+  g_timeout_add_full(G_PRIORITY_LOW,
+                     1000/*interval, ms*/,
+                     maybe_send_nop,
+                     0/*data*/,
+                     0/*notify*/);
   D(("enter main loop"));
   MTAG("misc");
   g_main_loop_run(mainloop);
index f3af468c08044668c1b758f11d983906fb61f7f1..d3ad537aee8d47f81b77423cd49622cb1275298e 100644 (file)
@@ -109,6 +109,11 @@ the queue.  If \fITARGET\fR is listed in the ID list then the tracks are moved
 to just after the first non-listed track before it, or to the head if there is
 no such track.
 .TP
+.B nop
+Do nothing.  Used by
+.BR disobedience (1)
+as a keepalive measure.
+.TP
 .B part \fITRACK\fR \fICONTEXT\fI \fIPART\fR
 Get a track name part.  Returns an empty string if a name part cannot be
 constructed.
index 201da384b1002cbf63f0da45bb3ed4caa1c5f532..e98d15263d14b2b12a2fb3b2d27d6dfea4d039bb 100644 (file)
@@ -1136,6 +1136,13 @@ int disorder_eclient_search(disorder_eclient *c,
                 "search", terms, (char *)0);
 }
 
+int disorder_eclient_nop(disorder_eclient *c,
+                         disorder_eclient_no_response *completed,
+                         void *v) {
+  return simple(c, no_response_opcallback, (void (*)())completed, v, 
+                "nop", (char *)0);
+}
+
 /* Log clients ***************************************************************/
 
 /** @brief Monitor the server log
index d1e4e97d5ebd81fbf2868af85fcb9f5953085f77..d898ca8ee51203bf3aa7bec6d2376f5e19ce005a 100644 (file)
@@ -292,6 +292,10 @@ int disorder_eclient_search(disorder_eclient *c,
                             const char *terms,
                             void *v);
 
+int disorder_eclient_nop(disorder_eclient *c,
+                         disorder_eclient_no_response *completed,
+                         void *v);
+
 #endif
 
 /*
index 5837e38628069775b6204c70d101387ab175bfbc..cb7714e16b2ac82ef5d496fd7d508bb7f1133d8a 100644 (file)
@@ -900,6 +900,13 @@ static int c_get_global(struct conn *c,
   return 1;
 }
 
+static int c_nop(struct conn *c,
+                char attribute((unused)) **vec,
+                int attribute((unused)) nvec) {
+  sink_printf(ev_writer_sink(c->w), "250 Quack\n");
+  return 1;
+}
+
 #define C_AUTH         0001            /* must be authenticated */
 #define C_TRUSTED      0002            /* must be trusted user */
 
@@ -923,6 +930,7 @@ static const struct command {
   { "log",            0, 0,       c_log,            C_AUTH },
   { "move",           2, 2,       c_move,           C_AUTH },
   { "moveafter",      1, INT_MAX, c_moveafter,      C_AUTH },
+  { "nop",            0, 0,       c_nop,            C_AUTH },
   { "part",           3, 3,       c_part,           C_AUTH },
   { "pause",          0, 0,       c_pause,          C_AUTH },
   { "play",           1, 1,       c_play,           C_AUTH },