From: Jaroslav Kysela Date: Sun, 8 Nov 2015 09:00:52 +0000 (+0100) Subject: subscription: another try to protect removed services X-Git-Tag: v4.2.1~1629 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=5fe5abbc5cb5d98d3858978c78e8529902d4fae7;p=thirdparty%2Ftvheadend.git subscription: another try to protect removed services --- diff --git a/src/dvr/dvr_rec.c b/src/dvr/dvr_rec.c index 2de196ce9..aefed3e2b 100644 --- a/src/dvr/dvr_rec.c +++ b/src/dvr/dvr_rec.c @@ -171,7 +171,7 @@ dvr_rec_unsubscribe(dvr_entry_t *de) pthread_join(de->de_thread, NULL); - subscription_unsubscribe(de->de_s, 0); + subscription_unsubscribe(de->de_s, UNSUBSCRIBE_FINAL); de->de_s = NULL; de->de_chain = NULL; diff --git a/src/htsp_server.c b/src/htsp_server.c index a3e053594..05a61e6dc 100644 --- a/src/htsp_server.c +++ b/src/htsp_server.c @@ -342,7 +342,7 @@ htsp_subscription_destroy(htsp_connection_t *htsp, htsp_subscription_t *hs) LIST_REMOVE(hs, hs_link); LIST_INSERT_HEAD(&htsp->htsp_dead_subscriptions, hs, hs_link); - subscription_unsubscribe(hs->hs_s, 0); + subscription_unsubscribe(hs->hs_s, UNSUBSCRIBE_FINAL); if(hs->hs_prch.prch_st != NULL) profile_chain_close(&hs->hs_prch); diff --git a/src/input/mpegts/mpegts_mux.c b/src/input/mpegts/mpegts_mux.c index 459dfaaf5..734cd01a6 100644 --- a/src/input/mpegts/mpegts_mux.c +++ b/src/input/mpegts/mpegts_mux.c @@ -210,7 +210,7 @@ mpegts_mux_unsubscribe_linked ths_next = LIST_NEXT(ths, ths_global_link); if (ths->ths_source == (tvh_input_t *)mi && !strcmp(ths->ths_title, "keep") && ths->ths_service != t) - subscription_unsubscribe(ths, 0); + subscription_unsubscribe(ths, UNSUBSCRIBE_FINAL); } } } @@ -1256,7 +1256,7 @@ mpegts_mux_unsubscribe_by_name n = LIST_NEXT(s, ths_mux_link); t = s->ths_service; if (t && t->s_type == STYPE_RAW && !strcmp(s->ths_title, name)) - subscription_unsubscribe(s, 0); + subscription_unsubscribe(s, UNSUBSCRIBE_FINAL); s = n; } } diff --git a/src/input/mpegts/mpegts_mux_sched.c b/src/input/mpegts/mpegts_mux_sched.c index 93cf2ab9e..368b343ea 100644 --- a/src/input/mpegts/mpegts_mux_sched.c +++ b/src/input/mpegts/mpegts_mux_sched.c @@ -39,7 +39,7 @@ mpegts_mux_sched_set_timer ( mpegts_mux_sched_t *mms ) /* Upate timer */ if (!mms->mms_enabled) { if (mms->mms_sub) - subscription_unsubscribe(mms->mms_sub, 0); + subscription_unsubscribe(mms->mms_sub, UNSUBSCRIBE_FINAL); mms->mms_sub = NULL; mms->mms_active = 0; gtimer_disarm(&mms->mms_timer); @@ -232,7 +232,7 @@ mpegts_mux_sched_timer ( void *p ) /* Cancel sub */ } else { if (mms->mms_sub) { - subscription_unsubscribe(mms->mms_sub, 0); + subscription_unsubscribe(mms->mms_sub, UNSUBSCRIBE_FINAL); mms->mms_sub = NULL; } mms->mms_active = 0; @@ -310,7 +310,7 @@ mpegts_mux_sched_delete ( mpegts_mux_sched_t *mms, int delconf ) if (delconf) hts_settings_remove("muxsched/%s", idnode_uuid_as_sstr(&mms->mms_id)); if (mms->mms_sub) - subscription_unsubscribe(mms->mms_sub, 0); + subscription_unsubscribe(mms->mms_sub, UNSUBSCRIBE_FINAL); gtimer_disarm(&mms->mms_timer); idnode_unlink(&mms->mms_id); free(mms->mms_cronstr); diff --git a/src/satip/rtsp.c b/src/satip/rtsp.c index f5c42c113..9450bf53d 100644 --- a/src/satip/rtsp.c +++ b/src/satip/rtsp.c @@ -335,7 +335,7 @@ rtsp_slave_remove rs->frontend, rs->session, rs->stream, slave->s_nicename); master->s_unlink(master, slave); if (sub->ths) - subscription_unsubscribe(sub->ths, 0); + subscription_unsubscribe(sub->ths, UNSUBSCRIBE_FINAL); if (sub->prch.prch_id) profile_chain_close(&sub->prch); LIST_REMOVE(sub, link); @@ -358,7 +358,7 @@ rtsp_clean(session_t *rs) while ((sub = LIST_FIRST(&rs->slaves)) != NULL) rtsp_slave_remove(rs, (mpegts_service_t *)rs->subs->ths_raw_service, sub->service); - subscription_unsubscribe(rs->subs, 0); + subscription_unsubscribe(rs->subs, UNSUBSCRIBE_FINAL); rs->subs = NULL; } if (rs->prch.prch_id) diff --git a/src/service_mapper.c b/src/service_mapper.c index 3a35cd109..acfb6ab1c 100644 --- a/src/service_mapper.c +++ b/src/service_mapper.c @@ -382,7 +382,7 @@ service_mapper_thread ( void *aux ) pthread_mutex_unlock(&sq->sq_mutex); pthread_mutex_lock(&global_lock); - subscription_unsubscribe(sub, 0); + subscription_unsubscribe(sub, UNSUBSCRIBE_FINAL); if(err) { tvhinfo("service_mapper", "%s: failed [err %s]", s->s_nicename, err); diff --git a/src/subscriptions.c b/src/subscriptions.c index 73861ac13..ead7e2c84 100644 --- a/src/subscriptions.c +++ b/src/subscriptions.c @@ -145,7 +145,7 @@ subscription_unlink_service0(th_subscription_t *s, int reason, int stop) LIST_REMOVE(s, ths_service_link); - if (stop && s-(s->ths_flags & SUBSCRIPTION_ONESHOT) != 0) + if (stop && (s->ths_flags & SUBSCRIPTION_ONESHOT) != 0) gtimer_arm(&s->ths_remove_timer, subscription_unsubscribe_cb, s, 0); stop: @@ -554,11 +554,28 @@ subscription_input(void *opauqe, streaming_message_t *sm) static void subscription_unsubscribe_cb(void *aux) { - subscription_unsubscribe((th_subscription_t *)aux, 0); + subscription_unsubscribe((th_subscription_t *)aux, UNSUBSCRIBE_FINAL); +} + +static void +subscription_destroy(th_subscription_t *s) +{ + streaming_msg_free(s->ths_start_message); + + if(s->ths_output->st_cb == subscription_input_null) + free(s->ths_output); + + free(s->ths_title); + free(s->ths_hostname); + free(s->ths_username); + free(s->ths_client); + free(s->ths_dvrfile); + free(s); + } void -subscription_unsubscribe(th_subscription_t *s, int quiet) +subscription_unsubscribe(th_subscription_t *s, int flags) { service_t *t; char buf[512]; @@ -573,7 +590,13 @@ subscription_unsubscribe(th_subscription_t *s, int quiet) t = s->ths_service; raw = s->ths_raw_service; - assert(s->ths_state != SUBSCRIPTION_ZOMBIE); + if (s->ths_state == SUBSCRIPTION_ZOMBIE) { + if ((flags & UNSUBSCRIBE_FINAL) != 0) { + subscription_destroy(s); + return; + } + abort(); + } s->ths_state = SUBSCRIPTION_ZOMBIE; service_instance_list_clear(&s->ths_instances); @@ -602,24 +625,17 @@ subscription_unsubscribe(th_subscription_t *s, int quiet) tvh_strlcatf(buf, sizeof(buf), l, ", username=\"%s\"", s->ths_username); if (s->ths_client) tvh_strlcatf(buf, sizeof(buf), l, ", client=\"%s\"", s->ths_client); - tvhlog(quiet ? LOG_TRACE : LOG_INFO, "subscription", "%04X: %s", shortid(s), buf); + tvhlog((flags & UNSUBSCRIBE_QUIET) != 0 ? LOG_TRACE : LOG_INFO, + "subscription", "%04X: %s", shortid(s), buf); if (t) service_remove_subscriber(t, s, SM_CODE_OK); gtimer_disarm(&s->ths_remove_timer); - streaming_msg_free(s->ths_start_message); - - if(s->ths_output->st_cb == subscription_input_null) - free(s->ths_output); - - free(s->ths_title); - free(s->ths_hostname); - free(s->ths_username); - free(s->ths_client); - free(s->ths_dvrfile); - free(s); + if ((flags & UNSUBSCRIBE_FINAL) != 0 || + (s->ths_flags & SUBSCRIPTION_ONESHOT) != 0) + subscription_destroy(s); gtimer_arm(&subscription_reschedule_timer, subscription_reschedule_cb, NULL, 0); @@ -763,7 +779,7 @@ subscription_create_from_channel_or_service(profile_chain_t *prch, if (flags & SUBSCRIPTION_ONESHOT) { if ((si = subscription_start_instance(s, error)) == NULL) { - subscription_unsubscribe(s, 1); + subscription_unsubscribe(s, UNSUBSCRIBE_QUIET | UNSUBSCRIBE_FINAL); return NULL; } subscription_link_service(s, si->si_s); diff --git a/src/subscriptions.h b/src/subscriptions.h index 1d8311ceb..25f171870 100644 --- a/src/subscriptions.h +++ b/src/subscriptions.h @@ -53,6 +53,10 @@ extern struct th_subscription_list subscriptions; #define SUBSCRIPTION_PRIO_MAPPER 7 ///< Channel mapper #define SUBSCRIPTION_PRIO_MIN 10 ///< User defined / Normal levels +/* Unsubscribe flags */ +#define UNSUBSCRIBE_QUIET 0x01 +#define UNSUBSCRIBE_FINAL 0x02 + typedef struct th_subscription { int ths_id; @@ -144,7 +148,7 @@ void subscription_init(void); void subscription_done(void); -void subscription_unsubscribe(th_subscription_t *s, int quiet); +void subscription_unsubscribe(th_subscription_t *s, int flags); void subscription_set_weight(th_subscription_t *s, unsigned int weight); diff --git a/src/webui/webui.c b/src/webui/webui.c index a778e6db0..f7f7a82e1 100644 --- a/src/webui/webui.c +++ b/src/webui/webui.c @@ -1087,7 +1087,7 @@ http_stream_service(http_connection_t *hc, service_t *service, int weight) pthread_mutex_unlock(&global_lock); http_stream_run(hc, &prch, name, s); pthread_mutex_lock(&global_lock); - subscription_unsubscribe(s, 0); + subscription_unsubscribe(s, UNSUBSCRIBE_FINAL); res = 0; } } @@ -1167,7 +1167,7 @@ http_stream_mux(http_connection_t *hc, mpegts_mux_t *mm, int weight) http_stream_run(hc, &prch, name, s); pthread_mutex_lock(&global_lock); } - subscription_unsubscribe(s, 0); + subscription_unsubscribe(s, UNSUBSCRIBE_FINAL); res = 0; } } @@ -1226,7 +1226,7 @@ http_stream_channel(http_connection_t *hc, channel_t *ch, int weight) pthread_mutex_unlock(&global_lock); http_stream_run(hc, &prch, name, s); pthread_mutex_lock(&global_lock); - subscription_unsubscribe(s, 0); + subscription_unsubscribe(s, UNSUBSCRIBE_FINAL); res = 0; } } @@ -1629,7 +1629,7 @@ page_dvrfile(http_connection_t *hc, const char *remain, void *opaque) pthread_mutex_lock(&global_lock); if (sub) - subscription_unsubscribe(sub, 0); + subscription_unsubscribe(sub, UNSUBSCRIBE_FINAL); http_stream_postop(tcp_id); pthread_mutex_unlock(&global_lock); return ret;