From: Jaroslav Kysela Date: Thu, 24 Mar 2016 19:36:41 +0000 (+0100) Subject: SAT>IP client: serialize request to server for consistency X-Git-Tag: v4.2.1~820 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=e48806652a3f464f022b82bdf7adf6c8ac2d0fc4;p=thirdparty%2Ftvheadend.git SAT>IP client: serialize request to server for consistency --- diff --git a/src/input/mpegts/satip/satip.c b/src/input/mpegts/satip/satip.c index f67ac9252..b90b994d6 100644 --- a/src/input/mpegts/satip/satip.c +++ b/src/input/mpegts/satip/satip.c @@ -588,6 +588,7 @@ satip_device_create( satip_device_info_t *info ) pthread_mutex_init(&sd->sd_tune_mutex, NULL); TAILQ_INIT(&sd->sd_frontends); + TAILQ_INIT(&sd->sd_serialize_queue); /* we may check if uuid matches, but the SHA hash should be enough */ if (sd->sd_info.uuid) diff --git a/src/input/mpegts/satip/satip_frontend.c b/src/input/mpegts/satip/satip_frontend.c index e478be871..68a2dc8ea 100644 --- a/src/input/mpegts/satip/satip_frontend.c +++ b/src/input/mpegts/satip/satip_frontend.c @@ -29,6 +29,11 @@ #include #endif +/* + * + */ +static void satip_frontend_add_to_waiting( satip_frontend_t *lfe ); + /* * */ @@ -534,8 +539,10 @@ satip_frontend_is_enabled return 0; /* master must be running */ return satip_frontend_match_satcfg(lfe2, mm, flags, weight); } - if (lfe2->sf_master == lfe->sf_number && lfe2->sf_running) - return satip_frontend_match_satcfg(lfe2, mm, flags, weight); + if (lfe2->sf_master == lfe->sf_number) { + if (lfe2->sf_running) + return satip_frontend_match_satcfg(lfe2, mm, flags, weight); + } } return 1; } @@ -564,7 +571,7 @@ satip_frontend_stop_mux mpegts_pid_done(&tr->sf_pids); free(tr); } - lfe->sf_running = 0; + lfe->sf_running = 0; lfe->sf_req = NULL; pthread_mutex_unlock(&lfe->sf_dvr_lock); } @@ -580,8 +587,10 @@ satip_frontend_warm_mux if (r) return r; + lfe->sf_netlimit = 0; if (lfe->sf_positions > 0) { - lfe->sf_position = satip_satconf_get_position(lfe, mmi->mmi_mux, NULL, 2, 0, -1); + lfe->sf_position = satip_satconf_get_position(lfe, mmi->mmi_mux, + &lfe->sf_netlimit, 2, 0, -1); if (lfe->sf_position <= 0) return SM_CODE_TUNING_FAILED; } @@ -631,6 +640,9 @@ satip_frontend_start_mux lfe->sf_status = SIGNAL_NONE; pthread_mutex_unlock(&mmi->tii_stats_mutex); + if (lfe->sf_type == DVB_TYPE_S) + satip_frontend_add_to_waiting(lfe); + /* notify thread that we are ready */ tvh_write(lfe->sf_dvr_pipe.wr, "s", 1); @@ -971,37 +983,65 @@ skip: return 0; } +static void +satip_frontend_add_to_waiting( satip_frontend_t *lfe ) +{ + satip_device_t *sd = lfe->sf_device; + satip_frontend_t *lfe2; + + if (lfe->sf_master) { + lfe2 = lfe; + } else { + TAILQ_FOREACH(lfe2, &lfe->sf_device->sd_frontends, sf_link) + if (lfe2 != lfe && lfe2->sf_master == lfe->sf_number) + break; + } + if (lfe2 == NULL && lfe->sf_netlimit <= 0) + return; + + pthread_mutex_lock(&sd->sd_tune_mutex); + if (lfe->sf_serialize) + TAILQ_REMOVE(&sd->sd_serialize_queue, lfe, sf_serialize_link); + lfe->sf_serialize = 1; + TAILQ_INSERT_TAIL(&sd->sd_serialize_queue, lfe, sf_serialize_link); + tvhtrace("satip", "add to waiting: %s", lfe->mi_name); + pthread_mutex_unlock(&sd->sd_tune_mutex); +} + static int satip_frontend_other_is_waiting( satip_frontend_t *lfe ) { - satip_frontend_t *lfe2; + satip_device_t *sd = lfe->sf_device; int r; - TAILQ_FOREACH(lfe2, &lfe->sf_device->sd_frontends, sf_link) { - if (lfe == lfe2) continue; - pthread_mutex_lock(&lfe2->sf_dvr_lock); - r = lfe2->sf_wait_for & (1 << lfe->sf_number); - pthread_mutex_unlock(&lfe2->sf_dvr_lock); - if (r) - return 1; - } - return 0; + pthread_mutex_lock(&sd->sd_tune_mutex); + if (lfe->sf_serialize) + r = TAILQ_FIRST(&sd->sd_serialize_queue) != lfe; + else + r = 0; + pthread_mutex_unlock(&sd->sd_tune_mutex); + return r; } static void satip_frontend_wake_other_waiting( satip_frontend_t *lfe ) { - satip_frontend_t *lfe2; - - TAILQ_FOREACH(lfe2, &lfe->sf_device->sd_frontends, sf_link) { - if (lfe == lfe2) continue; - pthread_mutex_lock(&lfe2->sf_dvr_lock); - if (lfe2->sf_running && lfe2->sf_wait_for & (1 << lfe->sf_number)) { - lfe2->sf_wait_for &= ~(1 << lfe->sf_number); - tvh_write(lfe2->sf_dvr_pipe.wr, "o", 1); + satip_device_t *sd = lfe->sf_device; + pthread_mutex_lock(&sd->sd_tune_mutex); + if (lfe->sf_serialize) { + tvhtrace("satip", "remove from waiting: %s", lfe->mi_name); + lfe->sf_serialize = 0; + TAILQ_REMOVE(&sd->sd_serialize_queue, lfe, sf_serialize_link); + lfe = TAILQ_FIRST(&sd->sd_serialize_queue); + if (lfe != NULL) { + tvhtrace("satip", "wake other waiting: %s", lfe->mi_name); + pthread_mutex_lock(&lfe->sf_dvr_lock); + if (lfe->sf_running) + tvh_write(lfe->sf_dvr_pipe.wr, "o", 1); + pthread_mutex_unlock(&lfe->sf_dvr_lock); } - pthread_mutex_unlock(&lfe2->sf_dvr_lock); } + pthread_mutex_unlock(&sd->sd_tune_mutex); } static void @@ -1302,7 +1342,7 @@ new_tune: u64_2 = getfastmonoclock(); pthread_mutex_lock(&lfe->sf_dvr_lock); - if (lfe->sf_wait_for == 0) start |= 2; else start &= ~2; + if (!satip_frontend_other_is_waiting(lfe)) start |= 2; else start &= ~2; pthread_mutex_unlock(&lfe->sf_dvr_lock); while (start != 3) { @@ -1310,7 +1350,7 @@ new_tune: nfds = tvhpoll_wait(efd, ev, 1, rtsp ? 55 : -1); pthread_mutex_lock(&lfe->sf_dvr_lock); - if (lfe->sf_wait_for == 0) start |= 2; else start &= ~2; + if (!satip_frontend_other_is_waiting(lfe)) start |= 2; else start &= ~2; pthread_mutex_unlock(&lfe->sf_dvr_lock); if (!tvheadend_is_running()) { exit_flag = 1; goto done; } @@ -1639,7 +1679,6 @@ new_tune: satip_frontend_tuning_error(lfe, tr); fatal = 1; } else { - satip_frontend_wake_other_waiting(lfe); strncpy((char *)session, rtsp->hc_rtsp_session ?: "", sizeof(session)); session[sizeof(session)-1] = '\0'; stream_id = rtsp->hc_rtsp_stream_id; @@ -1675,6 +1714,7 @@ new_tune: case RTSP_CMD_PLAY: if (!running) break; + satip_frontend_wake_other_waiting(lfe); if (rtsp->hc_code == 200 && play2) { play2 = 0; if (satip_frontend_pid_changed(rtsp, lfe, buf) > 0) { diff --git a/src/input/mpegts/satip/satip_private.h b/src/input/mpegts/satip/satip_private.h index 5e23d01cd..6802076bc 100644 --- a/src/input/mpegts/satip/satip_private.h +++ b/src/input/mpegts/satip/satip_private.h @@ -97,6 +97,7 @@ struct satip_device int sd_skip_ts; int sd_disable_workarounds; pthread_mutex_t sd_tune_mutex; + TAILQ_HEAD(,satip_frontend)sd_serialize_queue; }; struct satip_tune_req { @@ -156,7 +157,9 @@ struct satip_frontend uint32_t sf_seq; dvb_mux_t *sf_curmux; time_t sf_last_data_tstamp; - uint32_t sf_wait_for; + int sf_netlimit; + int sf_serialize; + TAILQ_ENTRY(satip_frontend)sf_serialize_link; /* * Configuration diff --git a/src/input/mpegts/satip/satip_satconf.c b/src/input/mpegts/satip/satip_satconf.c index 6dbd20b61..ed89f8903 100644 --- a/src/input/mpegts/satip/satip_satconf.c +++ b/src/input/mpegts/satip/satip_satconf.c @@ -167,9 +167,6 @@ retry: return 1; if (manage && lowest_lfe) { /* free tuner with lowest weight */ - pthread_mutex_lock(&lfe->sf_dvr_lock); - lfe->sf_wait_for |= 1 << lowest_lfe->sf_number; - pthread_mutex_unlock(&lfe->sf_dvr_lock); mm2 = lowest_lfe->sf_req->sf_mmi->mmi_mux; mm2->mm_stop(mm2, 1, SM_CODE_SUBSCRIPTION_OVERRIDDEN); goto retry;