From 8602487ae6f44d72b41fb345e5897d38a4f0e22a Mon Sep 17 00:00:00 2001 From: Jaroslav Kysela Date: Mon, 29 Sep 2014 10:09:44 +0200 Subject: [PATCH] epggrab: fix memory leaks on shutdown for opentv/pyepg/xmltv --- src/channels.c | 2 +- src/epggrab.c | 2 ++ src/epggrab.h | 2 +- src/epggrab/channel.c | 27 +++++++++++++++++++++++++-- src/epggrab/module.c | 2 +- src/epggrab/module/opentv.c | 7 +++++-- src/epggrab/module/pyepg.c | 7 +++++++ src/epggrab/module/xmltv.c | 7 +++++++ src/epggrab/private.h | 7 +++++++ 9 files changed, 56 insertions(+), 7 deletions(-) diff --git a/src/channels.c b/src/channels.c index ad37629b..cdca4ef5 100644 --- a/src/channels.c +++ b/src/channels.c @@ -263,7 +263,7 @@ channel_class_epggrab_set ( void *o, const void *v ) for (ecl = LIST_FIRST(&ch->ch_epggrab); ecl != NULL; ecl = n) { n = LIST_NEXT(ecl, ecl_chn_link); if (ecl->ecl_mark) { - epggrab_channel_link_delete(ecl); + epggrab_channel_link_delete(ecl, 1); save = 1; } } diff --git a/src/epggrab.c b/src/epggrab.c index 97d6d947..dfa349ea 100644 --- a/src/epggrab.c +++ b/src/epggrab.c @@ -413,6 +413,8 @@ void epggrab_done ( void ) epggrab_ota_shutdown(); eit_done(); opentv_done(); + pyepg_done(); + xmltv_done(); free(epggrab_cron); epggrab_cron = NULL; free(epggrab_cron_multi); diff --git a/src/epggrab.h b/src/epggrab.h index b3a5a95a..79358304 100644 --- a/src/epggrab.h +++ b/src/epggrab.h @@ -112,7 +112,7 @@ int epggrab_channel_set_number ( epggrab_channel_t *ch, int number ); * Updated/link */ void epggrab_channel_updated ( epggrab_channel_t *ch ); -void epggrab_channel_link_delete ( epggrab_channel_link_t *ecl ); +void epggrab_channel_link_delete ( epggrab_channel_link_t *ecl, int delconf ); int epggrab_channel_link ( epggrab_channel_t *ec, struct channel *ch ); /* ID */ diff --git a/src/epggrab/channel.c b/src/epggrab/channel.c index 7f02f1da..595dbb33 100644 --- a/src/epggrab/channel.c +++ b/src/epggrab/channel.c @@ -46,11 +46,11 @@ int epggrab_channel_match ( epggrab_channel_t *ec, channel_t *ch ) /* Destroy */ void epggrab_channel_link_delete - ( epggrab_channel_link_t *ecl ) + ( epggrab_channel_link_t *ecl, int delconf ) { LIST_REMOVE(ecl, ecl_chn_link); LIST_REMOVE(ecl, ecl_epg_link); - if (ecl->ecl_epggrab->mod->ch_save) + if (!delconf && ecl->ecl_epggrab->mod->ch_save) ecl->ecl_epggrab->mod->ch_save(ecl->ecl_epggrab->mod, ecl->ecl_epggrab); free(ecl); } @@ -222,6 +222,29 @@ epggrab_channel_t *epggrab_channel_find return ec; } +void epggrab_channel_destroy + ( epggrab_channel_tree_t *tree, epggrab_channel_t *ec, int delconf ) +{ + epggrab_channel_link_t *ecl; + + if (!ec) return; + + /* Already linked */ + while ((ecl = LIST_FIRST(&ec->channels)) != NULL) + epggrab_channel_link_delete(ecl, delconf); + RB_REMOVE(tree, ec, link); + free(ec->id); + free(ec); +} + +void epggrab_channel_flush + ( epggrab_channel_tree_t *tree, int delconf ) +{ + epggrab_channel_t *ec; + while ((ec = RB_FIRST(tree)) != NULL) + epggrab_channel_destroy(tree, ec, delconf); +} + /* ************************************************************************** * Global routines * *************************************************************************/ diff --git a/src/epggrab/module.c b/src/epggrab/module.c index 188e1079..923ceb72 100644 --- a/src/epggrab/module.c +++ b/src/epggrab/module.c @@ -182,7 +182,7 @@ void epggrab_module_ch_rem ( void *m, channel_t *ch ) { epggrab_channel_link_t *ecl; while ((ecl = LIST_FIRST(&ch->ch_epggrab))) - epggrab_channel_link_delete(ecl); + epggrab_channel_link_delete(ecl, 1); } void epggrab_module_ch_mod ( void *mod, channel_t *ch ) diff --git a/src/epggrab/module/opentv.c b/src/epggrab/module/opentv.c index 888e622a..80b59625 100644 --- a/src/epggrab/module/opentv.c +++ b/src/epggrab/module/opentv.c @@ -468,7 +468,7 @@ opentv_desc_channels tvhtrace(mt->mt_name, " ec = %p, ecl = %p", ec, ecl); if (ecl && ecl->ecl_channel != ch) { - epggrab_channel_link_delete(ecl); + epggrab_channel_link_delete(ecl, 1); ecl = NULL; } @@ -900,6 +900,8 @@ void opentv_init ( void ) { htsmsg_t *m; + RB_INIT(&_opentv_channels); + /* Load dictionaries */ if ((m = hts_settings_load("epggrab/opentv/dict"))) _opentv_dict_load(m); @@ -920,7 +922,8 @@ void opentv_done ( void ) { opentv_dict_t *dict; opentv_genre_t *genre; - + + epggrab_channel_flush(&_opentv_channels, 0); while ((dict = RB_FIRST(&_opentv_dicts)) != NULL) { RB_REMOVE(&_opentv_dicts, dict, h_link); huffman_tree_destroy(dict->codes); diff --git a/src/epggrab/module/pyepg.c b/src/epggrab/module/pyepg.c index d3b1e876..0aeb3902 100644 --- a/src/epggrab/module/pyepg.c +++ b/src/epggrab/module/pyepg.c @@ -422,6 +422,8 @@ void pyepg_init ( void ) { char buf[256]; + RB_INIT(&_pyepg_channels); + /* Internal module */ if (find_exec("pyepg", buf, sizeof(buf)-1)) epggrab_module_int_create(NULL, "pyepg-internal", "PyEPG", 4, buf, @@ -434,6 +436,11 @@ void pyepg_init ( void ) &_pyepg_channels); } +void pyepg_done ( void ) +{ + epggrab_channel_flush(&_pyepg_channels, 0); +} + void pyepg_load ( void ) { epggrab_module_channels_load(epggrab_module_find_by_id("pyepg")); diff --git a/src/epggrab/module/xmltv.c b/src/epggrab/module/xmltv.c index 085c0b99..d2cbe716 100755 --- a/src/epggrab/module/xmltv.c +++ b/src/epggrab/module/xmltv.c @@ -749,6 +749,8 @@ static void _xmltv_load_grabbers ( void ) void xmltv_init ( void ) { + RB_INIT(&_xmltv_channels); + /* External module */ _xmltv_module = (epggrab_module_t*) epggrab_module_ext_create(NULL, "xmltv", "XMLTV", 3, "xmltv", @@ -759,6 +761,11 @@ void xmltv_init ( void ) _xmltv_load_grabbers(); } +void xmltv_done ( void ) +{ + epggrab_channel_flush(&_xmltv_channels, 0); +} + void xmltv_load ( void ) { epggrab_module_channels_load(epggrab_module_find_by_id("xmltv")); diff --git a/src/epggrab/private.h b/src/epggrab/private.h index 36adf650..297278af 100644 --- a/src/epggrab/private.h +++ b/src/epggrab/private.h @@ -54,6 +54,11 @@ epggrab_channel_t *epggrab_channel_find ( epggrab_channel_tree_t *chs, const char *id, int create, int *save, epggrab_module_t *owner ); +void epggrab_channel_destroy + ( epggrab_channel_tree_t *tree, epggrab_channel_t *ec, int delconf ); +void epggrab_channel_flush + ( epggrab_channel_tree_t *tree, int delconf ); + void epggrab_channel_done(void); /* ************************************************************************** @@ -185,10 +190,12 @@ void opentv_load ( void ); /* PyEPG module */ void pyepg_init ( void ); +void pyepg_done ( void ); void pyepg_load ( void ); /* XMLTV module */ void xmltv_init ( void ); +void xmltv_done ( void ); void xmltv_load ( void ); #endif /* __EPGGRAB_PRIVATE_H__ */