From: Mike Brady Date: Mon, 19 Nov 2018 18:26:03 +0000 (+0000) Subject: Try to make the debug stuff pthread_cancel-proof including the debug / warn / inform... X-Git-Tag: 3.3RC0~169 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=d4435e2068b157148ec9ca9819fa514ae9badb98;p=thirdparty%2Fshairport-sync.git Try to make the debug stuff pthread_cancel-proof including the debug / warn / inform / die and debug_mutex calls. Tidy up usage of program_stop. --- diff --git a/audio_alsa.c b/audio_alsa.c index 9e28dd47..faa6ef93 100644 --- a/audio_alsa.c +++ b/audio_alsa.c @@ -919,8 +919,8 @@ int delay(long *the_delay) { } } } - // debug_mutex_unlock(&alsa_mutex, 3); - pthread_cleanup_pop(1); + debug_mutex_unlock(&alsa_mutex, 3); + pthread_cleanup_pop(0); // here, occasionally pretend there's a problem with pcm_get_delay() // if ((random() % 100000) < 3) // keep it pretty rare // reply = -EIO; // pretend something bad has happened @@ -954,8 +954,8 @@ static int play(void *buf, int samples) { do_mute(0); } - // debug_mutex_unlock(&alsa_mutex, 3); - pthread_cleanup_pop(1); // release the mutex + debug_mutex_unlock(&alsa_mutex, 3); + pthread_cleanup_pop(0); // release the mutex } if (ret == 0) { pthread_cleanup_debug_mutex_lock(&alsa_mutex, 10000, 1); @@ -1040,8 +1040,8 @@ static int play(void *buf, int samples) { frame_index = 0; measurement_data_is_valid = 0; } - // debug_mutex_unlock(&alsa_mutex, 3); - pthread_cleanup_pop(1); // release the mutex + debug_mutex_unlock(&alsa_mutex, 3); + pthread_cleanup_pop(0); // release the mutex } return ret; } @@ -1067,8 +1067,8 @@ static void flush(void) { measurement_data_is_valid = 0; alsa_handle = NULL; } - // debug_mutex_unlock(&alsa_mutex, 3); - pthread_cleanup_pop(1); // release the mutex + debug_mutex_unlock(&alsa_mutex, 3); + pthread_cleanup_pop(0); // release the mutex } static void stop(void) { @@ -1124,8 +1124,8 @@ void volume(double vol) { pthread_cleanup_debug_mutex_lock(&alsa_mutex, 1000, 1); volume_set_request = 1; // an external request has been made to set the volume do_volume(vol); - // debug_mutex_unlock(&alsa_mutex, 3); - pthread_cleanup_pop(1); // release the mutex + debug_mutex_unlock(&alsa_mutex, 3); + pthread_cleanup_pop(0); // release the mutex } /* @@ -1152,8 +1152,8 @@ static void mute(int mute_state_requested) { mute_request_pending = 1; overriding_mute_state_requested = mute_state_requested; do_mute(mute_state_requested); - // debug_mutex_unlock(&alsa_mutex, 3); - pthread_cleanup_pop(1); // release the mutex + debug_mutex_unlock(&alsa_mutex, 0); + pthread_cleanup_pop(0); // release the mutex } void do_mute(int mute_state_requested) { diff --git a/common.c b/common.c index e4724954..e0a35b8d 100644 --- a/common.c +++ b/common.c @@ -99,6 +99,8 @@ int get_requested_connection_state_to_output() { return requested_connection_sta void set_requested_connection_state_to_output(int v) { requested_connection_state_to_output = v; } void die(const char *format, ...) { + int oldState; + pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldState); char s[1024]; s[0] = 0; uint64_t time_now = get_absolute_time_in_fp(); @@ -121,10 +123,13 @@ void die(const char *format, ...) { daemon_log(LOG_EMERG, "% 20.9f|*fatal error: %s", tss, s); else daemon_log(LOG_EMERG, "fatal error: %s", s); + pthread_setcancelstate(oldState,NULL); exit(1); } void warn(const char *format, ...) { + int oldState; + pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldState); char s[1024]; s[0] = 0; uint64_t time_now = get_absolute_time_in_fp(); @@ -147,11 +152,14 @@ void warn(const char *format, ...) { daemon_log(LOG_WARNING, "% 20.9f|*warning: %s", tss, s); else daemon_log(LOG_WARNING, "%s", s); + pthread_setcancelstate(oldState,NULL); } void debug(int level, const char *format, ...) { if (level > debuglev) return; + int oldState; + pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldState); char s[1024]; s[0] = 0; uint64_t time_now = get_absolute_time_in_fp(); @@ -173,9 +181,12 @@ void debug(int level, const char *format, ...) { daemon_log(LOG_DEBUG, "% 20.9f|%s", tss, s); else daemon_log(LOG_DEBUG, "%s", s); + pthread_setcancelstate(oldState,NULL); } void inform(const char *format, ...) { + int oldState; + pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldState); char s[1024]; s[0] = 0; uint64_t time_now = get_absolute_time_in_fp(); @@ -198,6 +209,7 @@ void inform(const char *format, ...) { daemon_log(LOG_INFO, "% 20.9f|%s", tss, s); else daemon_log(LOG_INFO, "%s", s); + pthread_setcancelstate(oldState,NULL); } // The following two functions are adapted slightly and with thanks from Jonathan Leffler's sample @@ -1050,6 +1062,8 @@ void sps_nanosleep(const time_t sec, const long nanosec) { int sps_pthread_mutex_timedlock(pthread_mutex_t *mutex, useconds_t dally_time, const char *debugmessage, int debuglevel) { + int oldState; + pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldState); struct timespec tn; clock_gettime(CLOCK_REALTIME, &tn); uint64_t tnfpsec = tn.tv_sec; @@ -1091,6 +1105,7 @@ int sps_pthread_mutex_timedlock(pthread_mutex_t *mutex, useconds_t dally_time, debug(debuglevel, "error %d: \"%s\" waiting for a mutex: \"%s\".", r, strerror_r(r, errstr, sizeof(errstr)), debugmessage); } + pthread_setcancelstate(oldState,NULL); return r; } #endif @@ -1099,6 +1114,8 @@ int sps_pthread_mutex_timedlock(pthread_mutex_t *mutex, useconds_t dally_time, const char *debugmessage, int debuglevel) { // this is not pthread_cancellation safe because is contains a cancellation point + int oldState; + pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldState); useconds_t time_to_wait = dally_time; int r = pthread_mutex_trylock(mutex); while ((r == EBUSY) && (time_to_wait > 0)) { @@ -1121,6 +1138,7 @@ int sps_pthread_mutex_timedlock(pthread_mutex_t *mutex, useconds_t dally_time, strerror_r(r, errstr, sizeof(errstr)), debugmessage); } } + pthread_setcancelstate(oldState,NULL); return r; } #endif @@ -1129,6 +1147,8 @@ int _debug_mutex_lock(pthread_mutex_t *mutex, useconds_t dally_time, const char const int line, int debuglevel) { if (debuglevel > debuglev) return pthread_mutex_lock(mutex); + int oldState; + pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldState); uint64_t time_at_start = get_absolute_time_in_fp(); char dstring[1000]; memset(dstring, 0, sizeof(dstring)); @@ -1144,6 +1164,7 @@ int _debug_mutex_lock(pthread_mutex_t *mutex, useconds_t dally_time, const char "debug_mutex_lock at \"%s\" expected max wait: %0.9f, actual wait: %0.9f sec.", dstring, (1.0 * dally_time) / 1000000, delay); } + pthread_setcancelstate(oldState,NULL); return result; } @@ -1151,6 +1172,8 @@ int _debug_mutex_unlock(pthread_mutex_t *mutex, const char *filename, const int int debuglevel) { if (debuglevel > debuglev) return pthread_mutex_unlock(mutex); + int oldState; + pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldState); char dstring[1000]; char errstr[512]; memset(dstring, 0, sizeof(dstring)); @@ -1160,6 +1183,7 @@ int _debug_mutex_unlock(pthread_mutex_t *mutex, const char *filename, const int if (r != 0) debug(1, "error %d: \"%s\" unlocking a mutex: \"%s\".", r, strerror_r(r, errstr, sizeof(errstr)), dstring); + pthread_setcancelstate(oldState,NULL); return r; } diff --git a/rtsp.c b/rtsp.c index 5b887eb7..c819437f 100644 --- a/rtsp.c +++ b/rtsp.c @@ -1954,7 +1954,8 @@ void rtsp_conversation_thread_cleanup_function(void *arg) { rtsp_conn_info *conn = (rtsp_conn_info *)arg; // debug(1, "Connection %d: rtsp_conversation_thread_func_cleanup_function called.", // conn->connection_number); - player_stop(conn); + if (conn->player_thread) + player_stop(conn); if (conn->fd > 0) { // debug(1, "Connection %d: closing fd %d.", // conn->connection_number,conn->fd); @@ -2136,7 +2137,6 @@ static void *rtsp_conversation_thread_func(void *pconn) { if (conn->player_thread) debug(1, "RTSP Channel unexpectedly closed or a serious error occured -- closing the " "player thread."); - player_stop(conn); debug(3, "Successful termination of playing thread of RTSP conversation thread %d.", conn->connection_number); debug(3, "Request termination of RTSP conversation thread %d.", conn->connection_number);