]> git.ipfire.org Git - thirdparty/shairport-sync.git/commitdiff
Move watchdog to cover connection from start, not just from start of play. Start...
authorMike Brady <mikebrady@eircom.net>
Wed, 28 Nov 2018 17:18:03 +0000 (17:18 +0000)
committerMike Brady <mikebrady@eircom.net>
Wed, 28 Nov 2018 17:18:03 +0000 (17:18 +0000)
audio_alsa.c
common.c
player.c
rtp.c
rtsp.c
shairport.c

index dc6f11d816d4a01e4b25a22149bc0855a5cdc05e..00c33900306e0954ee1befe36d69244bb223bd13 100644 (file)
@@ -980,7 +980,7 @@ static int play(void *buf, int samples) {
       if (samples == 0)
         debug(1, "empty buffer being passed to pcm_writei -- skipping it");
       if ((samples != 0) && (buf != NULL)) {
-       debug(3,"write %d frames.",samples);
+        debug(3, "write %d frames.", samples);
         err = alsa_pcm_write(alsa_handle, buf, samples);
         if (err < 0) {
           frame_index = 0;
@@ -1066,7 +1066,7 @@ static void flush(void) {
 
     if ((derr = snd_pcm_hw_free(alsa_handle)))
       debug(1, "Error %d (\"%s\") freeing the output device hardware.", derr, snd_strerror(derr));
-    
+
     // flush also closes the device
     if ((derr = snd_pcm_close(alsa_handle)))
       debug(1, "Error %d (\"%s\") closing the output device.", derr, snd_strerror(derr));
index 0d76a4f42f6439b989a5522165be62806eb6f49f..76cf8204b1754002e8b043f559c2de81a4e51ca1 100644 (file)
--- a/common.c
+++ b/common.c
@@ -96,7 +96,10 @@ sigset_t pselect_sigset;
 
 static uint16_t UDPPortIndex = 0;
 
-void resetFreeUDPPort() { UDPPortIndex = 0; }
+void resetFreeUDPPort() {
+       debug(1,"Resetting UDP Port Suggestion to %u",config.udp_port_base);
+       UDPPortIndex = 0;
+}
 
 uint16_t nextFreeUDPPort() {
   if (UDPPortIndex == 0)
index 3507db6b49565e855c905a77f094d9bf987ac4bf..4e2bfc4fed81824e55533e84937224bce0a3962d 100644 (file)
--- a/player.c
+++ b/player.c
@@ -114,7 +114,6 @@ uint64_t modulo_64_offset(uint64_t from, uint64_t to) {
 }
 
 void do_flush(uint32_t timestamp, rtsp_conn_info *conn);
-void *player_watchdog_thread_code(void *arg);
 
 static void ab_resync(rtsp_conn_info *conn) {
   int i;
@@ -1431,12 +1430,6 @@ void player_thread_cleanup_handler(void *arg) {
 #endif
 
   debug(2, "Cancelling timing, control and audio threads...");
-  debug(2, "Cancel watchdog thread.");
-  pthread_cancel(conn->player_watchdog_thread);
-  debug(2, "Join watchdog thread.");
-  pthread_join(conn->player_watchdog_thread, NULL);
-  debug(2, "Delete watchdog mutex.");
-  pthread_mutex_destroy(&conn->watchdog_mutex);
   debug(2, "Cancel timing thread.");
   pthread_cancel(conn->rtp_timing_thread);
   debug(2, "Join timing thread.");
@@ -1730,10 +1723,6 @@ void *player_thread_func(void *arg) {
   pthread_create(&conn->rtp_control_thread, NULL, &rtp_control_receiver, (void *)conn);
   pthread_create(&conn->rtp_timing_thread, NULL, &rtp_timing_receiver, (void *)conn);
 
-  // create the watchdog mutex and start the watchdog thread;
-  pthread_mutex_init(&conn->watchdog_mutex, NULL);
-  pthread_create(&conn->player_watchdog_thread, NULL, &player_watchdog_thread_code, (void *)conn);
-
   pthread_cleanup_push(player_thread_cleanup_handler, arg); // undo what's been done so far
 
 // stop looking elsewhere for DACP stuff
@@ -2799,38 +2788,4 @@ int player_stop(rtsp_conn_info *conn) {
     // debuglev = dl;
     return -1;
   }
-}
-
-void player_watchdog_thread_cleanup_handler(void *arg) {
-  rtsp_conn_info *conn = (rtsp_conn_info *)arg;
-  debug(2, "Connection %d: Watchdog Exit.", conn->connection_number);
-}
-
-void *player_watchdog_thread_code(void *arg) {
-  pthread_cleanup_push(player_watchdog_thread_cleanup_handler, arg);
-  rtsp_conn_info *conn = (rtsp_conn_info *)arg;
-  do {
-    usleep(2000000); // check every two seconds
-    debug(3, "Connection %d: Check the player thread is doing something...",
-          conn->connection_number);
-    if ((config.dont_check_timeout == 0) && (config.timeout != 0)) {
-      debug_mutex_lock(&conn->watchdog_mutex, 1000, 0);
-      uint64_t last_watchdog_bark_time = conn->watchdog_bark_time;
-      debug_mutex_unlock(&conn->watchdog_mutex, 0);
-      if (last_watchdog_bark_time != 0) {
-        uint64_t time_since_last_bark = (get_absolute_time_in_fp() - last_watchdog_bark_time) >> 32;
-        uint64_t ct = config.timeout; // go from int to 64-bit int
-
-        if (time_since_last_bark >= ct) {
-          debug(1, "Connection %d: As Yeats almost said, \"Too long a silence / can make a stone "
-                   "of the heart\".",
-                conn->connection_number);
-          conn->stop = 1;
-          pthread_cancel(conn->thread);
-        }
-      }
-    }
-  } while (1);
-  pthread_cleanup_pop(0); // should never happen
-  pthread_exit(NULL);
-}
+}
\ No newline at end of file
diff --git a/rtp.c b/rtp.c
index dba32390cbbc9528df81280ff39f6c58e5dde44b..1f908b0e550eb55b07fba1bd3bb9e079a49fa784 100644 (file)
--- a/rtp.c
+++ b/rtp.c
@@ -890,9 +890,14 @@ static uint16_t bind_port(int ip_family, const char *self_ip_address, uint32_t s
 
   if (ret < 0) {
     close(local_socket);
-    die("error: could not bind a UDP port! Check the udp_port_range is large enough -- it must be "
+    char errorstring[1024];
+    strerror_r(errno, (char *)errorstring, sizeof(errorstring));
+    die("error %d: \"%s\". Could not bind a UDP port! Check the udp_port_range is large enough -- "
+        "it must be "
         "at least 3, and 10 or more is suggested -- or "
-        "check for restrictive firewall settings or a bad router!");
+        "check for restrictive firewall settings or a bad router! UDP base is %u, range is %u and "
+        "current suggestion is %u.",
+        errno, errorstring, config.udp_port_base, config.udp_port_range, desired_port);
   }
 
   uint16_t sport;
diff --git a/rtsp.c b/rtsp.c
index 478f20e64506d385210c5692c5e5261152475f41..beaaf8f788778d691bf931165ca4e2b04b612474 100644 (file)
--- a/rtsp.c
+++ b/rtsp.c
@@ -253,6 +253,39 @@ int pc_queue_get_item(pc_queue *the_queue, void *the_stuff) {
 
 #endif
 
+void player_watchdog_thread_cleanup_handler(void *arg) {
+  rtsp_conn_info *conn = (rtsp_conn_info *)arg;
+  debug(2, "Connection %d: Watchdog Exit.", conn->connection_number);
+}
+
+void *player_watchdog_thread_code(void *arg) {
+  pthread_cleanup_push(player_watchdog_thread_cleanup_handler, arg);
+  rtsp_conn_info *conn = (rtsp_conn_info *)arg;
+  do {
+    usleep(2000000); // check every two seconds
+    debug(3, "Connection %d: Check the thread is doing something...", conn->connection_number);
+    if ((config.dont_check_timeout == 0) && (config.timeout != 0)) {
+      debug_mutex_lock(&conn->watchdog_mutex, 1000, 0);
+      uint64_t last_watchdog_bark_time = conn->watchdog_bark_time;
+      debug_mutex_unlock(&conn->watchdog_mutex, 0);
+      if (last_watchdog_bark_time != 0) {
+        uint64_t time_since_last_bark = (get_absolute_time_in_fp() - last_watchdog_bark_time) >> 32;
+        uint64_t ct = config.timeout; // go from int to 64-bit int
+
+        if (time_since_last_bark >= ct) {
+          debug(1, "Connection %d: As Yeats almost said, \"Too long a silence / can make a stone "
+                   "of the heart\".",
+                conn->connection_number);
+          conn->stop = 1;
+          pthread_cancel(conn->thread);
+        }
+      }
+    }
+  } while (1);
+  pthread_cleanup_pop(0); // should never happen
+  pthread_exit(NULL);
+}
+
 void ask_other_rtsp_conversation_threads_to_stop(pthread_t except_this_thread);
 
 void rtsp_request_shutdown_stream(void) {
@@ -425,9 +458,9 @@ static void debug_print_msg_content(int level, rtsp_message *msg) {
 void msg_free(rtsp_message *msg) {
 
   if (msg) {
-    debug_mutex_lock(&reference_counter_lock,1000,3);
+    debug_mutex_lock(&reference_counter_lock, 1000, 3);
     msg->referenceCount--;
-    debug_mutex_unlock(&reference_counter_lock,3);
+    debug_mutex_unlock(&reference_counter_lock, 3);
     if (msg->referenceCount == 0) {
       unsigned int i;
       for (i = 0; i < msg->nheaders; i++) {
@@ -695,10 +728,9 @@ int msg_write_response(int fd, rtsp_message *resp) {
   ssize_t reply = write(fd, pkt, p - pkt);
   if (reply == -1) {
     char errorstring[1024];
-      strerror_r(errno, (char *)errorstring, sizeof(errorstring));
-      debug(1, "msg_write_response error %d: \"%s\".",
-            errno, (char *)errorstring);
-      return -4; 
+    strerror_r(errno, (char *)errorstring, sizeof(errorstring));
+    debug(1, "msg_write_response error %d: \"%s\".", errno, (char *)errorstring);
+    return -4;
   }
   if (reply != p - pkt) {
     debug(1, "msg_write_response error -- requested bytes not fully written.");
@@ -890,12 +922,14 @@ void handle_setup(rtsp_conn_info *conn, rtsp_message *req, rtsp_message *resp) {
                                      "timing_port=%d;server_"
                                      "port=%d",
            conn->local_control_port, conn->local_timing_port, conn->local_audio_port);
+  
 
   msg_add_header(resp, "Transport", resphdr);
 
   msg_add_header(resp, "Session", "1");
 
   resp->respcode = 200;
+  debug(1, "Connection %d: SETUP with UDP ports Control: %d, Timing: %d and Audio: %d.", conn->connection_number, conn->local_control_port, conn->local_timing_port, conn->local_audio_port);
   return;
 
 error:
@@ -2002,9 +2036,9 @@ void rtsp_conversation_thread_cleanup_function(void *arg) {
   if (conn->player_thread)
     player_stop(conn);
   if (conn->fd > 0) {
-    debug(3, "Connection %d: closing fd %d.", conn->connection_number,conn->fd);
+    debug(3, "Connection %d: closing fd %d.", conn->connection_number, conn->fd);
     close(conn->fd);
-    debug(3, "Connection %d: closed fd %d.", conn->connection_number,conn->fd);
+    debug(3, "Connection %d: closed fd %d.", conn->connection_number, conn->fd);
   }
   if (conn->auth_nonce) {
     free(conn->auth_nonce);
@@ -2035,7 +2069,17 @@ void rtsp_conversation_thread_cleanup_function(void *arg) {
     debug(3, "Connection %d: Unlocking play lock.", conn->connection_number);
     playing_conn = NULL;
   }
+
   debug_mutex_unlock(&playing_conn_lock, 3);
+  debug(2, "Cancel watchdog thread.");
+  pthread_cancel(conn->player_watchdog_thread);
+  int oldState;
+  pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldState);
+  debug(2, "Join watchdog thread.");
+  pthread_join(conn->player_watchdog_thread, NULL);
+  pthread_setcancelstate(oldState, NULL);
+  debug(2, "Delete watchdog mutex.");
+  pthread_mutex_destroy(&conn->watchdog_mutex);
 
   debug(2, "Connection %d: RTSP thread terminated.", conn->connection_number);
   conn->running = 0;
@@ -2049,6 +2093,10 @@ void msg_cleanup_function(void *arg) {
 static void *rtsp_conversation_thread_func(void *pconn) {
   rtsp_conn_info *conn = pconn;
 
+  // create the watchdog mutex and start the watchdog thread;
+  pthread_mutex_init(&conn->watchdog_mutex, NULL);
+  pthread_create(&conn->player_watchdog_thread, NULL, &player_watchdog_thread_code, (void *)conn);
+
   int rc = pthread_mutex_init(&conn->flush_mutex, NULL);
   if (rc)
     die("Connection %d: error %d initialising flush_mutex.", conn->connection_number, rc);
@@ -2136,7 +2184,7 @@ static void *rtsp_conversation_thread_func(void *pconn) {
       }
       debug(debug_level, "Connection %d: RTSP Response:", conn->connection_number);
       debug_print_msg_headers(debug_level, resp);
-      
+
       /*
       fd_set writefds;
       FD_ZERO(&writefds);
@@ -2146,7 +2194,7 @@ static void *rtsp_conversation_thread_func(void *pconn) {
       } while (conn->stop == 0 &&
                pselect(conn->fd + 1, NULL, &writefds, NULL, NULL, &pselect_sigset) <= 0);
       */
-      
+
       if (conn->stop == 0) {
         int err = msg_write_response(conn->fd, resp);
         if (err) {
@@ -2154,8 +2202,8 @@ static void *rtsp_conversation_thread_func(void *pconn) {
                    "connection.",
                 conn->connection_number);
           conn->stop = 1;
-          if (debuglev >= 1)
-            debuglev = 3; // see what happens next
+          // if (debuglev >= 1)
+          //  debuglev = 3; // see what happens next
         }
       }
       pthread_cleanup_pop(1);
index c92125441ffa738855e18b6c8926ff368abd2ccd..506f9febe7d5312b6866816813273646b848bbe0 100644 (file)
 #include <libconfig.h>
 #include <libgen.h>
 #include <memory.h>
+#include <net/if.h>
 #include <popt.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <sys/socket.h>
-#include <net/if.h>
 #include <sys/stat.h>
 #include <sys/types.h>
 #include <sys/wait.h>