From 83f65243447d932b78be29dd70aa05afaaeccede Mon Sep 17 00:00:00 2001 From: Adam Sutton Date: Wed, 11 Sep 2013 22:12:40 +0100 Subject: [PATCH] subscription: fix double list insertion on detection of bad service If a service was marked as bad (no input) it was not unlinking the subscription from the service before re-applying, this resulted in a double entry into the service subs list and ultimatey a livelock or possibly worse. --- src/subscriptions.c | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/src/subscriptions.c b/src/subscriptions.c index 7ad7766f..323a9446 100644 --- a/src/subscriptions.c +++ b/src/subscriptions.c @@ -108,8 +108,8 @@ subscription_link_service(th_subscription_t *s, service_t *t) /** * Called from service code */ -void -subscription_unlink_service(th_subscription_t *s, int reason) +static void +subscription_unlink_service0(th_subscription_t *s, int reason, int stop) { streaming_message_t *sm; service_t *t = s->ths_service; @@ -118,10 +118,10 @@ subscription_unlink_service(th_subscription_t *s, int reason) pthread_mutex_lock(&t->s_stream_mutex); - // Unlink from service output streaming_target_disconnect(&t->s_streaming_pad, &s->ths_input); - if(TAILQ_FIRST(&t->s_components) != NULL && + if(stop && + TAILQ_FIRST(&t->s_components) != NULL && s->ths_state == SUBSCRIPTION_GOT_SERVICE) { // Send a STOP message to the subscription client sm = streaming_msg_create_code(SMT_STOP, reason); @@ -134,6 +134,12 @@ subscription_unlink_service(th_subscription_t *s, int reason) s->ths_service = NULL; } +void +subscription_unlink_service(th_subscription_t *s, int reason) +{ + subscription_unlink_service0(s, reason, 1); +} + /* * Called from mpegts code */ @@ -209,11 +215,14 @@ subscription_reschedule(void) if(s->ths_state != SUBSCRIPTION_BAD_SERVICE) continue; /* And it not bad, so we're happy */ + subscription_unlink_service0(s, SM_CODE_BAD_SOURCE, 0); + si = s->ths_current_instance; assert(si != NULL); si->si_error = s->ths_testing_error; time(&si->si_error_time); + } if (s->ths_channel)