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)
This commit is contained in:
Jaroslav Kysela 2015-01-25 18:23:51 +01:00
parent c3ec4b114d
commit cde875ecb2
3 changed files with 76 additions and 41 deletions

View file

@ -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,

View file

@ -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);
}
}

View file

@ -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: