]> git.ipfire.org Git - thirdparty/shairport-sync.git/commitdiff
Remove watchdog stuff. USe the session timeout to set the TCP keep intervals and...
authorMike Brady <4265913+mikebrady@users.noreply.github.com>
Sat, 29 Jun 2024 19:04:29 +0000 (20:04 +0100)
committerMike Brady <4265913+mikebrady@users.noreply.github.com>
Sat, 29 Jun 2024 19:04:29 +0000 (20:04 +0100)
rtsp.c

diff --git a/rtsp.c b/rtsp.c
index f997824e9bd698123597e16eae4e21cdb7b4e6a9..1712e4805d21d82d4ed5761d52e72609e0718377 100644 (file)
--- a/rtsp.c
+++ b/rtsp.c
@@ -3,7 +3,7 @@
  * Copyright (c) James Laird 2013
 
  * Modifications associated with audio synchronization, multithreading and
- * metadata handling copyright (c) Mike Brady 2014-2023
+ * metadata handling copyright (c) Mike Brady 2014-2024
  * All rights reserved.
  *
  * Permission is hereby granted, free of charge, to any person
@@ -612,57 +612,6 @@ int get_play_lock(rtsp_conn_info *conn, int allow_session_interruption) {
   return response;
 }
 
-void player_watchdog_thread_cleanup_handler(void *arg) {
-  rtsp_conn_info *conn = (rtsp_conn_info *)arg;
-  debug(3, "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);
-#ifdef CONFIG_AIRPLAY_2
-    if ((config.dont_check_timeout == 0) && (config.timeout != 0) && (conn->airplay_type == ap_1)) {
-#else
-    if ((config.dont_check_timeout == 0) && (config.timeout != 0)) {
-#endif
-      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_ns() - last_watchdog_bark_time) / 1000000000;
-        uint64_t ct = config.timeout; // go from int to 64-bit int
-
-        if (time_since_last_bark >= ct) {
-          conn->watchdog_barks++;
-          if (conn->watchdog_barks == 1) {
-            // debuglev = 3; // tell us everything.
-            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);
-          } else if (conn->watchdog_barks == 3) {
-            if ((config.cmd_unfixable) && (config.unfixable_error_reported == 0)) {
-              config.unfixable_error_reported = 1;
-              command_execute(config.cmd_unfixable, "unable_to_cancel_play_session", 1);
-            } else {
-              die("an unrecoverable error, \"unable_to_cancel_play_session\", has been detected.",
-                  conn->connection_number);
-            }
-          }
-        }
-      }
-    }
-  } while (1);
-  pthread_cleanup_pop(0); // should never happen
-  pthread_exit(NULL);
-}
-
 static void track_thread(rtsp_conn_info *conn) {
   debug_mutex_lock(&conns_lock, 1000000, 3);
   // look for an empty slot first
@@ -1349,8 +1298,11 @@ enum rtsp_read_request_response rtsp_read_request(rtsp_conn_info *conn, rtsp_mes
         continue;
       }
       if (errno == ETIMEDOUT) {
-        debug(1, "Connection %d: ETIMEDOUT -- keepalive timeout.", conn->connection_number);
-        reply = rtsp_read_request_response_channel_closed;
+        debug(1,
+              "Connection %d: As Yeats almost said, \"Too long a silence / can make a stone "
+              "of the heart\".",
+              conn->connection_number);
+        reply = rtsp_read_request_response_immediate_shutdown_requested;
         // Note: the socket will be closed when the thread exits
         goto shutdown;
       }
@@ -2116,7 +2068,7 @@ struct pairings {
   uint8_t public_key[32];
 
   struct pairings *next;
-} * pairings;
+} *pairings;
 
 static struct pairings *pairing_find(const char *device_id) {
   for (struct pairings *pairing = pairings; pairing; pairing = pairing->next) {
@@ -5113,7 +5065,7 @@ void rtsp_conversation_thread_cleanup_function(void *arg) {
   if (conn != NULL) {
     int oldState;
     pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldState);
-    debug(2, "Connection %d: %s rtsp_conversation_thread_func_cleanup_function called.",
+    debug(3, "Connection %d: %s rtsp_conversation_thread_func_cleanup_function called.",
           conn->connection_number, get_category_string(conn->airplay_stream_category));
 #ifdef CONFIG_AIRPLAY_2
     // AP2
@@ -5205,14 +5157,7 @@ void rtsp_conversation_thread_cleanup_function(void *arg) {
     if (rc)
       debug(1, "Connection %d: error %d destroying flush_mutex.", conn->connection_number, rc);
 
-    debug(3, "Cancel watchdog thread.");
-    pthread_cancel(conn->player_watchdog_thread);
-    debug(3, "Join watchdog thread.");
-    pthread_join(conn->player_watchdog_thread, NULL);
-    debug(3, "Delete watchdog mutex.");
-    pthread_mutex_destroy(&conn->watchdog_mutex);
-
-    debug(2, "Connection %d: Closed.", conn->connection_number);
+    debug(3, "Connection %d: Closed.", conn->connection_number);
     conn->running = 0; // for the garbage collector
     pthread_setcancelstate(oldState, NULL);
   }
@@ -5226,11 +5171,6 @@ void msg_cleanup_function(void *arg) {
 static void *rtsp_conversation_thread_func(void *pconn) {
   rtsp_conn_info *conn = pconn;
 
-  // create the watchdog mutex, initialise the watchdog time and start the watchdog thread;
-  conn->watchdog_bark_time = get_absolute_time_in_ns();
-  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);
@@ -5649,22 +5589,26 @@ void *rtsp_listen_loop(__attribute((unused)) void *arg) {
         size_of_reply = sizeof(SOCKADDR);
         if (getsockname(conn->fd, (struct sockaddr *)&conn->local, &size_of_reply) == 0) {
 
+          if ((config.dont_check_timeout == 0) && (config.timeout != 0)) {
 // skip this stuff in OpenBSD
 #ifndef COMPILE_FOR_OPENBSD
-          // Thanks to https://holmeshe.me/network-essentials-setsockopt-SO_KEEPALIVE/ for this.
+            // Thanks to https://holmeshe.me/network-essentials-setsockopt-SO_KEEPALIVE/ for this.
 
-          // turn on keepalive stuff -- wait for keepidle + (keepcnt * keepinttvl time) seconds
-          // before giving up an ETIMEOUT error is returned if the keepalive check fails
+            // turn on keepalive stuff -- wait for keepidle + (keepcnt * keepinttvl time) seconds
+            // before giving up an ETIMEOUT error is returned if the keepalive check fails
 
-          // if TCP_KEEPINTVL is defined, check a few times before declaring the line dead
-          // otherwise just wait a little while longer
+            // if TCP_KEEPINTVL is defined, check a few times before declaring the line dead
+            // otherwise just wait a little while longer
 
 #ifdef TCP_KEEPINTVL
-          int keepAliveIdleTime = 35; // wait this many seconds before checking for a dropped client
-          int keepAliveCount = 5;     // check this many times
-          int keepAliveInterval = 5;  // wait this many seconds between checks
+            int keepAliveIdleTime =
+                config.timeout -
+                5 * 5;              // wait this many seconds before checking for a dropped client
+            int keepAliveCount = 5; // check this many times
+            int keepAliveInterval = 5; // wait this many seconds between checks
 #else
-          int keepAliveIdleTime = 60; // wait this many seconds before dropping a client
+            int keepAliveIdleTime =
+                config.timeout; // wait this many seconds before dropping a client
 #endif
 
 // --- the following is a bit  too complicated
@@ -5681,24 +5625,24 @@ void *rtsp_listen_loop(__attribute((unused)) void *arg) {
 #define KEEP_ALIVE_OR_IDLE_OPTION TCP_KEEPIDLE
 #endif
 
-          if (setsockopt(conn->fd, SOL_OPTION, KEEP_ALIVE_OR_IDLE_OPTION,
-                         (void *)&keepAliveIdleTime, sizeof(keepAliveIdleTime))) {
-            debug(1, "can't set the keepAliveIdleTime wait time");
-          }
+            if (setsockopt(conn->fd, SOL_OPTION, KEEP_ALIVE_OR_IDLE_OPTION,
+                           (void *)&keepAliveIdleTime, sizeof(keepAliveIdleTime))) {
+              debug(1, "can't set the keepAliveIdleTime wait time");
+            }
 // ---
 // if TCP_KEEPINTVL is defined...
 #ifdef TCP_KEEPINTVL
-          if (setsockopt(conn->fd, SOL_OPTION, TCP_KEEPCNT, (void *)&keepAliveCount,
-                         sizeof(keepAliveCount))) {
-            debug(1, "can't set the keepAliveCount count");
-          }
-          if (setsockopt(conn->fd, SOL_OPTION, TCP_KEEPINTVL, (void *)&keepAliveInterval,
-                         sizeof(keepAliveInterval))) {
-            debug(1, "can't set the keepAliveCount count interval");
-          };
+            if (setsockopt(conn->fd, SOL_OPTION, TCP_KEEPCNT, (void *)&keepAliveCount,
+                           sizeof(keepAliveCount))) {
+              debug(1, "can't set the keepAliveCount count");
+            }
+            if (setsockopt(conn->fd, SOL_OPTION, TCP_KEEPINTVL, (void *)&keepAliveInterval,
+                           sizeof(keepAliveInterval))) {
+              debug(1, "can't set the keepAliveCount count interval");
+            };
 #endif
 #endif
-
+          }
           // initialise the connection info
           void *client_addr = NULL, *self_addr = NULL;
           conn->connection_ip_family = conn->local.SAFAMILY;