]> git.ipfire.org Git - thirdparty/tvheadend.git/commitdiff
subscription: another try to protect removed services
authorJaroslav Kysela <perex@perex.cz>
Sun, 8 Nov 2015 09:00:52 +0000 (10:00 +0100)
committerJaroslav Kysela <perex@perex.cz>
Sun, 8 Nov 2015 09:00:52 +0000 (10:00 +0100)
src/dvr/dvr_rec.c
src/htsp_server.c
src/input/mpegts/mpegts_mux.c
src/input/mpegts/mpegts_mux_sched.c
src/satip/rtsp.c
src/service_mapper.c
src/subscriptions.c
src/subscriptions.h
src/webui/webui.c

index 2de196ce972fa463e30170cbf631ac9006f71d8b..aefed3e2babbc9ec5d5677540a528456db8069b5 100644 (file)
@@ -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;
index a3e053594da26622a5962d3df4769c67790a353b..05a61e6dc1b2c3cc34972b738e5a44cee1b6aa9f 100644 (file)
@@ -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);
index 459dfaaf521395637610f2cab480dc172185aadc..734cd01a665ded7a0d6a0e7953cfbb4df4c22e1a 100644 (file)
@@ -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;
   }
 }
index 93cf2ab9ed09cbb36823d8a9c0e66a461e36fb41..368b343ea2ca837866d04107fad0c3a532de9461 100644 (file)
@@ -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);
index f5c42c113c67d8eff4cd401e0e2717c80b8dc655..9450bf53d0cf0baae8b781af70ba854c1f27de65 100644 (file)
@@ -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)
index 3a35cd10940b70d8017d2d0ee931a04e78b9bf58..acfb6ab1cf41d94835a9bc9a51588ffc13dbeb5d 100644 (file)
@@ -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);
index 73861ac133165414b599c86f6f80e3b9b0661739..ead7e2c84e39a3c276628414b2dbc1772c5a26b1 100644 (file)
@@ -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);
index 1d8311ceb1d7ece40b258888699fb4b6420af546..25f171870b0abbd71526996dc418b82c18ac77e7 100644 (file)
@@ -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);
 
index a778e6db0ee46ea5247f29797450629f09515ed3..f7f7a82e1c50b2a149d9afee754267a0c576577e 100644 (file)
@@ -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;