chiark / gitweb /
Correct ordering of configuration key table.
authorRichard Kettlewell <rjk@greenend.org.uk>
Sun, 14 Feb 2010 10:19:50 +0000 (10:19 +0000)
committerRichard Kettlewell <rjk@greenend.org.uk>
Sun, 14 Feb 2010 10:19:50 +0000 (10:19 +0000)
Add a test to ensure it stays correct in the future!

.bzrignore
lib/configuration.c
lib/configuration.h
lib/queue.h
lib/speaker-protocol.h
libtests/Makefile.am
libtests/t-configuration.c [new file with mode: 0644]
server/play.c
server/speaker.c

index 30d6e0df6f5c7ad525db79a819a5f6db9eda516f..150c85c8e411e76136edf02898f010129caa1bc6 100644 (file)
@@ -172,6 +172,7 @@ libtests/t-words
 libtests/t-wstat
 libtests/t-macros
 libtests/t-cgi
 libtests/t-wstat
 libtests/t-macros
 libtests/t-cgi
+libtests/t-configuration
 doc/*.tmpl
 doc/disorder_templates.5
 oc/disorder_templates.5.html
 doc/*.tmpl
 doc/disorder_templates.5
 oc/disorder_templates.5.html
index e2af880368ee04290c147167c7be6b988ef83e08..98d672b6ee2c0b36349c8fe2c29a8f6af371ffb7 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * This file is part of DisOrder.
 /*
  * This file is part of DisOrder.
- * Copyright (C) 2004-2009 Richard Kettlewell
+ * Copyright (C) 2004-2010 Richard Kettlewell
  * Portions copyright (C) 2007 Mark Wooding
  *
  * This program is free software: you can redistribute it and/or modify
  * Portions copyright (C) 2007 Mark Wooding
  *
  * This program is free software: you can redistribute it and/or modify
@@ -1068,8 +1068,8 @@ static const struct conf conf[] = {
   { C(checkpoint_min),   &type_integer,          validate_non_negative },
   { C(collection),       &type_collections,      validate_any },
   { C(connect),          &type_netaddress,       validate_destaddr },
   { C(checkpoint_min),   &type_integer,          validate_non_negative },
   { C(collection),       &type_collections,      validate_any },
   { C(connect),          &type_netaddress,       validate_destaddr },
-  { C(cookie_login_lifetime),  &type_integer,    validate_positive },
   { C(cookie_key_lifetime),  &type_integer,      validate_positive },
   { C(cookie_key_lifetime),  &type_integer,      validate_positive },
+  { C(cookie_login_lifetime),  &type_integer,    validate_positive },
   { C(dbversion),        &type_integer,          validate_positive },
   { C(default_rights),   &type_rights,           validate_any },
   { C(device),           &type_string,           validate_any },
   { C(dbversion),        &type_integer,          validate_positive },
   { C(default_rights),   &type_rights,           validate_any },
   { C(device),           &type_string,           validate_any },
@@ -1099,10 +1099,10 @@ static const struct conf conf[] = {
   { C(plugins),          &type_string_accum,     validate_isdir },
   { C(prefsync),         &type_integer,          validate_positive },
   { C(queue_pad),        &type_integer,          validate_positive },
   { C(plugins),          &type_string_accum,     validate_isdir },
   { C(prefsync),         &type_integer,          validate_positive },
   { C(queue_pad),        &type_integer,          validate_positive },
-  { C(replay_min),       &type_integer,          validate_non_negative },
   { C(refresh),          &type_integer,          validate_positive },
   { C(reminder_interval), &type_integer,         validate_positive },
   { C(remote_userman),   &type_boolean,          validate_any },
   { C(refresh),          &type_integer,          validate_positive },
   { C(reminder_interval), &type_integer,         validate_positive },
   { C(remote_userman),   &type_boolean,          validate_any },
+  { C(replay_min),       &type_integer,          validate_non_negative },
   { C2(restrict, restrictions),         &type_restrict,         validate_any },
   { C(rtp_delay_threshold), &type_integer,       validate_positive },
   { C(sample_format),    &type_sample_format,    validate_sample_format },
   { C2(restrict, restrictions),         &type_restrict,         validate_any },
   { C(rtp_delay_threshold), &type_integer,       validate_positive },
   { C(sample_format),    &type_sample_format,    validate_sample_format },
@@ -1729,6 +1729,19 @@ static int namepartlist_compare(const struct namepartlist *a,
     return 0;
 }
 
     return 0;
 }
 
+/** @brief Verify configuration table.
+ * @return The number of problems found
+*/
+int config_verify(void) {
+  int fails = 0;
+  for(size_t n = 1; n < sizeof conf / sizeof *conf; ++n)
+    if(strcmp(conf[n-1].name, conf[n].name) >= 0) {
+      fprintf(stderr, "%s >= %s\n", conf[n-1].name, conf[n].name);
+      ++fails;
+    }
+  return fails;
+}
+
 /*
 Local Variables:
 c-basic-offset:2
 /*
 Local Variables:
 c-basic-offset:2
index 9170a2f2b752c118e937099a1fa38e116a4015d1..0371f3ea642b641aa9477be30618c73847885a4a 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * This file is part of DisOrder.
 /*
  * This file is part of DisOrder.
- * Copyright (C) 2004-2009 Richard Kettlewell
+ * Copyright (C) 2004-2010 Richard Kettlewell
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -320,6 +320,8 @@ char *config_usersysconf(const struct passwd *pw );
 char *config_private(void);
 /* get the private config file */
 
 char *config_private(void);
 /* get the private config file */
 
