From: Mike Brady Date: Thu, 29 Nov 2018 11:37:56 +0000 (+0000) Subject: Add an uncancellable usleep timer. Make the player and UDP thread cleanups uncancellable. X-Git-Tag: 3.3RC0~132 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=c318796e5511686fdafbc0b445ada2eb30b38ae2;p=thirdparty%2Fshairport-sync.git Add an uncancellable usleep timer. Make the player and UDP thread cleanups uncancellable. --- diff --git a/common.c b/common.c index 76cf8204..f815af91 100644 --- 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() { diff --git a/common.h b/common.h index a043d0f7..59492c5f 100644 --- 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 diff --git a/player.c b/player.c index 4e2bfc4f..57d7527b 100644 --- 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 c61be2ee..bfb32d75 100644 --- 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 beaaf8f7..2d1203d7 100644 --- 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; }