From 636b476218b2b8cb18fa4015c4c24a9897049e72 Mon Sep 17 00:00:00 2001 From: Adam Sutton Date: Mon, 2 Jul 2012 17:29:57 +0100 Subject: [PATCH] Slight tweak to the way the EPG grabbers install table handlers. Do not pass the epggrab_ota_mux ptr since these could be freed in another thread. Instead look them up as required. There is probably a better way of handling this by keeping a list of th_dvb_tables in the ota object and deleting them whenever the ota object is destroyed, but its more prone to mistake (I think). Relates to #27. --- src/epggrab/module/eit.c | 17 +++++++++++------ src/epggrab/module/opentv.c | 26 +++++++++++++++++--------- src/epggrab/otamux.c | 18 ++++++++++++++---- src/epggrab/private.h | 2 ++ 4 files changed, 44 insertions(+), 19 deletions(-) diff --git a/src/epggrab/module/eit.c b/src/epggrab/module/eit.c index 5b4d81b9..b23592bb 100644 --- a/src/epggrab/module/eit.c +++ b/src/epggrab/module/eit.c @@ -145,7 +145,8 @@ static int _eit_callback ( th_dvb_mux_instance_t *tdmi, uint8_t *ptr, int len, uint8_t tableid, void *opaque ) { - epggrab_ota_mux_t *ota = (epggrab_ota_mux_t*)opaque; + epggrab_module_ota_t *mod = opaque; + epggrab_ota_mux_t *ota; th_dvb_adapter_t *tda; service_t *svc; channel_t *ch; @@ -167,15 +168,19 @@ static int _eit_callback if(tableid < 0x4e || tableid > 0x6f || len < 11) return -1; - /* Get tsid/sid */ - sid = ptr[0] << 8 | ptr[1]; - tsid = ptr[5] << 8 | ptr[6]; + /* Get OTA */ + ota = epggrab_ota_find(mod, tdmi); + if (!ota || !ota->status) return 0; + sta = ota->status; /* Already complete */ if (epggrab_ota_is_complete(ota)) return 0; + /* Get tsid/sid */ + sid = ptr[0] << 8 | ptr[1]; + tsid = ptr[5] << 8 | ptr[6]; + /* Started */ - sta = ota->status; if (epggrab_ota_begin(ota)) { sta->tid = tableid; sta->tsid = tsid; @@ -416,7 +421,7 @@ static void _eit_start if (!(ota = epggrab_ota_create(m, tdmi))) return; if (!ota->status) ota->status = calloc(1, sizeof(eit_status_t)); - tdt_add(tdmi, NULL, _eit_callback, ota, "eit", TDT_CRC, 0x12, NULL); + tdt_add(tdmi, NULL, _eit_callback, m, "eit", TDT_CRC, 0x12, NULL); tvhlog(LOG_DEBUG, "eit", "install table handlers"); } diff --git a/src/epggrab/module/opentv.c b/src/epggrab/module/opentv.c index 8fb2219b..248a11bd 100644 --- a/src/epggrab/module/opentv.c +++ b/src/epggrab/module/opentv.c @@ -533,11 +533,16 @@ static int _opentv_bat_section static epggrab_ota_mux_t *_opentv_event_callback ( th_dvb_mux_instance_t *tdmi, uint8_t *buf, int len, uint8_t tid, void *p ) { - th_dvb_table_t *tdt = (th_dvb_table_t*)p; - epggrab_ota_mux_t *ota = tdt->tdt_opaque; - opentv_status_t *sta = ota->status; + th_dvb_table_t *tdt = p; + opentv_module_t *mod = tdt->tdt_opaque; + epggrab_ota_mux_t *ota = epggrab_ota_find((epggrab_module_ota_t*)mod, tdmi); + opentv_status_t *sta; opentv_pid_t *pid; + /* Ignore (invalid - stopped?) */ + if (!ota || !ota->status) return NULL; + sta = ota->status; + /* Ignore (not enough data) */ if (len < 20) return NULL; @@ -615,10 +620,13 @@ static int _opentv_summary_callback static int _opentv_channel_callback ( th_dvb_mux_instance_t *tdmi, uint8_t *buf, int len, uint8_t tid, void *p ) { - epggrab_ota_mux_t *ota = (epggrab_ota_mux_t*)p; - opentv_status_t *sta = ota->status; + opentv_module_t *mod = p; + epggrab_ota_mux_t *ota = epggrab_ota_find((epggrab_module_ota_t*)mod, tdmi); + opentv_status_t *sta; + if (!ota || !ota->status) return 0; + sta = ota->status; if (!sta->endbat) - return _opentv_bat_section((opentv_module_t*)ota->grab, sta, buf, len); + return _opentv_bat_section(mod, sta, buf, len); return 0; } @@ -680,7 +688,7 @@ static void _opentv_start fp->filter.filter[0] = 0x4a; fp->filter.mask[0] = 0xff; // TODO: what about 0x46 (service description) - tdt_add(tdmi, fp, _opentv_channel_callback, ota, + tdt_add(tdmi, fp, _opentv_channel_callback, m, m->id, TDT_CRC, *t++, NULL); } @@ -691,7 +699,7 @@ static void _opentv_start fp->filter.filter[0] = 0xa0; fp->filter.mask[0] = 0xfc; _opentv_status_get_pid(sta, *t); - tdt_add(tdmi, fp, _opentv_title_callback, ota, + tdt_add(tdmi, fp, _opentv_title_callback, m, m->id, TDT_CRC | TDT_TDT, *t++, NULL); } @@ -702,7 +710,7 @@ static void _opentv_start fp->filter.filter[0] = 0xa8; fp->filter.mask[0] = 0xfc; _opentv_status_get_pid(sta, *t); - tdt_add(tdmi, fp, _opentv_summary_callback, ota, + tdt_add(tdmi, fp, _opentv_summary_callback, m, m->id, TDT_CRC | TDT_TDT, *t++, NULL); } } diff --git a/src/epggrab/otamux.c b/src/epggrab/otamux.c index 6f9a6876..065687e3 100644 --- a/src/epggrab/otamux.c +++ b/src/epggrab/otamux.c @@ -122,6 +122,19 @@ static int _ota_time_cmp ( void *_a, void *_b ) return wa - wb; } +/* + * Find existing link + */ +epggrab_ota_mux_t *epggrab_ota_find + ( epggrab_module_ota_t *mod, th_dvb_mux_instance_t *tdmi ) +{ + epggrab_ota_mux_t *ota; + TAILQ_FOREACH(ota, &mod->muxes, grab_link) { + if (ota->tdmi == tdmi) break; + } + return ota; +} + /* * Create (temporary) or Find (existing) link */ @@ -129,10 +142,7 @@ epggrab_ota_mux_t *epggrab_ota_create ( epggrab_module_ota_t *mod, th_dvb_mux_instance_t *tdmi ) { /* Search for existing */ - epggrab_ota_mux_t *ota; - TAILQ_FOREACH(ota, &ota_mux_all, glob_link) { - if (ota->grab == mod && ota->tdmi == tdmi) break; - } + epggrab_ota_mux_t *ota = epggrab_ota_find(mod, tdmi); /* Create new */ if (!ota) { diff --git a/src/epggrab/private.h b/src/epggrab/private.h index c4b94374..875422c2 100644 --- a/src/epggrab/private.h +++ b/src/epggrab/private.h @@ -96,6 +96,8 @@ epggrab_module_ota_t *epggrab_module_ota_create * Note: this will return NULL for an already existing link that is currently * blocked (i.e. has completed within interval period) */ +epggrab_ota_mux_t *epggrab_ota_find + ( epggrab_module_ota_t *mod, struct th_dvb_mux_instance *tdmi ); epggrab_ota_mux_t *epggrab_ota_create ( epggrab_module_ota_t *mod, struct th_dvb_mux_instance *tdmi ); void epggrab_ota_create_and_register_by_id