From a22a2621b5aa26531a35b80a22bd85e3005d12e0 Mon Sep 17 00:00:00 2001 From: Jaroslav Kysela Date: Tue, 16 Jan 2018 12:32:28 +0100 Subject: [PATCH] service / channel: remove all subscriptions when disabled --- src/channels.c | 31 +++++++++++++++++++++++++++++++ src/channels.h | 2 ++ src/service.c | 2 ++ src/streaming.c | 2 ++ src/subscriptions.c | 37 ++++++++++++++++++++----------------- src/subscriptions.h | 2 +- src/tvheadend.h | 1 + 7 files changed, 59 insertions(+), 18 deletions(-) diff --git a/src/channels.c b/src/channels.c index 7ecba2051..baf8d1f5c 100644 --- a/src/channels.c +++ b/src/channels.c @@ -116,6 +116,14 @@ channel_class_delete ( idnode_t *self ) channel_delete((channel_t*)self, 1); } +static void +channel_class_notify_enabled ( void *obj, const char *lang ) +{ + channel_t *ch = (channel_t *)obj; + if (!ch->ch_enabled) + channel_remove_subscriber(ch, SM_CODE_CHN_NOT_ENABLED); +} + static int channel_class_autoname_set ( void *obj, const void *p ) { @@ -403,6 +411,7 @@ const idclass_t channel_class = { .desc = N_("Enable/disable the channel."), .def.i = 1, .off = offsetof(channel_t, ch_enabled), + .notify = channel_class_notify_enabled, }, { .type = PT_BOOL, @@ -765,6 +774,28 @@ channel_epg_update_all ( channel_t *ch ) channel_event_updated(e); } +/** + * Remove all subscribers for given channel + */ +void channel_remove_subscriber + ( channel_t *ch, int reason ) +{ + th_subscription_t *s, *s_next; + idnode_list_mapping_t *ilm; + service_t *t; + + lock_assert(&global_lock); + + LIST_FOREACH(ilm, &ch->ch_services, ilm_in2_link) { + t = (service_t *)ilm->ilm_in1; + for (s = LIST_FIRST(&t->s_subscriptions); s; s = s_next) { + s_next = LIST_NEXT(s, ths_service_link); + if (s->ths_channel == ch) + service_remove_subscriber(t, s, reason); + } + } +} + /* ************************************************************************** * Property updating * *************************************************************************/ diff --git a/src/channels.h b/src/channels.h index 47781a75d..12a9bfb6c 100644 --- a/src/channels.h +++ b/src/channels.h @@ -131,6 +131,8 @@ channel_t *channel_create0 void channel_delete(channel_t *ch, int delconf); +void channel_remove_subscriber(channel_t *ch, int reason); + channel_t *channel_find_by_name_and_bouquet(const char *name, const struct bouquet *bq); channel_t *channel_find_by_name(const char *name); /// Apply fuzzy matching when finding a channel such as ignoring diff --git a/src/service.c b/src/service.c index a2e8d0216..32a3deadd 100644 --- a/src/service.c +++ b/src/service.c @@ -70,6 +70,8 @@ service_class_notify_enabled ( void *obj, const char *lang ) if (t->s_enabled && t->s_auto != SERVICE_AUTO_OFF) t->s_auto = SERVICE_AUTO_NORMAL; bouquet_notify_service_enabled(t); + if (!t->s_enabled) + service_remove_subscriber(t, NULL, SM_CODE_SVC_NOT_ENABLED); } static const void * diff --git a/src/streaming.c b/src/streaming.c index a6af42a94..4ea670c66 100644 --- a/src/streaming.c +++ b/src/streaming.c @@ -490,6 +490,8 @@ streaming_code2txt(int code) return N_("No assigned adapters"); case SM_CODE_INVALID_SERVICE: return N_("Invalid service"); + case SM_CODE_CHN_NOT_ENABLED: + return N_("No channel enabled"); case SM_CODE_ABORTED: return N_("Aborted by user"); diff --git a/src/subscriptions.c b/src/subscriptions.c index 86f390823..f585bbdbd 100644 --- a/src/subscriptions.c +++ b/src/subscriptions.c @@ -52,6 +52,7 @@ static int subscription_postpone; /** * */ +static void subscription_reschedule(void); static void subscription_unsubscribe_cb(void *aux); /** @@ -309,6 +310,16 @@ subscription_ca_check_cb(void *aux) pthread_mutex_unlock(&t->s_stream_mutex); } +/** + * + */ +void +subscription_delayed_reschedule(int64_t mono) +{ + mtimer_arm_rel(&subscription_reschedule_timer, + subscription_reschedule_cb, NULL, mono); +} + /** * */ @@ -338,7 +349,7 @@ subscription_start_instance /** * */ -void +static void subscription_reschedule(void) { static int reenter = 0; @@ -436,9 +447,7 @@ subscription_reschedule(void) if (postpone <= 0 || postpone == INT_MAX) postpone = 2; - mtimer_arm_rel(&subscription_reschedule_timer, - subscription_reschedule_cb, NULL, sec2mono(postpone)); - + subscription_delayed_reschedule(sec2mono(postpone)); reenter = 0; } @@ -476,10 +485,9 @@ subscription_set_postpone(void *aux, const char *path, int64_t postpone) if (s->ths_postpone_end > now && s->ths_postpone_end - now > postpone2) s->ths_postpone_end = now + postpone2; } - mtimer_arm_rel(&subscription_reschedule_timer, - subscription_reschedule_cb, NULL, 0); + subscription_delayed_reschedule(0); } - pthread_mutex_unlock(&global_lock); + pthread_mutex_unlock(&global_lock); return postpone; } @@ -498,8 +506,7 @@ subscription_input_null(void *opaque, streaming_message_t *sm) th_subscription_t *s = opaque; if (sm->sm_type == SMT_STOP && subgetstate(s) != SUBSCRIPTION_ZOMBIE) { LIST_INSERT_HEAD(&subscriptions_remove, s, ths_remove_link); - mtimer_arm_rel(&subscription_reschedule_timer, - subscription_reschedule_cb, NULL, 0); + subscription_delayed_reschedule(0); } streaming_msg_free(sm); @@ -735,8 +742,7 @@ subscription_unsubscribe(th_subscription_t *s, int flags) (s->ths_flags & SUBSCRIPTION_ONESHOT) != 0) subscription_destroy(s); - mtimer_arm_rel(&subscription_reschedule_timer, - subscription_reschedule_cb, NULL, 0); + subscription_delayed_reschedule(0); notify_reload("subscriptions"); } @@ -818,8 +824,7 @@ subscription_create LIST_INSERT_SORTED(&subscriptions, s, ths_global_link, subscription_sort); - mtimer_arm_rel(&subscription_reschedule_timer, - subscription_reschedule_cb, NULL, 0); + subscription_delayed_reschedule(0); notify_reload("subscriptions"); return s; @@ -888,8 +893,7 @@ subscription_create_from_channel_or_service(profile_chain_t *prch, subscription_link_service(s, si->si_s); subscription_show_info(s); } else { - mtimer_arm_rel(&subscription_reschedule_timer, - subscription_reschedule_cb, NULL, 0); + subscription_delayed_reschedule(0); } return s; } @@ -1178,8 +1182,7 @@ subscription_change_weight(th_subscription_t *s, int weight) LIST_INSERT_SORTED(&subscriptions, s, ths_global_link, subscription_sort); - mtimer_arm_rel(&subscription_reschedule_timer, - subscription_reschedule_cb, NULL, 0); + subscription_delayed_reschedule(0); } /** diff --git a/src/subscriptions.h b/src/subscriptions.h index a79962615..aec5989d3 100644 --- a/src/subscriptions.h +++ b/src/subscriptions.h @@ -158,7 +158,7 @@ void subscription_unsubscribe(th_subscription_t *s, int flags); void subscription_set_weight(th_subscription_t *s, unsigned int weight); -void subscription_reschedule(void); +void subscription_delayed_reschedule(int64_t mono); th_subscription_t * subscription_create_from_channel(struct profile_chain *prch, diff --git a/src/tvheadend.h b/src/tvheadend.h index 5ed6f6685..24928ade9 100644 --- a/src/tvheadend.h +++ b/src/tvheadend.h @@ -555,6 +555,7 @@ typedef enum { #define SM_CODE_NO_VALID_ADAPTER 208 #define SM_CODE_NO_ADAPTERS 209 #define SM_CODE_INVALID_SERVICE 210 +#define SM_CODE_CHN_NOT_ENABLED 211 #define SM_CODE_ABORTED 300 -- 2.47.3