chiark / gitweb /
disorder-choose rejects tracks in queue/recent list
[disorder] / server / speaker.c
index e4a00bead0389c30b4451683cfea22d27b504751..bcc44ccbf69a7fcf2d67339c19ac41661db4867d 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * This file is part of DisOrder
- * Copyright (C) 2005, 2006, 2007 Richard Kettlewell
+ * Copyright (C) 2005-2008 Richard Kettlewell
  * Portions (C) 2007 Mark Wooding
  *
  * This program is free software; you can redistribute it and/or modify
@@ -35,7 +35,7 @@
  * this is arranged by the @c disorder-normalize program (see @ref
  * server/normalize.c).
  *
- * @b Garbage @b Collection.  This program deliberately does not use the
+7 * @b Garbage @b Collection.  This program deliberately does not use the
  * garbage collector even though it might be convenient to do so.  This is for
  * two reasons.  Firstly some sound APIs use thread threads and we do not want
  * to have to deal with potential interactions between threading and garbage
@@ -69,6 +69,7 @@
 #include <fcntl.h>
 #include <poll.h>
 #include <sys/un.h>
+#include <sys/stat.h>
 
 #include "configuration.h"
 #include "syscalls.h"
@@ -79,6 +80,7 @@
 #include "user.h"
 #include "speaker.h"
 #include "printf.h"
+#include "version.h"
 
 /** @brief Linked list of all prepared tracks */
 struct track *tracks;
@@ -141,13 +143,6 @@ static void help(void) {
   exit(0);
 }
 
-/* Display version number and terminate. */
-static void version(void) {
-  xprintf("%s", disorder_version_string);
-  xfclose(stdout);
-  exit(0);
-}
-
 /** @brief Return the number of bytes per frame in @p format */
 static size_t bytes_per_frame(const struct stream_header *format) {
   return format->channels * format->bits / 8;
@@ -552,18 +547,31 @@ static void mainloop(void) {
           report();
          break;
        case SM_CANCEL:
-          D(("SM_CANCEL %s",  sm.id));
+          D(("SM_CANCEL %s", sm.id));
          t = removetrack(sm.id);
          if(t) {
            if(t == playing) {
+              /* scratching the playing track */
               sm.type = SM_FINISHED;
-              strcpy(sm.id, playing->id);
-              speaker_send(1, &sm);
              playing = 0;
+            } else {
+              /* Could be scratching the playing track before it's quite got
+               * going, or could be just removing a track from the queue.  We
+               * log more because there's been a bug here recently than because
+               * it's particularly interesting; the log message will be removed
+               * if no further problems show up. */
+              info("SM_CANCEL for nonplaying track %s", sm.id);
+              sm.type = SM_STILLBORN;
             }
+            strcpy(sm.id, t->id);
            destroy(t);
-         } else
+         } else {
+            /* Probably scratching the playing track well before it's got
+             * going, but could indicate a bug, so we log this as an error. */
+            sm.type = SM_UNKNOWN;
            error(0, "SM_CANCEL for unknown track %s", sm.id);
+          }
+          speaker_send(1, &sm);
           report();
          break;
        case SM_RELOAD:
@@ -606,7 +614,7 @@ int main(int argc, char **argv) {
   while((n = getopt_long(argc, argv, "hVc:dDSs", options, 0)) >= 0) {
     switch(n) {
     case 'h': help();
-    case 'V': version();
+    case 'V': version("disorder-speaker");
     case 'c': configfile = optarg; break;
     case 'd': debugging = 1; break;
     case 'D': debugging = 0; break;
@@ -634,17 +642,17 @@ int main(int argc, char **argv) {
   if(getuid() == 0 || geteuid() == 0) fatal(0, "do not run as root");
   /* identify the backend used to play */
   for(n = 0; backends[n]; ++n)
-    if(backends[n]->backend == config->speaker_backend)
+    if(backends[n]->backend == config->api)
       break;
   if(!backends[n])
-    fatal(0, "unsupported backend %d", config->speaker_backend);
+    fatal(0, "unsupported api %d", config->api);
   backend = backends[n];
   /* backend-specific initialization */
   backend->init();
   /* create the socket directory */
   byte_xasprintf(&dir, "%s/speaker", config->home);
   unlink(dir);                          /* might be a leftover socket */
-  if(mkdir(dir, 0700) < 0)
+  if(mkdir(dir, 0700) < 0 && errno != EEXIST)
     fatal(errno, "error creating %s", dir);
   /* set up the listen socket */
   listenfd = xsocket(PF_UNIX, SOCK_STREAM, 0);