]> git.ipfire.org Git - thirdparty/tvheadend.git/commitdiff
linuxdvb: fix the exclusive frontend access, fixes #5330
authorJaroslav Kysela <perex@perex.cz>
Mon, 19 Nov 2018 11:07:14 +0000 (12:07 +0100)
committerJaroslav Kysela <perex@perex.cz>
Mon, 19 Nov 2018 11:07:14 +0000 (12:07 +0100)
src/input/mpegts/linuxdvb/linuxdvb_adapter.c
src/input/mpegts/linuxdvb/linuxdvb_frontend.c
src/input/mpegts/linuxdvb/linuxdvb_private.h

index 96b5c22a354f9d69bd4ff6f8e9647759bb8f4e7a..ad50987a2141867eab94eed0f88d5913db21709d 100644 (file)
@@ -370,7 +370,6 @@ linuxdvb_adapter_add ( const char *path )
   int delsys, fenum, type5;
   dvb_fe_type_t fetypes[DVB_TYPE_LAST+1];
   struct dtv_property cmd;
-  linuxdvb_frontend_t *lfe;
 #endif
 
   tvhtrace(LS_LINUXDVB, "scanning adapter %s", path);
@@ -610,29 +609,6 @@ linuxdvb_adapter_add ( const char *path )
   if (!la)
     return;
 
-#if DVB_VER_ATLEAST(5,5)
-  memset(fetypes, 0, sizeof(fetypes));
-  LIST_FOREACH(lfe, &la->la_frontends, lfe_link)
-    fetypes[lfe->lfe_type]++;
-  for (i = j = r = 0; i < ARRAY_SIZE(fetypes); i++) {
-    if (fetypes[i] > 1)
-      r++;
-    else if (fetypes[i] > 0)
-      j++;
-  }
-  if (r && j) {
-    la->la_exclusive = 1;
-    for (i = 0; i < ARRAY_SIZE(fetypes); i++)
-      if (fetypes[i] > 0)
-        tvhwarn(LS_LINUXDVB, "adapter %d has tuner count %d for type %s (wrong config)",
-                            a, fetypes[i], dvb_type2str(i));
-  } else if (!r && j > 1) {
-    la->la_exclusive = 1;
-  }
-  if (la->la_exclusive)
-    tvhinfo(LS_LINUXDVB, "adapter %d setting exclusive flag", a);
-#endif
-
   /* Save configuration */
   if (save && la)
     linuxdvb_adapter_changed(la);
index 82021020f409bc780b7a932fa2d29379e91d3545..9899eee617575df25169d2ab93c48706d3b26592 100644 (file)
@@ -63,10 +63,22 @@ const void *
 linuxdvb_frontend_class_active_get ( void *obj )
 {
   int *active;
-  linuxdvb_frontend_t *lfe = (linuxdvb_frontend_t*)obj;
+  linuxdvb_frontend_t *lfe = (linuxdvb_frontend_t*)obj, *lfe2;
   active = (int *)mpegts_input_class_active_get(obj);
-  if (!(*active) && lfe->lfe_adapter->la_exclusive)
-    *active = lfe->lfe_adapter->la_is_enabled(lfe->lfe_adapter);
+  if (!(*active)) {
+    if (lfe->mi_is_enabled((mpegts_input_t*)lfe, NULL, 0, -1) != MI_IS_ENABLED_NEVER) {
+      *active = 1;
+      return active;
+    }
+    LIST_FOREACH(lfe2, &lfe->lfe_adapter->la_frontends, lfe_link) {
+      if (lfe2 == lfe || strcmp(lfe2->lfe_fe_path, lfe->lfe_fe_path))
+        continue;
+      if (lfe2->mi_is_enabled((mpegts_input_t*)lfe2, NULL, 0, -1) != MI_IS_ENABLED_NEVER) {
+        *active = 1;
+        return active;
+      }
+    }
+  }
   return active;
 }
 
@@ -508,13 +520,13 @@ linuxdvb_frontend_open_fd ( linuxdvb_frontend_t *lfe, const char *name )
     return 0;
 
   /* Share FD across frontends */
