From 2a1c84fb58e4caaa7a91991846b36ef2cfa8dd9f Mon Sep 17 00:00:00 2001 Message-Id: <2a1c84fb58e4caaa7a91991846b36ef2cfa8dd9f.1715065724.git.mdw@distorted.org.uk> From: Mark Wooding Date: Sun, 14 Feb 2010 10:19:50 +0000 Subject: [PATCH] Correct ordering of configuration key table. Add a test to ensure it stays correct in the future! Organization: Straylight/Edgeware From: Richard Kettlewell --- .bzrignore | 1 + lib/configuration.c | 19 ++++++++++++++++--- lib/configuration.h | 4 +++- lib/queue.h | 7 +++++++ lib/speaker-protocol.h | 4 ++++ libtests/Makefile.am | 5 ++++- libtests/t-configuration.c | 33 +++++++++++++++++++++++++++++++++ server/play.c | 21 ++++++++++++++++++--- server/speaker.c | 4 ++++ 9 files changed, 90 insertions(+), 8 deletions(-) create mode 100644 libtests/t-configuration.c diff --git a/.bzrignore b/.bzrignore index 30d6e0d..150c85c 100644 --- a/.bzrignore +++ b/.bzrignore @@ -172,6 +172,7 @@ libtests/t-words libtests/t-wstat libtests/t-macros libtests/t-cgi +libtests/t-configuration doc/*.tmpl doc/disorder_templates.5 oc/disorder_templates.5.html diff --git a/lib/configuration.c b/lib/configuration.c index e2af880..98d672b 100644 --- a/lib/configuration.c +++ b/lib/configuration.c @@ -1,6 +1,6 @@ /* * 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 @@ -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(cookie_login_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 }, @@ -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(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(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 }, @@ -1729,6 +1729,19 @@ static int namepartlist_compare(const struct namepartlist *a, 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 diff --git a/lib/configuration.h b/lib/configuration.h index 9170a2f..0371f3e 100644 --- a/lib/configuration.h +++ b/lib/configuration.h @@ -1,6 +1,6 @@ /* * 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 @@ -320,6 +320,8 @@ char *config_usersysconf(const struct passwd *pw ); char *config_private(void); /* get the private config file */ +int config_verify(void); + extern char *configfile; extern int config_per_user; diff --git a/lib/queue.h b/lib/queue.h index 72e3876..c287ebe 100644 --- a/lib/queue.h +++ b/lib/queue.h @@ -188,6 +188,13 @@ struct queue_entry { /** @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 diff --git a/lib/speaker-protocol.h b/lib/speaker-protocol.h index 3b21f0a..24fc970 100644 --- a/lib/speaker-protocol.h +++ b/lib/speaker-protocol.h @@ -43,6 +43,7 @@ struct speaker_message { * - @ref SM_FINISHED * - @ref SM_PLAYING * - @ref SM_UNKNOWN + * - @ref SM_ARRIVED */ int type; @@ -102,6 +103,9 @@ struct speaker_message { /** @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. */ diff --git a/libtests/Makefile.am b/libtests/Makefile.am index 7be6c51..de3562b 100644 --- a/libtests/Makefile.am +++ b/libtests/Makefile.am @@ -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-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) @@ -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_configuration_SOURCES=t-configuration.c test.c test.h +t_configuration_LDFLAGS=$(LIBGCRYPT) 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 index 0000000..4ff7b18 --- /dev/null +++ b/libtests/t-configuration.c @@ -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 . + */ +#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: +*/ diff --git a/server/play.c b/server/play.c index 9f54d61..8f1bd1d 100644 --- a/server/play.c +++ b/server/play.c @@ -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; + 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); } @@ -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->prepared) + if(q->prepared || q->preparing) 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 */ - 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); - q->prepared = 1; + q->preparing = 1; + /* Actually the track is still "in flight" */ + rc = START_SOFTFAIL; } return rc; } diff --git a/server/speaker.c b/server/speaker.c index de5692b..ccdf1e1 100644 --- a/server/speaker.c +++ b/server/speaker.c @@ -529,6 +529,10 @@ static void mainloop(void) { 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"); -- [mdw]