]> git.ipfire.org Git - thirdparty/shairport-sync.git/commitdiff
Add an uncancellable usleep timer. Make the player and UDP thread cleanups uncancellable.
authorMike Brady <mikebrady@eircom.net>
Thu, 29 Nov 2018 11:37:56 +0000 (11:37 +0000)
committerMike Brady <mikebrady@eircom.net>
Thu, 29 Nov 2018 11:37:56 +0000 (11:37 +0000)
common.c
common.h
player.c
rtp.c
rtsp.c

index 76cf8204b1754002e8b043f559c2de81a4e51ca1..f815af91b438995cca80fc117717ac244810ded1 100644 (file)
--- a/common.c
+++ b/common.c
@@ -94,6 +94,16 @@ volatile int debuglev = 0;
 
 sigset_t pselect_sigset;
 
+
+int usleep_uncancellable(useconds_t usec) {
+       int response;
+       int oldState;
+  pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldState);
+  response = usleep_uncancellable(usec);
+  pthread_setcancelstate(oldState, NULL);
+  return response;
+}
+
 static uint16_t UDPPortIndex = 0;
 
 void resetFreeUDPPort() {
index a043d0f78f8313455bd9c3b0e135d5e1eb2de3eb..59492c5f0aeefa182c9db4b760ba262b7832c0e7 100644 (file)
--- a/common.h
+++ b/common.h
@@ -330,5 +330,7 @@ char *get_version_string(); // mallocs a string space -- remember to free it aft
 
 void sps_nanosleep(const time_t sec,
                    const long nanosec); // waits for this time, even through interruptions
+                   
+int usleep_uncancellable(useconds_t usec);
 
 #endif // _COMMON_H
index 4e2bfc4fed81824e55533e84937224bce0a3962d..57d7527b90f9351d66b94cb362202ac8efe784c5 100644 (file)
--- a/player.c
+++ b/player.c
@@ -1396,6 +1396,8 @@ void player_thread_initial_cleanup_handler(__attribute__((unused)) void *arg) {
 
 void player_thread_cleanup_handler(void *arg) {
   rtsp_conn_info *conn = (rtsp_conn_info *)arg;
+  int oldState;
+  pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldState);
   debug(3, "Connection %d: player thread main loop exit via player_thread_cleanup_handler.",
         conn->connection_number);
 
@@ -1465,6 +1467,7 @@ void player_thread_cleanup_handler(void *arg) {
 
   clear_reference_timestamp(conn);
   conn->rtp_running = 0;
+  pthread_setcancelstate(oldState, NULL);
 }
 
 void *player_thread_func(void *arg) {
diff --git a/rtp.c b/rtp.c
index c61be2ee6b6300f3e386ab2e98016d9ced8b3a18..bfb32d750cd15f3726a23f76f8c4af87caf85186 100644 (file)
--- a/rtp.c
+++ b/rtp.c
@@ -98,14 +98,15 @@ uint64_t local_to_remote_time_difference_now(rtsp_conn_info *conn) {
 }
 
 void rtp_audio_receiver_cleanup_handler(void *arg) {
-  debug(1, "Audio Receiver Cleanup.");
+       int oldState;
+  pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldState);
+  debug(3, "Audio Receiver Cleanup.");
   rtsp_conn_info *conn = (rtsp_conn_info *)arg;
-  debug(3, "shutdown audio socket.");
-  shutdown(conn->audio_socket, SHUT_RDWR);
-  debug(3, "close audio socket.");
+  debug(3, "Close Audio Socket.");
   close(conn->audio_socket);
-
-  debug(1, "Audio Receiver Cleanup Successful.");
+  debug(3, "Audio Receiver Cleanup Successful.");
+  usleep(20000); // microseconds
+  pthread_setcancelstate(oldState, NULL);
 }
 
 void *rtp_audio_receiver(void *arg) {
@@ -240,13 +241,17 @@ void *rtp_audio_receiver(void *arg) {
 }
 
 void rtp_control_handler_cleanup_handler(void *arg) {
+  int oldState;
+  pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldState);
   debug(3, "Control Receiver Cleanup.");
   rtsp_conn_info *conn = (rtsp_conn_info *)arg;
-  debug(1, "shutdown control socket.");
+  debug(3, "Shut Down Control Socket.");
   shutdown(conn->control_socket, SHUT_RDWR);
-  debug(3, "close control socket.");
+  debug(3, "Close Control Socket.");
   close(conn->control_socket);
-  debug(1, "Control Receiver Cleanup Successful.");
+  debug(3, "Control Receiver Cleanup Successful.");
+  usleep(20000); // microseconds
+  pthread_setcancelstate(oldState, NULL);
 }
 
 void *rtp_control_receiver(void *arg) {
@@ -559,15 +564,19 @@ void *rtp_timing_sender(void *arg) {
 }
 
 void rtp_timing_receiver_cleanup_handler(void *arg) {
+       int oldState;
+  pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldState);
   debug(3, "Timing Receiver Cleanup.");
   rtsp_conn_info *conn = (rtsp_conn_info *)arg;
+  debug(3, "Cancel Timing Requester.");
   pthread_cancel(conn->timer_requester);
+  debug(3, "Join Timing Requester.");  
   pthread_join(conn->timer_requester, NULL);
-  debug(1, "shutdown timing socket.");
-  shutdown(conn->timing_socket, SHUT_RDWR);
-  debug(3, "close timing socket.");
+  debug(3, "Close Timing Socket.");
   close(conn->timing_socket);
-  debug(1, "Timing Receiver Cleanup Successful.");
+  debug(3, "Timing Receiver Cleanup Successful.");
+  usleep(20000); // microseconds
+  pthread_setcancelstate(oldState, NULL);
 }
 
 void *rtp_timing_receiver(void *arg) {
diff --git a/rtsp.c b/rtsp.c
index beaaf8f788778d691bf931165ca4e2b04b612474..2d1203d78d2e625be4dabb8cd7c3dd60e0a3ef8e 100644 (file)
--- a/rtsp.c
+++ b/rtsp.c
@@ -570,10 +570,12 @@ enum rtsp_read_request_response rtsp_read_request(rtsp_conn_info *conn, rtsp_mes
     if (nread < 0) {
       if (errno == EINTR)
         continue;
-      char errorstring[1024];
-      strerror_r(errno, (char *)errorstring, sizeof(errorstring));
-      debug(1, "Connection %d: rtsp_read_request_response_read_error %d: \"%s\".",
-            conn->connection_number, errno, (char *)errorstring);
+      if (errno != ECONNRESET) {
+                               char errorstring[1024];
+                               strerror_r(errno, (char *)errorstring, sizeof(errorstring));
+                               debug(1, "Connection %d: rtsp_read_request_response_read_error %d: \"%s\".",
+                                                       conn->connection_number, errno, (char *)errorstring);
+      }
       reply = rtsp_read_request_response_read_error;
       goto shutdown;
     }
@@ -1577,7 +1579,7 @@ static void handle_announce(rtsp_conn_info *conn, rtsp_message *req, rtsp_messag
     have_the_player = 1;
     warn("Duplicate ANNOUNCE, by the look of it!");
   } else if (playing_conn->stop) {
-    debug(2, "Connection %d: ANNOUNCE: already shutting down; waiting for it...",
+    debug(1, "Connection %d: ANNOUNCE: already shutting down; waiting for it...",
           playing_conn->connection_number);
     should_wait = 1;
   } else if (config.allow_session_interruption == 1) {
@@ -2063,14 +2065,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, "Connection %d: Checking play lock.", conn->connection_number);
-  debug_mutex_lock(&playing_conn_lock, 1000000, 3); // get it
-  if (playing_conn == conn) {
-    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;
@@ -2081,6 +2076,15 @@ void rtsp_conversation_thread_cleanup_function(void *arg) {
   debug(2, "Delete watchdog mutex.");
   pthread_mutex_destroy(&conn->watchdog_mutex);
 
+
+  debug(3, "Connection %d: Checking play lock.", conn->connection_number);
+  debug_mutex_lock(&playing_conn_lock, 1000000, 3); // get it
+  if (playing_conn == conn) {
+    debug(1, "Connection %d: Unlocking play lock.", conn->connection_number);
+    playing_conn = NULL;
+  }
+  debug_mutex_unlock(&playing_conn_lock, 3);
+  
   debug(2, "Connection %d: RTSP thread terminated.", conn->connection_number);
   conn->running = 0;
 }