-  if (lfe->lfe_adapter->la_exclusive) {
-    LIST_FOREACH(lfe2, &lfe->lfe_adapter->la_frontends, lfe_link) {
-      if (lfe2->lfe_fe_fd > 0) {
-        lfe->lfe_fe_fd = dup(lfe2->lfe_fe_fd);
-        extra = " (shared)";
-        break;
-      }
+  LIST_FOREACH(lfe2, &lfe->lfe_adapter->la_frontends, lfe_link) {
+    if (lfe2 == lfe || strcmp(lfe->lfe_fe_path, lfe2->lfe_fe_path))
+      continue;
+    if (lfe2->lfe_fe_fd > 0) {
+      lfe->lfe_fe_fd = dup(lfe2->lfe_fe_fd);
+      extra = " (shared)";
+      break;
     }
   }
 
@@ -555,13 +567,12 @@ static int
 linuxdvb_frontend_get_weight ( mpegts_input_t *mi, mpegts_mux_t *mm, int flags, int weight )
 {
   int w = 0;
-  linuxdvb_adapter_t *la = ((linuxdvb_frontend_t*)mi)->lfe_adapter;
-  linuxdvb_frontend_t *lfe;
-  if (la->la_exclusive) {
-    LIST_FOREACH(lfe, &la->la_frontends, lfe_link)
-      w = MAX(w, mpegts_input_get_weight((mpegts_input_t*)lfe, mm, flags, weight));
-  } else {
-    w = mpegts_input_get_weight(mi, mm, flags, weight);
+  linuxdvb_frontend_t *lfe = (linuxdvb_frontend_t*)mi, *lfe2;
+  w = mpegts_input_get_weight(mi, mm, flags, weight);
+  LIST_FOREACH(lfe2, &lfe->lfe_adapter->la_frontends, lfe_link) {
+    if (lfe2 == lfe || strcmp(lfe->lfe_fe_path, lfe2->lfe_fe_path))
+      continue;
+    w = MAX(w, mpegts_input_get_weight((mpegts_input_t*)lfe2, mm, flags, weight));
   }
   return w;
 }
@@ -640,15 +651,13 @@ linuxdvb_frontend_is_enabled
 
 
 ok:
-  if (lfe->lfe_adapter->la_exclusive) {
-    w = -1;
-    LIST_FOREACH(lfe2, &lfe->lfe_adapter->la_frontends, lfe_link) {
-      if (lfe2 == lfe) continue;
-      w = MAX(w, mpegts_input_get_weight((mpegts_input_t *)lfe2, mm, flags, weight));
-    }
-    if (w >= weight)
-      return MI_IS_ENABLED_RETRY;
+  w = -1;
+  LIST_FOREACH(lfe2, &lfe->lfe_adapter->la_frontends, lfe_link) {
+    if (lfe2 == lfe || strcmp(lfe2->lfe_fe_path, lfe->lfe_fe_path)) continue;
+    w = MAX(w, mpegts_input_get_weight((mpegts_input_t *)lfe2, mm, flags, weight));
   }
+  if (w >= weight)
+    return MI_IS_ENABLED_RETRY;
 
   return MI_IS_ENABLED_OK;
 }
@@ -725,12 +734,9 @@ linuxdvb_frontend_warm_mux ( mpegts_input_t *mi, mpegts_mux_instance_t *mmi )
   if (r)
     return r;
 
-  if (!lfe->lfe_adapter->la_exclusive)
-    return 0;
-
   /* Stop other active frontend (should be only one) */
   LIST_FOREACH(lfe2, &lfe->lfe_adapter->la_frontends, lfe_link) {
-    if (lfe2 == lfe) continue;
+    if (lfe2 == lfe || strcmp(lfe2->lfe_fe_path, lfe->lfe_fe_path)) continue;
     pthread_mutex_lock(&lfe2->mi_output_lock);
     lmmi = LIST_FIRST(&lfe2->mi_mux_active);
     pthread_mutex_unlock(&lfe2->mi_output_lock);
index 2ace1d746e528d7c1c934a90d12bca16a0f5dc99..124b46c14a255cbec1c3d2b2986a00fa009ea59e 100644 (file)
@@ -70,7 +70,6 @@ struct linuxdvb_adapter
   char    *la_name;
   char    *la_rootpath;
   int      la_dvb_number;
-  int      la_exclusive; /* one frontend at a time */
 
   /*
    * Frontends