From: Mike Brady Date: Sun, 15 Jul 2018 12:11:51 +0000 (+0100) Subject: Add a cancellation stack to get_buffer_frame. X-Git-Tag: 3.3RC0~286^2~25 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=8ed8f808b8c952b246452ea8a262d92fb061e2d9;p=thirdparty%2Fshairport-sync.git Add a cancellation stack to get_buffer_frame. --- diff --git a/player.c b/player.c index 07716b76..4ba93f8f 100644 --- a/player.c +++ b/player.c @@ -771,6 +771,11 @@ static inline void process_sample(int32_t sample, char **outp, enum sps_format_t *outp += result; } +void buffer_get_frame_cleanup_handler(void *arg) { + rtsp_conn_info *conn = (rtsp_conn_info *)arg; + debug_mutex_unlock(&conn->ab_mutex, 3); +} + // get the next frame, when available. return 0 if underrun/stream reset. static abuf_t *buffer_get_frame(rtsp_conn_info *conn) { // int16_t buf_fill; @@ -780,8 +785,12 @@ static abuf_t *buffer_get_frame(rtsp_conn_info *conn) { int notified_buffer_empty = 0; // diagnostic only debug_mutex_lock(&conn->ab_mutex, 30000, 1); + + int wait; long dac_delay = 0; // long because alsa returns a long + + pthread_cleanup_push(buffer_get_frame_cleanup_handler, (void *)conn); // undo what's been done so far do { // get the time local_time_now = get_absolute_time_in_fp(); // type okay @@ -820,8 +829,8 @@ static abuf_t *buffer_get_frame(rtsp_conn_info *conn) { debug_mutex_lock(&conn->flush_mutex, 1000, 1); if (conn->flush_requested == 1) { if (config.output->flush) - config.output->flush(); - ab_resync(conn); + config.output->flush(); // no cancellation points + ab_resync(conn); // no cancellation points conn->first_packet_timestamp = 0; conn->first_packet_time_to_play = 0; conn->time_since_play_started = 0; @@ -1207,7 +1216,7 @@ static abuf_t *buffer_get_frame(rtsp_conn_info *conn) { time_of_wakeup.tv_sec = sec; time_of_wakeup.tv_nsec = nsec; // pthread_cond_timedwait(&conn->flowcontrol, &conn->ab_mutex, &time_of_wakeup); - int rc = pthread_cond_timedwait(&conn->flowcontrol, &conn->ab_mutex, &time_of_wakeup); + int rc = pthread_cond_timedwait(&conn->flowcontrol, &conn->ab_mutex, &time_of_wakeup); // this is a pthread cancellation point if (rc != 0) debug(3, "pthread_cond_timedwait returned error code %d.", rc); #endif @@ -1222,24 +1231,24 @@ static abuf_t *buffer_get_frame(rtsp_conn_info *conn) { } } while (wait); - if (conn->player_thread_please_stop) { - debug(3, "buffer_get_frame exiting due to thread stop request."); - debug_mutex_unlock(&conn->ab_mutex, 3); - return 0; - } - // seq_t read = conn->ab_read; - - if (!curframe->ready) { - // debug(1, "Supplying a silent frame for frame %u", read); - conn->missing_packets++; - curframe->timestamp = 0; // indicate a silent frame should be substituted + if (conn->player_thread_please_stop==0) { + if (!curframe->ready) { + // debug(1, "Supplying a silent frame for frame %u", read); + conn->missing_packets++; + curframe->timestamp = 0; // indicate a silent frame should be substituted + } + curframe->ready = 0; + curframe->resend_level = 0; + conn->ab_read = SUCCESSOR(conn->ab_read); } - curframe->ready = 0; - curframe->resend_level = 0; - conn->ab_read = SUCCESSOR(conn->ab_read); - debug_mutex_unlock(&conn->ab_mutex, 3); - return curframe; + + pthread_cleanup_pop(1); + + if (conn->player_thread_please_stop) + return 0; + else + return curframe; } static inline short shortmean(short a, short b) { @@ -1743,7 +1752,7 @@ void *player_thread_func(void *arg) { // debug(1, "Play begin"); while (!conn->player_thread_please_stop) { - abuf_t *inframe = buffer_get_frame(conn); + abuf_t *inframe = buffer_get_frame(conn); // this has cancellation point(s) if (inframe) { inbuf = inframe->data; inbuflength = inframe->length;