+int config_verify(void);
+
 extern char *configfile;
 extern int config_per_user;
 
 extern char *configfile;
 extern int config_per_user;
 
index 72e38769726442557231928b0d28a2743ebdabf2..c287ebe950afd4eb9ce55e989be998c6c1713796 100644 (file)
@@ -188,6 +188,13 @@ struct queue_entry {
   /** @brief How much of track has been played so far (seconds) */
   long sofar;
 
   /** @brief How much of track has been played so far (seconds) */
   long sofar;
 
+  /** @brief True if track preparation is underway
+   *
+   * This is set when a decoder has been started and is expected to connect to
+   * the speaker, but the speaker has not sent as @ref SM_ARRIVED message back
+   * yet. */
+  int preparing;
+
   /** @brief True if decoder is connected to speaker 
    *
    * This is not a @ref playing_state for a couple of reasons
   /** @brief True if decoder is connected to speaker 
    *
    * This is not a @ref playing_state for a couple of reasons
index 3b21f0a8ef8821f21f5a25a3fa844e2a1964c520..24fc970587d7f748e1b6aa3db3e23a9fe2b58d69 100644 (file)
@@ -43,6 +43,7 @@ struct speaker_message {
    * - @ref SM_FINISHED
    * - @ref SM_PLAYING
    * - @ref SM_UNKNOWN
    * - @ref SM_FINISHED
    * - @ref SM_PLAYING
    * - @ref SM_UNKNOWN
+   * - @ref SM_ARRIVED
    */
   int type;
 
    */
   int type;
 
@@ -102,6 +103,9 @@ struct speaker_message {
 /** @brief Cancelled track @c id which wasn't playing */
 #define SM_STILLBORN 133
 
 /** @brief Cancelled track @c id which wasn't playing */
 #define SM_STILLBORN 133
 
+/** @brief A connection for track @c id arrived */
+#define SM_ARRIVED 134
+
 void speaker_send(int fd, const struct speaker_message *sm);
 /* Send a message. */
 
 void speaker_send(int fd, const struct speaker_message *sm);
 /* Send a message. */
 
index 7be6c510063f1ebfdaf388969523409b7c5e5087..de3562b15506c47eaaaa89dea206597f289e29f2 100644 (file)
@@ -20,7 +20,8 @@ TESTS=t-addr t-arcfour t-basen t-bits t-cache t-casefold t-charset    \
        t-cookies t-dateparse t-event t-filepart t-hash t-heap t-hex    \
        t-kvp t-mime t-printf t-regsub t-selection t-signame t-sink     \
        t-split t-syscalls t-trackname t-unicode t-url t-utf8 t-vector  \
        t-cookies t-dateparse t-event t-filepart t-hash t-heap t-hex    \
        t-kvp t-mime t-printf t-regsub t-selection t-signame t-sink     \
        t-split t-syscalls t-trackname t-unicode t-url t-utf8 t-vector  \
-       t-words t-wstat t-macros t-cgi t-eventdist t-resample
+       t-words t-wstat t-macros t-cgi t-eventdist t-resample           \
+       t-configuration
 
 noinst_PROGRAMS=$(TESTS)
 
 
 noinst_PROGRAMS=$(TESTS)
 
@@ -63,6 +64,8 @@ t_wstat_SOURCES=t-wstat.c test.c test.h
 t_eventdist_SOURCES=t-eventdist.c test.c test.h
 t_resample_SOURCES=t-resample.c test.c test.h
 t_resample_LDFLAGS=$(LIBSAMPLERATE)
 t_eventdist_SOURCES=t-eventdist.c test.c test.h
 t_resample_SOURCES=t-resample.c test.c test.h
 t_resample_LDFLAGS=$(LIBSAMPLERATE)
+t_configuration_SOURCES=t-configuration.c test.c test.h
+t_configuration_LDFLAGS=$(LIBGCRYPT)
 
 check-report: before-check check make-coverage-reports
 before-check:
 
 check-report: before-check check make-coverage-reports
 before-check:
diff --git a/libtests/t-configuration.c b/libtests/t-configuration.c
new file mode 100644 (file)
index 0000000..4ff7b18
--- /dev/null
@@ -0,0 +1,33 @@
+/*
+ * This file is part of DisOrder.
+ * Copyright (C) 2010 Richard Kettlewell
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+#include "test.h"
+
+static void test_configuration(void) {
+  insist(config_verify() == 0);
+}
+
+TEST(configuration);
+
+/*
+Local Variables:
+c-basic-offset:2
+comment-column:40
+fill-column:79
+indent-tabs-mode:nil
+End:
+*/
index 9f54d615bf77d547fd240b2412d14f971f360855..8f1bd1dac3fff0cb0d7f491fdf63cfcd2eeb67cc 100644 (file)
@@ -96,6 +96,19 @@ static int speaker_readable(ev_source *ev, int fd,
     D(("SM_PLAYING %s %ld", sm.id, sm.data));
     playing->sofar = sm.data;
     break;
     D(("SM_PLAYING %s %ld", sm.id, sm.data));
     playing->sofar = sm.data;
     break;
+  case SM_ARRIVED: {
+    /* track ID is now prepared */
+    struct queue_entry *q;
+    for(q = qhead.next; q != &qhead && strcmp(q->id, sm.id); q = q->next)
+      ;
+    if(q && q->preparing) {
+      q->preparing = 0;
+      q->prepared = 1;
+      /* We might be waiting to play the now-prepared track */
+      play(ev);
+    }
+    break;
+  }
   default:
     disorder_error(0, "unknown speaker message type %d", sm.type);
   }
   default:
     disorder_error(0, "unknown speaker message type %d", sm.type);
   }
@@ -379,7 +392,7 @@ int prepare(ev_source *ev,
   if(q->pid >= 0)
     return START_OK;
   /* If the track is already prepared, do nothing */
   if(q->pid >= 0)
     return START_OK;
   /* If the track is already prepared, do nothing */
-  if(q->prepared)
+  if(q->prepared || q->preparing)
     return START_OK;
   /* Find the player plugin */
   if(!(player = find_player(q)) < 0) 
     return START_OK;
   /* Find the player plugin */
   if(!(player = find_player(q)) < 0) 
@@ -388,10 +401,12 @@ int prepare(ev_source *ev,
   q->type = play_get_type(q->pl);
   if((q->type & DISORDER_PLAYER_TYPEMASK) != DISORDER_PLAYER_RAW)
     return START_OK;                    /* Not a raw player */
   q->type = play_get_type(q->pl);
   if((q->type & DISORDER_PLAYER_TYPEMASK) != DISORDER_PLAYER_RAW)
     return START_OK;                    /* Not a raw player */
-  const int rc = play_background(ev, player, q, prepare_child, NULL);
+  int rc = play_background(ev, player, q, prepare_child, NULL);
   if(rc == START_OK) {
     ev_child(ev, q->pid, 0, player_finished, q);
   if(rc == START_OK) {
     ev_child(ev, q->pid, 0, player_finished, q);
-    q->prepared = 1;
+    q->preparing = 1;
+    /* Actually the track is still "in flight" */
+    rc = START_SOFTFAIL;
   }
   return rc;
 }
   }
   return rc;
 }
index de5692b9fe7b91e5b24453e867dddc244a2e8234..ccdf1e11aecff9115670a2dc46049ecd7bf7d294 100644 (file)
@@ -529,6 +529,10 @@ static void mainloop(void) {
             nonblock(fd);
             t->fd = fd;               /* yay */
           }
             nonblock(fd);
             t->fd = fd;               /* yay */
           }
+          /* Notify the server that the connection arrived */
+          sm.type = SM_ARRIVED;
+          strcpy(sm.id, id);
+          speaker_send(1, &sm);
         }
       } else
         disorder_error(errno, "accept");
         }
       } else
         disorder_error(errno, "accept");