From 87a232ebb84a55e0d85b233910d8e519705fb3cc Mon Sep 17 00:00:00 2001 From: Adam Sutton Date: Tue, 10 Jun 2014 20:22:40 +0100 Subject: [PATCH] mpegts network_scan: fix problems with having multiple networks previously as soon as any mux failed it would give up assuming nothing else could be tuned. However just because no tuner was available that could service that mux doesn't mean there wasn't one that couldn't service another. The only real issue I can see with this is if we're idle scanning it's possible due to bad luck to starve muxes of an attempt. We can either rely on random chance or put some additional weighting based on time? Though that could be problematic for other reasons. --- src/input/mpegts/mpegts_network_scan.c | 45 ++++++++++++-------------- 1 file changed, 21 insertions(+), 24 deletions(-) diff --git a/src/input/mpegts/mpegts_network_scan.c b/src/input/mpegts/mpegts_network_scan.c index acb9c9b1..10d5c894 100644 --- a/src/input/mpegts/mpegts_network_scan.c +++ b/src/input/mpegts/mpegts_network_scan.c @@ -60,16 +60,14 @@ mpegts_network_scan_timer_arm ( int period ) static void mpegts_network_scan_timer_cb ( void *p ) { - mpegts_mux_t *mm, *mark = NULL; + mpegts_mux_t *mm, *nxt = NULL; int r; /* Process Q */ - while ((mm = TAILQ_FIRST(&mpegts_network_scan_pend))) { + for (mm = TAILQ_FIRST(&mpegts_network_scan_pend); mm != NULL; mm = nxt) { + nxt = TAILQ_NEXT(mm, mm_scan_link); assert(mm->mm_scan_state == MM_SCAN_STATE_PEND); - /* Stop (looped) */ - if (mm == mark) break; - /* Attempt to tune */ r = mpegts_mux_subscribe(mm, "scan", mm->mm_scan_weight); @@ -80,23 +78,16 @@ mpegts_network_scan_timer_cb ( void *p ) } assert(mm->mm_scan_state == MM_SCAN_STATE_PEND); - /* Stop (no free tuners) */ - if (r == SM_CODE_NO_FREE_ADAPTER) - break; - - /* Available tuners can't be used - * Note: this is subtly different it does not imply there are no free - * tuners, just that none of the free ones can service this mux. - * therefore we move this to the back of the queue and see if we - * can find one we can tune + /* Either there are no free tuners, or no valid tuners + * + * Although these are subtly different, the reality is that in this + * context we need to treat each the same. We simply skip over this + * mux and see if anything else can be tuned as it may use other + * tuners */ - if (r == SM_CODE_NO_VALID_ADAPTER) { - if (!mark) mark = mm; - TAILQ_REMOVE(&mpegts_network_scan_pend, mm, mm_scan_link); - TAILQ_INSERT_SORTED_R(&mpegts_network_scan_pend, mpegts_mux_queue, - mm, mm_scan_link, mm_cmp); + if (r == SM_CODE_NO_FREE_ADAPTER || + r == SM_CODE_NO_VALID_ADAPTER) continue; - } /* Failed */ TAILQ_REMOVE(&mpegts_network_scan_pend, mm, mm_scan_link); @@ -105,13 +96,14 @@ mpegts_network_scan_timer_cb ( void *p ) mm->mm_config_save(mm); } mm->mm_scan_state = MM_SCAN_STATE_IDLE; + mm->mm_scan_weight = 0; mpegts_network_scan_notify(mm); } - /* Re-arm (backstop, most things will auto-rearm at point of next event - * such as timeout of scan or completion) + /* Re-arm timer. Really this is just a safety measure as we'd normally + * expect the timer to be forcefully triggered on finish of a mux scan */ - mpegts_network_scan_timer_arm(10); + mpegts_network_scan_timer_arm(120); } /****************************************************************************** @@ -194,7 +186,8 @@ mpegts_network_scan_queue_del ( mpegts_mux_t *mm ) } else if (mm->mm_scan_state == MM_SCAN_STATE_PEND) { TAILQ_REMOVE(&mpegts_network_scan_pend, mm, mm_scan_link); } - mm->mm_scan_state = MM_SCAN_STATE_IDLE; + mm->mm_scan_state = MM_SCAN_STATE_IDLE; + mm->mm_scan_weight = 0; gtimer_disarm(&mm->mm_scan_timeout); mpegts_network_scan_timer_arm(0); mpegts_network_scan_notify(mm); @@ -204,6 +197,7 @@ void mpegts_network_scan_queue_add ( mpegts_mux_t *mm, int weight ) { int reload = 0; + char buf[256]; if (!mm->mm_is_enabled(mm)) return; @@ -225,6 +219,9 @@ mpegts_network_scan_queue_add ( mpegts_mux_t *mm, int weight ) TAILQ_REMOVE(&mpegts_network_scan_pend, mm, mm_scan_link); } + mm->mm_display_name(mm, buf, sizeof(buf)); + tvhdebug("mpegts", "adding mux %p:%s to queue weight %d", mm, buf, weight); + /* Add new entry */ mm->mm_scan_state = MM_SCAN_STATE_PEND; TAILQ_INSERT_SORTED_R(&mpegts_network_scan_pend, mpegts_mux_queue,