From cde875ecb2296a42adc909b5336d4027734bc637 Mon Sep 17 00:00:00 2001 From: Jaroslav Kysela Date: Sun, 25 Jan 2015 18:23:51 +0100 Subject: [PATCH] SAT>IP: corner case fixes, fixes #2638 - fixed wait before next tune (flush the incoming rtsp replies) - fixed mutex global_lock deadlock (satip_frontend_tuning_error) --- src/input/mpegts.h | 2 +- src/input/mpegts/mpegts_mux.c | 25 ++++--- src/input/mpegts/satip/satip_frontend.c | 90 ++++++++++++++++--------- 3 files changed, 76 insertions(+), 41 deletions(-) diff --git a/src/input/mpegts.h b/src/input/mpegts.h index 707d9e14..ade18bcb 100644 --- a/src/input/mpegts.h +++ b/src/input/mpegts.h @@ -755,7 +755,7 @@ void mpegts_mux_delete ( mpegts_mux_t *mm, int delconf ); void mpegts_mux_save ( mpegts_mux_t *mm, htsmsg_t *c ); -void mpegts_mux_tuning_error( mpegts_mux_t *mm ); +void mpegts_mux_tuning_error( const char *mux_uuid, mpegts_mux_instance_t *mmi_match ); mpegts_mux_instance_t *mpegts_mux_instance_create0 ( mpegts_mux_instance_t *mmi, const idclass_t *class, const char *uuid, diff --git a/src/input/mpegts/mpegts_mux.c b/src/input/mpegts/mpegts_mux.c index 771eabde..8087f1e4 100644 --- a/src/input/mpegts/mpegts_mux.c +++ b/src/input/mpegts/mpegts_mux.c @@ -1314,21 +1314,30 @@ mpegts_mux_unsubscribe_by_name } void -mpegts_mux_tuning_error ( mpegts_mux_t *mm ) +mpegts_mux_tuning_error ( const char *mux_uuid, mpegts_mux_instance_t *mmi_match ) { + mpegts_mux_t *mm; th_subscription_t *sub; mpegts_mux_instance_t *mmi; streaming_message_t *sm; + struct timespec timeout; - lock_assert(&global_lock); + timeout.tv_sec = 2; + timeout.tv_nsec = 0; - if ((mmi = mm->mm_active) != NULL) { - LIST_FOREACH(sub, &mmi->mmi_subs, ths_mmi_link) { - sm = streaming_msg_create_code(SMT_SERVICE_STATUS, TSS_TUNING); - streaming_target_deliver(sub->ths_output, sm); + if (!pthread_mutex_timedlock(&global_lock, &timeout)) { + mm = mpegts_mux_find(mux_uuid); + if (mm) { + if ((mmi = mm->mm_active) != NULL && mmi == mmi_match) { + LIST_FOREACH(sub, &mmi->mmi_subs, ths_mmi_link) { + sm = streaming_msg_create_code(SMT_SERVICE_STATUS, TSS_TUNING); + streaming_target_deliver(sub->ths_output, sm); + } + if (mmi->mmi_input) + mmi->mmi_input->mi_tuning_error(mmi->mmi_input, mm); + } } - if (mmi->mmi_input) - mmi->mmi_input->mi_tuning_error(mmi->mmi_input, mm); + pthread_mutex_unlock(&global_lock); } } diff --git a/src/input/mpegts/satip/satip_frontend.c b/src/input/mpegts/satip/satip_frontend.c index 95f5e6bb..c95adce4 100644 --- a/src/input/mpegts/satip/satip_frontend.c +++ b/src/input/mpegts/satip/satip_frontend.c @@ -1116,13 +1116,43 @@ satip_frontend_shutdown ( http_client_t *rtsp, tvhpoll_t *efd ) static void satip_frontend_tuning_error ( satip_frontend_t *lfe, satip_tune_req_t *tr ) { - pthread_mutex_lock(&global_lock); + mpegts_mux_t *mm; + mpegts_mux_instance_t *mmi; + char uuid[UUID_HEX_SIZE]; + pthread_mutex_lock(&lfe->sf_dvr_lock); if (lfe->sf_running && lfe->sf_req == tr && - tr->sf_mmi && tr->sf_mmi->mmi_mux) - mpegts_mux_tuning_error(tr->sf_mmi->mmi_mux); + (mmi = tr->sf_mmi) != NULL && (mm = mmi->mmi_mux) != NULL) { + strcpy(uuid, idnode_uuid_as_str(&mm->mm_id)); + pthread_mutex_unlock(&lfe->sf_dvr_lock); + mpegts_mux_tuning_error(uuid, mmi); + return; + } pthread_mutex_unlock(&lfe->sf_dvr_lock); - pthread_mutex_unlock(&global_lock); +} + +static void +satip_frontend_close_rtsp + ( satip_frontend_t *lfe, tvhpoll_t *efd, http_client_t **rtsp ) +{ + tvhpoll_event_t ev; + + memset(&ev, 0, sizeof(ev)); + ev.events = TVHPOLL_IN; + ev.fd = lfe->sf_dvr_pipe.rd; + ev.data.ptr = NULL; + tvhpoll_rem(efd, &ev, 1); + + satip_frontend_shutdown(*rtsp, efd); + + memset(&ev, 0, sizeof(ev)); + ev.events = TVHPOLL_IN; + ev.fd = lfe->sf_dvr_pipe.rd; + ev.data.ptr = NULL; + tvhpoll_add(efd, &ev, 1); + + http_client_close(*rtsp); + *rtsp = NULL; } static void * @@ -1186,25 +1216,7 @@ new_tune: nfds = tvhpoll_wait(efd, ev, 1, rtsp ? 50 : -1); if (!tvheadend_running) { exit_flag = 1; goto done; } - if (rtsp && nfds == 0) { - - memset(ev, 0, sizeof(ev)); - ev[0].events = TVHPOLL_IN; - ev[0].fd = lfe->sf_dvr_pipe.rd; - ev[0].data.ptr = NULL; - tvhpoll_rem(efd, ev, 1); - - satip_frontend_shutdown(rtsp, efd); - - memset(ev, 0, sizeof(ev)); - ev[0].events = TVHPOLL_IN; - ev[0].fd = lfe->sf_dvr_pipe.rd; - ev[0].data.ptr = NULL; - tvhpoll_add(efd, ev, 1); - - http_client_close(rtsp); - rtsp = NULL; - } + if (rtsp && nfds == 0) satip_frontend_close_rtsp(lfe, efd, &rtsp); if (nfds <= 0) continue; if (ev[0].data.ptr == NULL) { @@ -1280,14 +1292,17 @@ new_tune: lfe_master = lfe; } - pthread_mutex_lock(&lfe->sf_device->sd_tune_mutex); - u64 = lfe_master->sf_last_tune; - i = lfe_master->sf_tdelay; - pthread_mutex_unlock(&lfe->sf_device->sd_tune_mutex); - if (i < 0) - i = 0; - if (i > 2000) - i = 2000; + i = 0; + if (!rtsp) { + pthread_mutex_lock(&lfe->sf_device->sd_tune_mutex); + u64 = lfe_master->sf_last_tune; + i = lfe_master->sf_tdelay; + pthread_mutex_unlock(&lfe->sf_device->sd_tune_mutex); + if (i < 0) + i = 0; + if (i > 2000) + i = 2000; + } tc = 1; while (i) { @@ -1329,6 +1344,15 @@ new_tune: goto done; } + if (ev[0].data.ptr == rtsp) { + tc = 0; + r = http_client_run(rtsp); + if (r < 0) { + http_client_close(rtsp); + rtsp = NULL; + } + } + } pthread_mutex_lock(&lfe->sf_device->sd_tune_mutex); @@ -1408,7 +1432,7 @@ new_tune: continue; } else if (b[0] == 's') { start = 1; running = 0; - goto done; + continue; } } tvhtrace("satip", "%s - input thread received mux close", buf); @@ -1442,6 +1466,8 @@ new_tune: satip_frontend_tuning_error(lfe, tr); fatal = 1; } else if (r == HTTP_CON_DONE) { + if (start) + goto done; reply = 0; switch (rtsp->hc_cmd) { case RTSP_CMD_OPTIONS: