]> git.ipfire.org Git - thirdparty/shairport-sync.git/commitdiff
Make debuglev volatile, over player_vol past the cleanup push, add some temporary...
authorMike Brady <mikebrady@eircom.net>
Mon, 19 Nov 2018 14:24:24 +0000 (14:24 +0000)
committerMike Brady <mikebrady@eircom.net>
Mon, 19 Nov 2018 14:24:24 +0000 (14:24 +0000)
common.c
common.h
player.c
rtsp.c

index 3ba442d4e951dccb987ae71ee5a19fd2a4e99882..e47249541ab58cdc7c8b445ea3efce4fd138837e 100644 (file)
--- a/common.c
+++ b/common.c
@@ -90,7 +90,7 @@ static volatile int requested_connection_state_to_output = 1;
 
 shairport_cfg config;
 
-int debuglev = 0;
+volatile int debuglev = 0;
 
 sigset_t pselect_sigset;
 
@@ -588,6 +588,7 @@ int config_set_lookup_bool(config_t *cfg, char *where, int *dst) {
 }
 
 void command_set_volume(double volume) {
+//this has a cancellation point if waiting is enabled
   if (config.cmd_set_volume) {
     /*Spawn a child to run the program.*/
     pid_t pid = fork();
@@ -634,6 +635,7 @@ void command_set_volume(double volume) {
 }
 
 void command_start(void) {
+       //this has a cancellation point if waiting is enabled or a response is awaited
   if (config.cmd_start) {
     pid_t pid;
     int pipes[2];
@@ -701,6 +703,7 @@ void command_start(void) {
 }
 
 void command_stop(void) {
+//this has a cancellation point if waiting is enabled
   if (config.cmd_stop) {
     /*Spawn a child to run the program.*/
     pid_t pid = fork();
index c9674c417d069571bc8782fb9327c8f1af03e62f..81aab4cb5cf20cf632cb0935d5653d4e25af03e6 100644 (file)
--- a/common.h
+++ b/common.h
@@ -243,7 +243,7 @@ void r64arrayinit();
 uint64_t ranarray64u();
 int64_t ranarray64i();
 
-extern int debuglev;
+volatile int debuglev;
 void die(const char *format, ...);
 void warn(const char *format, ...);
 void inform(const char *format, ...);
index 2d392c2cec9ff54debb2ad0c29412bb0703ce76e..41e528a57acf46ad9e4bfa60732832415f1651f6 100644 (file)
--- a/player.c
+++ b/player.c
@@ -831,9 +831,7 @@ static abuf_t *buffer_get_frame(rtsp_conn_info *conn) {
 
     uint32_t flush_limit = 0;
     if (conn->ab_synced) {
-      int frame_flushed;
       do {
-        frame_flushed = 0;
         curframe = conn->audio_buffer + BUFIDX(conn->ab_read);
         if ((conn->ab_read != conn->ab_write) &&
             (curframe->ready)) { // it could be synced and empty, under
@@ -864,7 +862,6 @@ static abuf_t *buffer_get_frame(rtsp_conn_info *conn) {
             curframe->resend_level = 0;
             flush_limit += curframe->length;
             conn->ab_read = SUCCESSOR(conn->ab_read);
-            frame_flushed = 1;
             conn->initial_reference_time = 0;
             conn->initial_reference_timestamp = 0;
           }
@@ -874,11 +871,8 @@ static abuf_t *buffer_get_frame(rtsp_conn_info *conn) {
             debug(2, "Dropping flush request in buffer_get_frame");
             conn->flush_rtp_timestamp = 0;
           }
-        } else {
-          if (curframe->ready == 0)
-            debug(1, "An unready frame was seen in a flush sequence!");
         }
-      } while ((conn->flush_rtp_timestamp != 0) && (flush_limit <= 8820) && (frame_flushed));
+      } while ((conn->flush_rtp_timestamp != 0) && (flush_limit <= 8820) && (curframe->ready == 0));
 
       if (flush_limit == 8820) {
         debug(1, "Flush hit the 8820 frame limit!");
@@ -1410,11 +1404,14 @@ typedef struct stats { // statistics for running averages
   int64_t sync_error, correction, drift;
 } stats_t;
 
-void player_thread_cleanup_handler(void *arg) {
-  debug(1, "player_thread_cleanup_handler called");
+void player_thread_initial_cleanup_handler(__attribute__((unused)) void *arg) {
   rtsp_conn_info *conn = (rtsp_conn_info *)arg;
+  debug(3, "Connection %d: player thread main loop exit via player_thread_initial_cleanup_handler.", conn->connection_number);
+}
 
-  debug(3, "Connection %d: player thread main loop exit.", conn->connection_number);
+void player_thread_cleanup_handler(void *arg) {
+  rtsp_conn_info *conn = (rtsp_conn_info *)arg;
+  debug(3, "Connection %d: player thread main loop exit via player_thread_cleanup_handler.", conn->connection_number);
 
   if (config.statistics_requested) {
     int rawSeconds = (int)difftime(time(NULL), conn->playstart);
@@ -1486,7 +1483,7 @@ void player_thread_cleanup_handler(void *arg) {
 
 void *player_thread_func(void *arg) {
   rtsp_conn_info *conn = (rtsp_conn_info *)arg;
-
+  pthread_cleanup_push(player_thread_initial_cleanup_handler, arg);
   conn->packet_count = 0;
   conn->packet_count_since_flush = 0;
   conn->previous_random_number = 0;
@@ -1510,7 +1507,7 @@ void *player_thread_func(void *arg) {
                conn); // this sets up incoming rate, bit depth, channels.
                       // No pthread cancellation point in here
   // This must be after init_decoder
-  init_buffer(conn); // will need a corresponding deallocation
+  init_buffer(conn); // will need a corresponding deallocation. No cancellation points in here
 
   if (conn->stream.encrypted) {
 #ifdef CONFIG_MBEDTLS
@@ -1694,7 +1691,7 @@ void *player_thread_func(void *arg) {
     debug(1, "DACP monitor already initialised?");
   else
     // this does not have pthread cancellation points in it (assuming avahi doesn't)
-    conn->dapo_private_storage = mdns_dacp_monitor(conn->dacp_id); // ??
+    conn->dapo_private_storage = mdns_dacp_monitor(conn->dacp_id);
 #endif
 
   conn->framesProcessedInThisEpoch = 0;
@@ -1752,9 +1749,6 @@ void *player_thread_func(void *arg) {
     }
   }
 
-  // set the default volume to whaterver it was before, as stored in the config airplay_volume
-  debug(3, "Set initial volume to %f.", config.airplay_volume);
-  player_volume(config.airplay_volume, conn); // ??
   int64_t frames_to_drop = 0;
 
   // create and start the timing, control and audio receiver threads
@@ -1764,6 +1758,10 @@ void *player_thread_func(void *arg) {
 
   pthread_cleanup_push(player_thread_cleanup_handler, arg); // undo what's been done so far
 
+  // set the default volume to whaterver it was before, as stored in the config airplay_volume
+  debug(2, "Set initial volume to %f.", config.airplay_volume);
+  player_volume(config.airplay_volume, conn); // will contain a cancellation point if asked to wait
+
   debug(2, "Play begin");
   while (1) {
     abuf_t *inframe = buffer_get_frame(conn); // this has cancellation point(s)
@@ -2480,8 +2478,10 @@ void *player_thread_func(void *arg) {
   }
 
   debug(1, "This should never be called.");
-  pthread_cleanup_pop(1);
-  pthread_exit(NULL);
+  pthread_cleanup_pop(1); // pop the cleanup handler
+  debug(1, "This should never be called either.");
+  pthread_cleanup_pop(1); // pop the initial cleanup handler
+  pthread_exit(NULL); 
 }
 
 // takes the volume as specified by the airplay protocol
@@ -2756,11 +2756,9 @@ int player_play(rtsp_conn_info *conn) {
   if (config.buffer_start_fill > BUFFER_FRAMES)
     die("specified buffer starting fill %d > buffer size %d", config.buffer_start_fill,
         BUFFER_FRAMES);
+  debug(1,"Executing the run_this_before_play_begins hook, if any.");
   command_start();
-#ifdef CONFIG_METADATA
-  debug(2, "pbeg");
-  send_ssnc_metadata('pbeg', NULL, 0, 1); // contains cancellation points
-#endif
+  debug(1,"Create a player thread...");
   pthread_t *pt = malloc(sizeof(pthread_t));
   if (pt == NULL)
     die("Couldn't allocate space for pthread_t");
@@ -2772,16 +2770,22 @@ int player_play(rtsp_conn_info *conn) {
   if (rc)
     debug(1, "Error setting stack size for player_thread: %s", strerror(errno));
   // finished initialising.
-  pthread_create(pt, &tattr, player_thread_func, (void *)conn);
+  rc = pthread_create(pt, &tattr, player_thread_func, (void *)conn);
+  if (rc)
+    debug(1, "Error creating player_thread: %s", strerror(errno));
   pthread_attr_destroy(&tattr);
+  debug(1,"Player thread successfully created.");
+#ifdef CONFIG_METADATA
+  debug(2, "pbeg");
+  send_ssnc_metadata('pbeg', NULL, 0, 1); // contains cancellation points
+#endif
   return 0;
 }
 
 int player_stop(rtsp_conn_info *conn) {
-  int dl = debuglev;
-  if (debuglev)
-    debuglev = 3;
   // note -- this may be called from another connection thread.
+  int dl = debuglev;
+  debuglev = 3;
   debug(3, "player_stop");
   if (conn->player_thread) {
     debug(2, "player_thread cancel...");
@@ -2795,12 +2799,12 @@ int player_stop(rtsp_conn_info *conn) {
     debug(2, "pend");
     send_ssnc_metadata('pend', NULL, 0, 1); // contains cancellation points
 #endif
-    debuglev = dl;
+       debuglev = dl;
     command_stop();
     return 0;
   } else {
-    debug(3, "player_stop: player thread not running on connection %d.", conn->connection_number);
-    debuglev = dl;
+    debug(3, "Connection %d: player thread already deleted.", conn->connection_number);
+  debuglev = dl;
     return -1;
   }
 }
diff --git a/rtsp.c b/rtsp.c
index 352088cb859eaba50d9f23c9aee29a4d58066402..5b887eb7ac8f1d28fd6a5083fafc1eb5949e6c11 100644 (file)
--- a/rtsp.c
+++ b/rtsp.c
@@ -2098,11 +2098,8 @@ static void *rtsp_conversation_thread_func(void *pconn) {
       if (conn->stop == 0) {
         int err = msg_write_response(conn->fd, resp);
         if (err) {
-               int odv = debuglev;
-               debuglev = 3;
                debug(1,"A communication error was detected. Closing the play session.");
                player_stop(conn);
-               debuglev = odv;
         }
       }
       pthread_cleanup_pop(1);