Add an uncancellable usleep timer. Make the player and UDP thread cleanups uncancellable.
This commit is contained in:
@@ -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() {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user