From: Jaroslav Kysela Date: Wed, 6 Dec 2017 10:11:59 +0000 (+0100) Subject: idnode: add light notify functions, big get_title() cleanups X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=0f18b89dfbf7974ee7184149fce6dad67666c554;p=thirdparty%2Ftvheadend.git idnode: add light notify functions, big get_title() cleanups --- diff --git a/src/access.c b/src/access.c index b29550be6..2c4d0a0f8 100644 --- a/src/access.c +++ b/src/access.c @@ -1213,23 +1213,25 @@ access_entry_class_movedown(idnode_t *self) } } -static const char * -access_entry_class_get_title (idnode_t *self, const char *lang) +static void +access_entry_class_get_title + (idnode_t *self, const char *lang, char *buf, size_t dstsize) { access_entry_t *ae = (access_entry_t *)self; - const char *s = ae->ae_username; if (ae->ae_comment && ae->ae_comment[0] != '\0') { if (ae->ae_username && ae->ae_username[0]) { - snprintf(prop_sbuf, PROP_SBUF_LEN, "%s (%s)", ae->ae_username, ae->ae_comment); - s = prop_sbuf; + snprintf(buf, dstsize, "%s (%s)", ae->ae_username, ae->ae_comment); + return; } else { - s = ae->ae_comment; + snprintf(buf, dstsize, "%s", ae->ae_comment); + return; } } - if (s == NULL || *s == '\0') - s = ""; - return s; + if (ae->ae_username && ae->ae_username[0] != '\0') + snprintf(buf, dstsize, "%s", ae->ae_username); + else + buf[0] = '\0'; } static int @@ -1966,14 +1968,17 @@ passwd_entry_class_delete(idnode_t *self) passwd_entry_destroy(pw, 1); } -static const char * -passwd_entry_class_get_title (idnode_t *self, const char *lang) +static void +passwd_entry_class_get_title + (idnode_t *self, const char *lang, char *dst, size_t dstsize) { passwd_entry_t *pw = (passwd_entry_t *)self; - if (pw->pw_comment && pw->pw_comment[0] != '\0') - return pw->pw_comment; - return pw->pw_username ?: ""; + if (pw->pw_comment && pw->pw_comment[0] != '\0') { + snprintf(dst, dstsize, "%s", pw->pw_comment); + } else { + snprintf(dst, dstsize, "%s", pw->pw_username ?: ""); + } } static int @@ -2136,14 +2141,16 @@ ipblock_entry_class_save(idnode_t *self, char *filename, size_t fsize) return c; } -static const char * -ipblock_entry_class_get_title (idnode_t *self, const char *lang) +static void +ipblock_entry_class_get_title + (idnode_t *self, const char *lang, char *dst, size_t dstsize) { ipblock_entry_t *ib = (ipblock_entry_t *)self; if (ib->ib_comment && ib->ib_comment[0] != '\0') - return ib->ib_comment; - return N_("IP blocking"); + snprintf(dst, dstsize, "%s", ib->ib_comment); + else + snprintf(dst, dstsize, "%s", tvh_gettext_lang(lang, N_("IP blocking"))); } static void diff --git a/src/api/api_caclient.c b/src/api/api_caclient.c index 49b1470da..cf14335a9 100644 --- a/src/api/api_caclient.c +++ b/src/api/api_caclient.c @@ -32,14 +32,14 @@ api_caclient_list { caclient_t *cac; htsmsg_t *l, *e; - char ubuf[UUID_HEX_SIZE]; + char ubuf[UUID_HEX_SIZE], buf[384]; l = htsmsg_create_list(); pthread_mutex_lock(&global_lock); TAILQ_FOREACH(cac, &caclients, cac_link) { e = htsmsg_create_map(); htsmsg_add_str(e, "uuid", idnode_uuid_as_str(&cac->cac_id, ubuf)); - htsmsg_add_str(e, "title", idnode_get_title(&cac->cac_id, perm->aa_lang_ui)); + htsmsg_add_str(e, "title", idnode_get_title(&cac->cac_id, perm->aa_lang_ui, buf, sizeof(buf))); htsmsg_add_str(e, "status", caclient_get_status(cac)); htsmsg_add_msg(l, NULL, e); } diff --git a/src/api/api_epggrab.c b/src/api/api_epggrab.c index f53f6f00e..5e8d064c1 100644 --- a/src/api/api_epggrab.c +++ b/src/api/api_epggrab.c @@ -38,13 +38,13 @@ api_epggrab_module_list { htsmsg_t *l = htsmsg_create_list(), *m; epggrab_module_t *mod; - char ubuf[UUID_HEX_SIZE]; + char ubuf[UUID_HEX_SIZE], buf[384]; pthread_mutex_lock(&global_lock); LIST_FOREACH(mod, &epggrab_modules, link) { m = htsmsg_create_map(); htsmsg_add_str(m, "uuid", idnode_uuid_as_str(&mod->idnode, ubuf)); htsmsg_add_str(m, "status", epggrab_module_get_status(mod)); - htsmsg_add_str(m, "title", idnode_get_title(&mod->idnode, perm->aa_lang_ui)); + htsmsg_add_str(m, "title", idnode_get_title(&mod->idnode, perm->aa_lang_ui, buf, sizeof(buf))); htsmsg_add_msg(l, NULL, m); } pthread_mutex_unlock(&global_lock); diff --git a/src/api/api_idnode.c b/src/api/api_idnode.c index fe7b42623..517315a2f 100644 --- a/src/api/api_idnode.c +++ b/src/api/api_idnode.c @@ -177,7 +177,7 @@ api_idnode_load_by_class0 idnode_set_t *is; idnode_t *in; htsmsg_t *l, *e; - char ubuf[UUID_HEX_SIZE]; + char ubuf[UUID_HEX_SIZE], buf[384]; // TODO: this only works if pass as integer _enum = htsmsg_get_bool_or_default(args, "enum", 0); @@ -197,7 +197,7 @@ api_idnode_load_by_class0 /* Name/UUID only */ if (_enum) { e = htsmsg_create_key_val(idnode_uuid_as_str(in, ubuf), - idnode_get_title(in, perm->aa_lang_ui)); + idnode_get_title(in, perm->aa_lang_ui, buf, sizeof(buf))); /* Full record */ } else { diff --git a/src/bouquet.c b/src/bouquet.c index 53d397c18..d88033838 100644 --- a/src/bouquet.c +++ b/src/bouquet.c @@ -681,14 +681,16 @@ bouquet_class_delete(idnode_t *self) bouquet_delete((bouquet_t *)self); } -static const char * -bouquet_class_get_title (idnode_t *self, const char *lang) +static void +bouquet_class_get_title + (idnode_t *self, const char *lang, char *dst, size_t dstsize) { bouquet_t *bq = (bouquet_t *)self; if (bq->bq_comment && bq->bq_comment[0] != '\0') - return bq->bq_comment; - return bq->bq_name ?: ""; + snprintf(dst, dstsize, "%s", bq->bq_comment); + else + snprintf(dst, dstsize, "%s", bq->bq_name ?: ""); } /* exported for others */ diff --git a/src/channels.c b/src/channels.c index 41115ee6c..085e42667 100644 --- a/src/channels.c +++ b/src/channels.c @@ -217,10 +217,13 @@ channel_class_get_icon ( void *obj ) return &prop_ptr; } -static const char * -channel_class_get_title ( idnode_t *self, const char *lang ) +static void +channel_class_get_title + ( idnode_t *self, const char *lang, char *dst, size_t dstsize ) { - return channel_get_name((channel_t*)self, tvh_gettext_lang(lang, channel_blank_name)); + const char *s = channel_get_name((channel_t*)self, + tvh_gettext_lang(lang, channel_blank_name)); + snprintf(dst, dstsize, "%s", s); } /* exported for others */ @@ -1500,11 +1503,12 @@ channel_tag_class_delete(idnode_t *self) channel_tag_destroy((channel_tag_t *)self, 1); } -static const char * -channel_tag_class_get_title (idnode_t *self, const char *lang) +static void +channel_tag_class_get_title + (idnode_t *self, const char *lang, char *dst, size_t dstsize) { channel_tag_t *ct = (channel_tag_t *)self; - return ct->ct_name ?: ""; + snprintf(dst, dstsize, "%s", ct->ct_name ?: ""); } static void diff --git a/src/descrambler/caclient.c b/src/descrambler/caclient.c index edbc371e9..e5c9b775c 100644 --- a/src/descrambler/caclient.c +++ b/src/descrambler/caclient.c @@ -188,15 +188,17 @@ caclient_class_save ( idnode_t *in, char *filename, size_t fsize ) return c; } -static const char * -caclient_class_get_title ( idnode_t *in, const char *lang ) +static void +caclient_class_get_title + ( idnode_t *in, const char *lang, char *dst, size_t dstsize ) { caclient_t *cac = (caclient_t *)in; - if (cac->cac_name && cac->cac_name[0]) - return cac->cac_name; - snprintf(prop_sbuf, PROP_SBUF_LEN, - tvh_gettext_lang(lang, N_("CA client %i")), cac->cac_index); - return prop_sbuf; + if (cac->cac_name && cac->cac_name[0]) { + snprintf(dst, dstsize, "%s", cac->cac_name); + } else { + snprintf(dst, dstsize, + tvh_gettext_lang(lang, N_("CA client %i")), cac->cac_index); + } } static void @@ -297,7 +299,7 @@ const idclass_t caclient_class = .name = N_("Client name"), .desc = N_("Name of the client."), .off = offsetof(caclient_t, cac_name), - .notify = idnode_notify_title_changed, + .notify = idnode_notify_title_changed_lang, }, { .type = PT_STR, diff --git a/src/descrambler/capmt.c b/src/descrambler/capmt.c index 6ba631400..e3eac35b7 100644 --- a/src/descrambler/capmt.c +++ b/src/descrambler/capmt.c @@ -260,6 +260,8 @@ typedef struct capmt { pthread_t capmt_tid; + char capmt_name[128]; + /* from capmt configuration */ char *capmt_sockfile; int capmt_port; @@ -308,7 +310,8 @@ static void capmt_send_client_info(capmt_t *capmt); static inline const char * capmt_name(capmt_t *capmt) { - return idnode_get_title(&capmt->cac_id, NULL); + return idnode_get_title(&capmt->cac_id, NULL, + capmt->capmt_name, sizeof(capmt->capmt_name)); } static inline int @@ -1922,7 +1925,7 @@ capmt_thread(void *aux) d = 60; } - tvhinfo(LS_CAPMT, "%s: Automatic reconnection attempt in in %d seconds", idnode_get_title(&capmt->cac_id, NULL), d); + tvhinfo(LS_CAPMT, "%s: Automatic reconnection attempt in in %d seconds", capmt_name(capmt), d); mono = mclk() + sec2mono(d); do { diff --git a/src/descrambler/constcw.c b/src/descrambler/constcw.c index cd3aefefd..7f3c6004c 100644 --- a/src/descrambler/constcw.c +++ b/src/descrambler/constcw.c @@ -36,6 +36,8 @@ typedef struct constcw_service { typedef struct constcw { caclient_t; + char ccw_name[128]; + /* From configuration */ uint16_t ccw_caid; /* CA ID */ uint32_t ccw_providerid; /* CA provider ID */ @@ -52,7 +54,8 @@ typedef struct constcw { static const char * constcw_name(constcw_t *ccw) { - return idnode_get_title(&ccw->cac_id, NULL); + return idnode_get_title(&ccw->cac_id, NULL, + ccw->ccw_name, sizeof(ccw->ccw_name)); } /** diff --git a/src/dvr/dvr_autorec.c b/src/dvr/dvr_autorec.c index 0abf9d301..ae04f873b 100644 --- a/src/dvr/dvr_autorec.c +++ b/src/dvr/dvr_autorec.c @@ -506,8 +506,9 @@ dvr_autorec_entry_class_perm(idnode_t *self, access_t *a, htsmsg_t *msg_to_write return 0; } -static const char * -dvr_autorec_entry_class_get_title (idnode_t *self, const char *lang) +static void +dvr_autorec_entry_class_get_title + (idnode_t *self, const char *lang, char *dst, size_t dstsize) { dvr_autorec_entry_t *dae = (dvr_autorec_entry_t *)self; const char *s = ""; @@ -515,7 +516,7 @@ dvr_autorec_entry_class_get_title (idnode_t *self, const char *lang) s = dae->dae_name; else if (dae->dae_comment && dae->dae_comment[0] != '\0') s = dae->dae_comment; - return s; + snprintf(dst, dstsize, "%s", s); } static int diff --git a/src/dvr/dvr_config.c b/src/dvr/dvr_config.c index bcb09cfc7..0a25b6c8d 100644 --- a/src/dvr/dvr_config.c +++ b/src/dvr/dvr_config.c @@ -682,13 +682,16 @@ dvr_config_class_profile_rend(void *o, const char *lang) return NULL; } -static const char * -dvr_config_class_get_title (idnode_t *self, const char *lang) +static void +dvr_config_class_get_title + (idnode_t *self, const char *lang, char *dst, size_t dstsize) { dvr_config_t *cfg = (dvr_config_t *)self; - if (!dvr_config_is_default(cfg)) - return cfg->dvr_config_name; - return N_("(Default profile)"); + if (!dvr_config_is_default(cfg)) { + snprintf(dst, dstsize, "%s", cfg->dvr_config_name); + } else { + snprintf(dst, dstsize, "%s", tvh_gettext_lang(lang, N_("(Default profile)"))); + } } static int diff --git a/src/dvr/dvr_db.c b/src/dvr/dvr_db.c index 6535a24be..f548a4ca7 100644 --- a/src/dvr/dvr_db.c +++ b/src/dvr/dvr_db.c @@ -2634,8 +2634,9 @@ dvr_entry_class_perm(idnode_t *self, access_t *a, htsmsg_t *msg_to_write) return 0; } -static const char * -dvr_entry_class_get_title (idnode_t *self, const char *lang) +static void +dvr_entry_class_get_title + (idnode_t *self, const char *lang, char *dst, size_t dstsize) { dvr_entry_t *de = (dvr_entry_t *)self; const char *s; @@ -2648,7 +2649,7 @@ dvr_entry_class_get_title (idnode_t *self, const char *lang) s = lang_str_get(de->de_desc, NULL); } } - return s; + snprintf(dst, dstsize, "%s", s); } static int diff --git a/src/dvr/dvr_timerec.c b/src/dvr/dvr_timerec.c index ae1ca6836..be5ecd74d 100644 --- a/src/dvr/dvr_timerec.c +++ b/src/dvr/dvr_timerec.c @@ -303,8 +303,9 @@ dvr_timerec_entry_class_perm(idnode_t *self, access_t *a, htsmsg_t *msg_to_write return 0; } -static const char * -dvr_timerec_entry_class_get_title (idnode_t *self, const char *lang) +static void +dvr_timerec_entry_class_get_title + (idnode_t *self, const char *lang, char *dst, size_t dstsize) { dvr_timerec_entry_t *dte = (dvr_timerec_entry_t *)self; const char *s = ""; @@ -312,7 +313,7 @@ dvr_timerec_entry_class_get_title (idnode_t *self, const char *lang) s = dte->dte_name; else if (dte->dte_comment && dte->dte_comment[0] != '\0') s = dte->dte_comment; - return s; + snprintf(dst, dstsize, "%s", s); } static int diff --git a/src/epggrab/channel.c b/src/epggrab/channel.c index 9b82217fe..f9e98b52c 100644 --- a/src/epggrab/channel.c +++ b/src/epggrab/channel.c @@ -539,14 +539,14 @@ epggrab_channel_is_ota ( epggrab_channel_t *ec ) * Class */ -static const char * -epggrab_channel_class_get_title(idnode_t *self, const char *lang) +static void +epggrab_channel_class_get_title + (idnode_t *self, const char *lang, char *dst, size_t dstsize) { epggrab_channel_t *ec = (epggrab_channel_t*)self; - snprintf(prop_sbuf, PROP_SBUF_LEN, "%s: %s (%s)", + snprintf(dst, dstsize, "%s: %s (%s)", ec->name ?: ec->id, ec->id, ec->mod->name); - return prop_sbuf; } static htsmsg_t * diff --git a/src/epggrab/module.c b/src/epggrab/module.c index fc9fa1e3e..ca1b238f2 100644 --- a/src/epggrab/module.c +++ b/src/epggrab/module.c @@ -73,13 +73,13 @@ epggrab_module_get_status(epggrab_module_t *mod) * Class */ -static const char *epggrab_mod_class_title(idnode_t *self, const char *lang) +static void epggrab_mod_class_title + (idnode_t *self, const char *lang, char *dst, size_t dstsize) { epggrab_module_t *mod = (epggrab_module_t *)self; const char *s1 = tvh_gettext_lang(lang, epggrab_module_type(mod)); const char *s2 = tvh_str_default(mod->name, mod->id); - snprintf(prop_sbuf, PROP_SBUF_LEN, "%s: %s", s1, s2); - return prop_sbuf; + snprintf(dst, dstsize, "%s: %s", s1, s2); } static void diff --git a/src/esfilter.c b/src/esfilter.c index 11949610b..a6bef849b 100644 --- a/src/esfilter.c +++ b/src/esfilter.c @@ -215,13 +215,6 @@ esfilter_class_save(idnode_t *self, char *filename, size_t fsize) return c; } -static const char * -esfilter_class_get_title(idnode_t *self, const char *lang) -{ - esfilter_t *esf = (esfilter_t *)self; - return idnode_uuid_as_str(&esf->esf_id, prop_sbuf); -} - static void esfilter_class_delete(idnode_t *self) { @@ -594,7 +587,6 @@ const idclass_t esfilter_class = { .ic_event = "esfilter", .ic_perm_def = ACCESS_ADMIN, .ic_save = esfilter_class_save, - .ic_get_title = esfilter_class_get_title, .ic_delete = esfilter_class_delete, .ic_moveup = esfilter_class_moveup, .ic_movedown = esfilter_class_movedown, diff --git a/src/idnode.c b/src/idnode.c index 638000971..1701f45ae 100644 --- a/src/idnode.c +++ b/src/idnode.c @@ -41,15 +41,20 @@ typedef struct idclass_link RB_ENTRY(idclass_link) link; } idclass_link_t; +pthread_mutex_t idnode_mutex = PTHREAD_MUTEX_INITIALIZER; static idnodes_rb_t idnodes; static RB_HEAD(,idclass_link) idclasses; static RB_HEAD(,idclass_link) idrootclasses; static TAILQ_HEAD(,idnode_save) idnodes_save; -tvh_cond_t save_cond; -pthread_t save_tid; -static int save_running; -static mtimer_t save_timer; +static tvh_cond_t save_cond; +static pthread_t save_tid; +static int save_running; +static mtimer_t save_timer; + +static pthread_mutex_t idnode_lnotify_mutex = PTHREAD_MUTEX_INITIALIZER; +static tvh_uuid_set_t idnode_lnotify_set; +static tvh_uuid_set_t idnode_lnotify_title_set; SKEL_DECLARE(idclasses_skel, idclass_link_t); @@ -101,6 +106,8 @@ idnode_insert(idnode_t *in, const char *uuid, const idclass_t *class, int flags) lock_assert(&global_lock); + idnode_lock(); + in->in_class = class; do { @@ -145,6 +152,8 @@ idnode_insert(idnode_t *in, const char *uuid, const idclass_t *class, int flags) c = RB_INSERT_SORTED(in->in_domain, in, in_domain_link, in_cmp); assert(c == NULL); + idnode_unlock(); + /* Fire event */ idnode_notify(in, "create"); @@ -160,8 +169,10 @@ idnode_unlink(idnode_t *in) char ubuf[UUID_HEX_SIZE]; lock_assert(&global_lock); + idnode_lock(); RB_REMOVE(&idnodes, in, in_link); RB_REMOVE(in->in_domain, in, in_domain_link); + idnode_unlock(); tvhtrace(LS_IDNODE, "unlink node %s", idnode_uuid_as_str(in, ubuf)); idnode_notify(in, "delete"); assert(in->in_save == NULL || in->in_save == SAVEPTR_OUTOFSERVICE); @@ -232,15 +243,19 @@ idnode_uuid_as_str(const idnode_t *in, char *uuid) * */ const char * -idnode_get_title(idnode_t *in, const char *lang) +idnode_get_title(idnode_t *in, const char *lang, char *dst, size_t dstsize) { static char ubuf[UUID_HEX_SIZE]; const idclass_t *ic = in->in_class; for(; ic != NULL; ic = ic->ic_super) { - if(ic->ic_get_title != NULL) - return ic->ic_get_title(in, lang); + if(ic->ic_get_title != NULL) { + ic->ic_get_title(in, lang, dst, dstsize); + return dst; + } } - return idnode_uuid_as_str(in, ubuf); + strncpy(dst, idnode_uuid_as_str(in, ubuf), dstsize); + dst[dstsize-1] = 0; + return dst; } @@ -701,9 +716,11 @@ idnode_cmp_title { idnode_t *ina = *(idnode_t**)a; idnode_t *inb = *(idnode_t**)b; - const char *sa = idnode_get_title(ina, (const char *)lang); - const char *sb = idnode_get_title(inb, (const char *)lang); - return strcmp(sa ?: "", sb ?: ""); + char bufa[384]; + char bufb[384]; + idnode_get_title(ina, (const char *)lang, bufa, sizeof(bufa)); + idnode_get_title(inb, (const char *)lang, bufb, sizeof(bufb)); + return strcmp(bufa, bufb); } #define safecmp(a, b) ((a) > (b) ? 1 : ((a) < (b) ? -1 : 0)) @@ -1516,7 +1533,7 @@ idnode_serialize0(idnode_t *self, htsmsg_t *list, int optmask, const char *lang) { const idclass_t *idc = self->in_class; const char *uuid, *s; - char ubuf[UUID_HEX_SIZE]; + char ubuf[UUID_HEX_SIZE], buf[384]; htsmsg_t *m = htsmsg_create_map(); if (!idc->ic_snode) { @@ -1524,7 +1541,7 @@ idnode_serialize0(idnode_t *self, htsmsg_t *list, int optmask, const char *lang) htsmsg_add_str(m, "uuid", uuid); htsmsg_add_str(m, "id", uuid); } - htsmsg_add_str(m, "text", idnode_get_title(self, lang) ?: ""); + htsmsg_add_str(m, "text", idnode_get_title(self, lang, buf, sizeof(buf)) ?: ""); if ((s = idclass_get_caption(idc, lang))) htsmsg_add_str(m, "caption", s); if ((s = idclass_get_class(idc))) @@ -1759,9 +1776,10 @@ idnode_list_get_csv1 char *str; idnode_list_mapping_t *ilm; htsmsg_t *l = htsmsg_create_list(); + char buf[384]; LIST_FOREACH(ilm, in1_list, ilm_in1_link) - htsmsg_add_str(l, NULL, idnode_get_title(ilm->ilm_in2, lang)); + htsmsg_add_str(l, NULL, idnode_get_title(ilm->ilm_in2, lang, buf, sizeof(buf))); str = htsmsg_list_2_csv(l, ',', 1); htsmsg_destroy(l); @@ -1775,9 +1793,10 @@ idnode_list_get_csv2 char *str; idnode_list_mapping_t *ilm; htsmsg_t *l = htsmsg_create_list(); + char buf[384]; LIST_FOREACH(ilm, in2_list, ilm_in2_link) - htsmsg_add_str(l, NULL, idnode_get_title(ilm->ilm_in1, lang)); + htsmsg_add_str(l, NULL, idnode_get_title(ilm->ilm_in1, lang, buf, sizeof(buf))); str = htsmsg_list_2_csv(l, ',', 1); htsmsg_destroy(l); @@ -1898,16 +1917,21 @@ idnode_notify_changed (void *in) } void -idnode_notify_title_changed (void *in, const char *lang) +idnode_notify_title_changed (void *in) { char ubuf[UUID_HEX_SIZE]; htsmsg_t *m = htsmsg_create_map(); htsmsg_add_str(m, "uuid", idnode_uuid_as_str(in, ubuf)); - htsmsg_add_str(m, "text", idnode_get_title(in, lang)); - notify_by_msg("title", m, 0); + notify_by_msg("title", m, NOTIFY_REWRITE_TITLE); idnode_notify_changed(in); } +void +idnode_notify_title_changed_lang (void *in, const char *lang) +{ + return idnode_notify_title_changed(in); +} + /* ************************************************************************** * Save thread * *************************************************************************/ @@ -1916,32 +1940,69 @@ static void * save_thread ( void *aux ) { idnode_save_t *ise; + idnode_t *in; htsmsg_t *m; + uint32_t u32; + tvh_uuid_t *uuid; char filename[PATH_MAX]; + tvh_uuid_set_t set, tset; + + uuid_set_init(&set, 10); + uuid_set_init(&tset, 10); tvhthread_renice(15); pthread_mutex_lock(&global_lock); while (atomic_get(&save_running)) { - if ((ise = TAILQ_FIRST(&idnodes_save)) == NULL || - (ise->ise_reqtime + IDNODE_SAVE_DELAY > mclk())) { + if (((ise = TAILQ_FIRST(&idnodes_save)) == NULL || + (ise->ise_reqtime + IDNODE_SAVE_DELAY > mclk())) && + uuid_set_empty(&idnode_lnotify_set) && + uuid_set_empty(&idnode_lnotify_title_set)) { if (ise) mtimer_arm_abs(&save_timer, idnode_save_trigger_thread_cb, NULL, ise->ise_reqtime + IDNODE_SAVE_DELAY); tvh_cond_wait(&save_cond, &global_lock); continue; } - m = idnode_savefn(ise->ise_node, filename, sizeof(filename)); - ise->ise_node->in_save = NULL; - TAILQ_REMOVE(&idnodes_save, ise, ise_link); - pthread_mutex_unlock(&global_lock); - free(ise); - if (m) { - hts_settings_save(m, "%s", filename); - htsmsg_destroy(m); + if (ise) { + m = idnode_savefn(ise->ise_node, filename, sizeof(filename)); + ise->ise_node->in_save = NULL; + TAILQ_REMOVE(&idnodes_save, ise, ise_link); + pthread_mutex_unlock(&global_lock); + free(ise); + if (m) { + hts_settings_save(m, "%s", filename); + htsmsg_destroy(m); + } + pthread_mutex_lock(&global_lock); + } + pthread_mutex_lock(&idnode_lnotify_mutex); + if (!uuid_set_empty(&idnode_lnotify_set)) { + set = idnode_lnotify_set; + uuid_set_init(&idnode_lnotify_set, 10); + } + if (!uuid_set_empty(&idnode_lnotify_title_set)) { + tset = idnode_lnotify_title_set; + uuid_set_init(&idnode_lnotify_title_set, 10); + } + pthread_mutex_unlock(&idnode_lnotify_mutex); + if (!uuid_set_empty(&set)) { + UUID_SET_FOREACH(uuid, &set, u32) { + in = idnode_find0(uuid, NULL, NULL); + if (in) + idnode_notify_changed(in); + } + uuid_set_free(&set); + } + if (!uuid_set_empty(&tset)) { + UUID_SET_FOREACH(uuid, &tset, u32) { + in = idnode_find0(uuid, NULL, NULL); + if (in) + idnode_notify_title_changed(in); + } + uuid_set_free(&tset); } - pthread_mutex_lock(&global_lock); } mtimer_disarm(&save_timer); @@ -1963,6 +2024,26 @@ save_thread ( void *aux ) return NULL; } +/* ************************************************************************** + * Light update - outside global lock + * *************************************************************************/ + +void idnode_lnotify_changed( void *in ) +{ + pthread_mutex_lock(&idnode_lnotify_mutex); + uuid_set_add(&idnode_lnotify_set, &((idnode_t *)in)->in_uuid); + pthread_mutex_unlock(&idnode_lnotify_mutex); + tvh_cond_signal(&save_cond, 0); +} + +void idnode_lnotify_title_changed( void *in ) +{ + pthread_mutex_lock(&idnode_lnotify_mutex); + uuid_set_add(&idnode_lnotify_title_set, &((idnode_t *)in)->in_uuid); + pthread_mutex_unlock(&idnode_lnotify_mutex); + tvh_cond_signal(&save_cond, 0); +} + /* ************************************************************************** * Initialization * *************************************************************************/ @@ -1975,6 +2056,8 @@ idnode_boot(void) RB_INIT(&idrootclasses); TAILQ_INIT(&idnodes_save); tvh_cond_init(&save_cond); + uuid_set_init(&idnode_lnotify_set, 10); + uuid_set_init(&idnode_lnotify_title_set, 10); } void @@ -2003,6 +2086,9 @@ idnode_done(void) free(il); } SKEL_FREE(idclasses_skel); + + uuid_set_free(&idnode_lnotify_set); + uuid_set_free(&idnode_lnotify_title_set); } /****************************************************************************** diff --git a/src/idnode.h b/src/idnode.h index 8ffafe962..506518852 100644 --- a/src/idnode.h +++ b/src/idnode.h @@ -79,7 +79,7 @@ struct idclass { /* Callbacks */ idnode_set_t *(*ic_get_childs) (idnode_t *self); - const char *(*ic_get_title) (idnode_t *self, const char *lang); + void (*ic_get_title) (idnode_t *self, const char *lang, char *dst, size_t dstsize); void (*ic_changed) (idnode_t *self); htsmsg_t *(*ic_save) (idnode_t *self, char *filename, size_t fsize); void (*ic_load) (idnode_t *self, htsmsg_t *conf); @@ -194,11 +194,17 @@ typedef LIST_HEAD(,idnode_filter_ele) idnode_filter_t; extern idnode_t tvhlog_conf; extern const idclass_t tvhlog_conf_class; +extern pthread_mutex_t idnode_mutex; void idnode_boot(void); void idnode_init(void); void idnode_done(void); +static inline void idnode_lock(void) + { pthread_mutex_lock(&idnode_mutex); } +static inline void idnode_unlock(void) + { pthread_mutex_unlock(&idnode_mutex); } + #define IDNODE_SHORT_UUID (1<<0) int idnode_insert(idnode_t *in, const char *uuid, const idclass_t *idc, int flags); @@ -207,7 +213,7 @@ void idnode_unlink(idnode_t *in); uint32_t idnode_get_short_uuid (const idnode_t *in); const char *idnode_uuid_as_str (const idnode_t *in, char *buf); idnode_set_t *idnode_get_childs (idnode_t *in); -const char *idnode_get_title (idnode_t *in, const char *lang); +const char *idnode_get_title (idnode_t *in, const char *lang, char *dst, size_t dstsize); int idnode_is_leaf (idnode_t *in); int idnode_is_instance (idnode_t *in, const idclass_t *idc); void idnode_delete (idnode_t *in); @@ -223,7 +229,11 @@ idnode_set_t *idnode_find_all(const idclass_t *idc, const idnodes_rb_t *nodes); void idnode_notify (idnode_t *in, const char *action); void idnode_notify_changed (void *in); -void idnode_notify_title_changed (void *in, const char *lang); +void idnode_notify_title_changed (void *in); +void idnode_notify_title_changed_lang (void *in, const char *lang); + +void idnode_lnotify_changed (void *in); +void idnode_lnotify_title_changed (void *in); void idclass_register ( const idclass_t *idc ); const idclass_t *idclass_find ( const char *name ); diff --git a/src/input/mpegts/iptv/iptv.c b/src/input/mpegts/iptv/iptv.c index bf8b4d62f..10227721e 100644 --- a/src/input/mpegts/iptv/iptv.c +++ b/src/input/mpegts/iptv/iptv.c @@ -84,10 +84,11 @@ iptv_handler_find ( const char *scheme ) * IPTV input * *************************************************************************/ -static const char * -iptv_input_class_get_title ( idnode_t *self, const char *lang ) +static void +iptv_input_class_get_title + ( idnode_t *self, const char *lang, char *dst, size_t dstsize ) { - return tvh_gettext_lang(lang, N_("IPTV")); + snprintf(dst, dstsize, "%s", tvh_gettext_lang(lang, N_("IPTV"))); } extern const idclass_t mpegts_input_class; @@ -516,6 +517,7 @@ iptv_input_recv_packets ( iptv_mux_t *im, ssize_t len ) iptv_network_t *in = (iptv_network_t*)im->mm_network; mpegts_mux_instance_t *mmi; mpegts_pcr_t pcr; + char buf[384]; int64_t s64; pcr.pcr_first = PTS_UNSET; @@ -528,7 +530,7 @@ iptv_input_recv_packets ( iptv_mux_t *im, ssize_t len ) in->in_bps > in->in_max_bandwidth * 1024) { if (!in->in_bw_limited) { tvhinfo(LS_IPTV, "%s bandwidth limited exceeded", - idnode_get_title(&in->mn_id, NULL)); + idnode_get_title(&in->mn_id, NULL, buf, sizeof(buf))); in->in_bw_limited = 1; } } diff --git a/src/input/mpegts/linuxdvb/linuxdvb_adapter.c b/src/input/mpegts/linuxdvb/linuxdvb_adapter.c index 69c4ecd6e..37f57d093 100644 --- a/src/input/mpegts/linuxdvb/linuxdvb_adapter.c +++ b/src/input/mpegts/linuxdvb/linuxdvb_adapter.c @@ -103,11 +103,12 @@ linuxdvb_adapter_class_get_childs ( idnode_t *in ) return is; } -static const char * -linuxdvb_adapter_class_get_title ( idnode_t *in, const char *lang ) +static void +linuxdvb_adapter_class_get_title + ( idnode_t *in, const char *lang, char *dst, size_t dstsize ) { linuxdvb_adapter_t *la = (linuxdvb_adapter_t*)in; - return la->la_name ?: la->la_rootpath; + snprintf(dst, dstsize, "%s", la->la_name ?: la->la_rootpath); } static const void * diff --git a/src/input/mpegts/linuxdvb/linuxdvb_ca.c b/src/input/mpegts/linuxdvb/linuxdvb_ca.c index 238b883d4..418023426 100644 --- a/src/input/mpegts/linuxdvb/linuxdvb_ca.c +++ b/src/input/mpegts/linuxdvb/linuxdvb_ca.c @@ -162,7 +162,7 @@ linuxdvb_ca_class_enabled_notify ( void *p, const char *lang ) #endif } - idnode_notify_title_changed(&lca->lca_id, lang); + idnode_notify_title_changed(&lca->lca_id); } } @@ -175,20 +175,18 @@ linuxdvb_ca_class_high_bitrate_notify ( void *p, const char *lang ) CIPLUS13_DATA_RATE_72_MBPS); } -static const char * -linuxdvb_ca_class_get_title ( idnode_t *in, const char *lang ) +static void +linuxdvb_ca_class_get_title + ( idnode_t *in, const char *lang, char *dst, size_t dstsize ) { linuxdvb_ca_t *lca = (linuxdvb_ca_t *) in; - static char buf[256]; if (!lca->lca_enabled) - snprintf(buf, sizeof(buf), "ca%u: disabled", lca->lca_number); + snprintf(dst, dstsize, "ca%u: disabled", lca->lca_number); else if (lca->lca_state == CA_SLOT_STATE_EMPTY) - snprintf(buf, sizeof(buf), "ca%u: slot empty", lca->lca_number); + snprintf(dst, dstsize, "ca%u: slot empty", lca->lca_number); else - snprintf(buf, sizeof(buf), "ca%u: %s (%s)", lca->lca_number, - lca->lca_cam_menu_string, lca->lca_state_str); - - return buf; + snprintf(dst, dstsize, "ca%u: %s (%s)", lca->lca_number, + lca->lca_cam_menu_string, lca->lca_state_str); } static const void * @@ -529,7 +527,7 @@ linuxdvb_ca_ai_callback(void *arg, uint8_t slot_id, uint16_t session_num, snprintf(lca->lca_cam_menu_string, sizeof(lca->lca_cam_menu_string), "%.*s", menu_string_len, menu_string); - idnode_notify_title_changed(&lca->lca_id, NULL); + idnode_notify_title_changed(&lca->lca_id); return 0; } @@ -804,7 +802,7 @@ linuxdvb_ca_monitor ( void *aux ) if (lca->lca_state != state) { tvhnotice(LS_LINUXDVB, "%s: CAM slot %u status changed to %s", lca->lca_name, csi.num, lca->lca_state_str); - idnode_notify_title_changed(&lca->lca_id, NULL); + idnode_notify_title_changed(&lca->lca_id); lca->lca_state = state; } diff --git a/src/input/mpegts/linuxdvb/linuxdvb_en50494.c b/src/input/mpegts/linuxdvb/linuxdvb_en50494.c index 9c815959e..6a7d26f8d 100644 --- a/src/input/mpegts/linuxdvb/linuxdvb_en50494.c +++ b/src/input/mpegts/linuxdvb/linuxdvb_en50494.c @@ -64,18 +64,20 @@ /* prevention of self raised DiSEqC collisions */ static pthread_mutex_t linuxdvb_en50494_lock; -static const char * -linuxdvb_en50494_class_get_title ( idnode_t *o, const char *lang ) +static void +linuxdvb_en50494_class_get_title + ( idnode_t *o, const char *lang, char *dst, size_t dstsize ) { - static const char *title = N_("Unicable I (EN50494)"); - return tvh_gettext_lang(lang, title); + const char *title = N_("Unicable I (EN50494)"); + snprintf(dst, dstsize, "%s", tvh_gettext_lang(lang, title)); } -static const char * -linuxdvb_en50607_class_get_title ( idnode_t *o, const char *lang ) +static void +linuxdvb_en50607_class_get_title + ( idnode_t *o, const char *lang, char *dst, size_t dstsize ) { - static const char *title = N_("Unicable II (EN50607)"); - return tvh_gettext_lang(lang, title); + const char *title = N_("Unicable II (EN50607)"); + snprintf(dst, dstsize, "%s", tvh_gettext_lang(lang, title)); } static htsmsg_t * diff --git a/src/input/mpegts/linuxdvb/linuxdvb_lnb.c b/src/input/mpegts/linuxdvb/linuxdvb_lnb.c index 754f1bfde..2a976d05e 100644 --- a/src/input/mpegts/linuxdvb/linuxdvb_lnb.c +++ b/src/input/mpegts/linuxdvb/linuxdvb_lnb.c @@ -43,13 +43,12 @@ typedef struct linuxdvb_lnb_conf int lnb_switch; } linuxdvb_lnb_conf_t; -static const char * -linuxdvb_lnb_class_get_title ( idnode_t *o, const char *lang ) +static void +linuxdvb_lnb_class_get_title + ( idnode_t *o, const char *lang, char *dst, size_t dstsize ) { - static char buf[256]; linuxdvb_diseqc_t *ld = (linuxdvb_diseqc_t*)o; - snprintf(buf, sizeof(buf), "LNB: %s", ld->ld_type); - return buf; + snprintf(dst, dstsize, tvh_gettext_lang(lang, N_("LNB: %s")), ld->ld_type); } extern const idclass_t linuxdvb_diseqc_class; diff --git a/src/input/mpegts/linuxdvb/linuxdvb_rotor.c b/src/input/mpegts/linuxdvb/linuxdvb_rotor.c index 698dce91c..0ee2d6fe7 100644 --- a/src/input/mpegts/linuxdvb/linuxdvb_rotor.c +++ b/src/input/mpegts/linuxdvb/linuxdvb_rotor.c @@ -75,13 +75,12 @@ typedef struct linuxdvb_rotor #ifndef ROTOR_TEST -static const char * -linuxdvb_rotor_class_get_title ( idnode_t *o, const char *lang ) +static void +linuxdvb_rotor_class_get_title + ( idnode_t *o, const char *lang, char *dst, size_t dstsize ) { - static char buf[256]; linuxdvb_diseqc_t *ld = (linuxdvb_diseqc_t*)o; - snprintf(buf, sizeof(buf), "Rotor: %s", ld->ld_type); - return buf; + snprintf(dst, dstsize, tvh_gettext_lang(lang, N_("Rotor: %s")), ld->ld_type); } extern const idclass_t linuxdvb_diseqc_class; diff --git a/src/input/mpegts/linuxdvb/linuxdvb_satconf.c b/src/input/mpegts/linuxdvb/linuxdvb_satconf.c index 75944c3ec..3c78e4029 100644 --- a/src/input/mpegts/linuxdvb/linuxdvb_satconf.c +++ b/src/input/mpegts/linuxdvb/linuxdvb_satconf.c @@ -147,13 +147,14 @@ linuxdvb_satconf_class_network_getset(1); linuxdvb_satconf_class_network_getset(2); linuxdvb_satconf_class_network_getset(3); -static const char * -linuxdvb_satconf_class_get_title ( idnode_t *p, const char *lang ) +static void +linuxdvb_satconf_class_get_title + ( idnode_t *p, const char *lang, char *dst, size_t dstsize ) { linuxdvb_satconf_t *ls = (linuxdvb_satconf_t*)p; struct linuxdvb_satconf_type *lst = linuxdvb_satconf_type_find(ls->ls_type); - return lst ? lst->name : ls->ls_type; + snprintf(dst, dstsize, "%s", lst ? lst->name : ls->ls_type); } static void @@ -1419,10 +1420,11 @@ linuxdvb_satconf_ele_class_rotortype_get ( void *o ) return &prop_ptr; } -static const char * -linuxdvb_satconf_ele_class_get_title ( idnode_t *o, const char *lang ) +static void +linuxdvb_satconf_ele_class_get_title + ( idnode_t *o, const char *lang, char *dst, size_t dstsize ) { - return ((linuxdvb_satconf_ele_t *)o)->lse_name; + snprintf(dst, dstsize, "%s", ((linuxdvb_satconf_ele_t *)o)->lse_name); } static idnode_set_t * @@ -1487,7 +1489,7 @@ const idclass_t linuxdvb_satconf_ele_class = .id = "displayname", .name = N_("Name"), .off = offsetof(linuxdvb_satconf_ele_t, lse_name), - .notify = idnode_notify_title_changed, + .notify = idnode_notify_title_changed_lang, }, { .type = PT_INT, @@ -1630,11 +1632,12 @@ linuxdvb_satconf_delete ( linuxdvb_satconf_t *ls, int delconf ) * DiseqC *****************************************************************************/ -static const char * -linuxdvb_diseqc_class_get_title ( idnode_t *o, const char *lang ) +static void +linuxdvb_diseqc_class_get_title + ( idnode_t *o, const char *lang, char *dst, size_t dstsize ) { linuxdvb_diseqc_t *ld = (linuxdvb_diseqc_t*)o; - return ld->ld_type; + snprintf(dst, dstsize, "%s", ld->ld_type); } static void diff --git a/src/input/mpegts/linuxdvb/linuxdvb_switch.c b/src/input/mpegts/linuxdvb/linuxdvb_switch.c index e53279a2c..e9e61192c 100644 --- a/src/input/mpegts/linuxdvb/linuxdvb_switch.c +++ b/src/input/mpegts/linuxdvb/linuxdvb_switch.c @@ -98,13 +98,12 @@ linuxdvb_switch_class_toneburst_list ( void *o, const char *lang ) return strtab2htsmsg(tab, 1, lang); } -static const char * -linuxdvb_switch_class_get_title ( idnode_t *o, const char *lang ) +static void +linuxdvb_switch_class_get_title + ( idnode_t *o, const char *lang, char *dst, size_t dstsize ) { - static char buf[256]; linuxdvb_diseqc_t *ld = (linuxdvb_diseqc_t*)o; - snprintf(buf, sizeof(buf), tvh_gettext_lang(lang, N_("Switch: %s")), ld->ld_type); - return buf; + snprintf(dst, dstsize, tvh_gettext_lang(lang, N_("Switch: %s")), ld->ld_type); } extern const idclass_t linuxdvb_diseqc_class; diff --git a/src/input/mpegts/mpegts_input.c b/src/input/mpegts/mpegts_input.c index 1d090f43e..9a0733324 100644 --- a/src/input/mpegts/mpegts_input.c +++ b/src/input/mpegts/mpegts_input.c @@ -57,13 +57,12 @@ mpegts_input_dbus_notify(mpegts_input_t *mi, int64_t subs) * Class definition * *************************************************************************/ -static const char * -mpegts_input_class_get_title ( idnode_t *in, const char *lang ) +static void +mpegts_input_class_get_title + ( idnode_t *in, const char *lang, char *dst, size_t dstsize ) { - static char buf[512]; mpegts_input_t *mi = (mpegts_input_t*)in; - mi->mi_display_name(mi, buf, sizeof(buf)); - return buf; + mi->mi_display_name(mi, dst, dstsize); } const void * @@ -121,11 +120,15 @@ mpegts_input_class_network_rend ( void *obj, const char *lang ) { char *str; mpegts_network_link_t *mnl; + mpegts_network_t *mn; mpegts_input_t *mi = obj; htsmsg_t *l = htsmsg_create_list(); + char buf[384]; - LIST_FOREACH(mnl, &mi->mi_networks, mnl_mi_link) - htsmsg_add_str(l, NULL, idnode_get_title(&mnl->mnl_network->mn_id, lang)); + LIST_FOREACH(mnl, &mi->mi_networks, mnl_mi_link) { + mn = mnl->mnl_network; + htsmsg_add_str(l, NULL, idnode_get_title(&mn->mn_id, lang, buf, sizeof(buf))); + } str = htsmsg_list_2_csv(l, ',', 1); htsmsg_destroy(l); @@ -197,7 +200,7 @@ mpegts_input_class_linked_enum( void * self, const char *lang ) { mpegts_input_t *mi = self, *mi2; tvh_input_t *ti; - char ubuf[UUID_HEX_SIZE]; + char ubuf[UUID_HEX_SIZE], buf[384]; htsmsg_t *m = htsmsg_create_list(); htsmsg_t *e = htsmsg_create_key_val("", tvh_gettext_lang(lang, N_("Not linked"))); htsmsg_add_msg(m, NULL, e); @@ -206,7 +209,7 @@ mpegts_input_class_linked_enum( void * self, const char *lang ) mi2 = (mpegts_input_t *)ti; if (mi2 != mi) { e = htsmsg_create_key_val(idnode_uuid_as_str(&ti->ti_id, ubuf), - idnode_get_title(&mi2->ti_id, lang)); + idnode_get_title(&mi2->ti_id, lang, buf, sizeof(buf))); htsmsg_add_msg(m, NULL, e); } } @@ -271,7 +274,7 @@ const idclass_t mpegts_input_class = .name = N_("Name"), .desc = N_("Name of the tuner/adapter."), .off = offsetof(mpegts_input_t, mi_name), - .notify = idnode_notify_title_changed, + .notify = idnode_notify_title_changed_lang, }, { .type = PT_BOOL, diff --git a/src/input/mpegts/mpegts_mux.c b/src/input/mpegts/mpegts_mux.c index 6e9a12441..3421f495c 100644 --- a/src/input/mpegts/mpegts_mux.c +++ b/src/input/mpegts/mpegts_mux.c @@ -314,12 +314,11 @@ mpegts_mux_class_delete ( idnode_t *self ) if (mm->mm_delete) mm->mm_delete(mm, 1); } -static const char * -mpegts_mux_class_get_title ( idnode_t *self, const char *lang ) +static void +mpegts_mux_class_get_title + ( idnode_t *self, const char *lang, char *dst, size_t dstsize ) { - static __thread char buf[256]; - mpegts_mux_nice_name((mpegts_mux_t*)self, buf, sizeof(buf)); - return buf; + mpegts_mux_nice_name((mpegts_mux_t*)self, dst, dstsize); } static const void * diff --git a/src/input/mpegts/mpegts_network.c b/src/input/mpegts/mpegts_network.c index 1f3e36725..f4114db45 100644 --- a/src/input/mpegts/mpegts_network.c +++ b/src/input/mpegts/mpegts_network.c @@ -41,15 +41,14 @@ mpegts_network_class_save return NULL; } -static const char * -mpegts_network_class_get_title ( idnode_t *in, const char *lang ) +static void +mpegts_network_class_get_title + ( idnode_t *in, const char *lang, char *dst, size_t dstsize ) { - static char buf[256]; mpegts_network_t *mn = (mpegts_network_t*)in; - *buf = 0; + *dst = 0; if (mn->mn_display_name) - mn->mn_display_name(mn, buf, sizeof(buf)); - return buf; + mn->mn_display_name(mn, dst, dstsize); } static const void * @@ -176,7 +175,7 @@ const idclass_t mpegts_network_class = .name = N_("Network name"), .desc = N_("Name of the network."), .off = offsetof(mpegts_network_t, mn_network_name), - .notify = idnode_notify_title_changed, + .notify = idnode_notify_title_changed_lang, }, { .type = PT_STR, diff --git a/src/input/mpegts/satip/satip.c b/src/input/mpegts/satip/satip.c index 766c9f5f5..778a16f55 100644 --- a/src/input/mpegts/satip/satip.c +++ b/src/input/mpegts/satip/satip.c @@ -171,14 +171,12 @@ satip_device_class_get_childs ( idnode_t *in ) return is; } -static const char * -satip_device_class_get_title( idnode_t *in, const char *lang ) +static void +satip_device_class_get_title + ( idnode_t *in, const char *lang, char *dst, size_t dstsize ) { - static char buf[256]; satip_device_t *sd = (satip_device_t *)in; - snprintf(buf, sizeof(buf), - "%s - %s", sd->sd_info.friendlyname, sd->sd_info.addr); - return buf; + snprintf(dst, dstsize, "%s - %s", sd->sd_info.friendlyname, sd->sd_info.addr); } static const char *satip_tunercfg_tab[] = { diff --git a/src/input/mpegts/satip/satip_satconf.c b/src/input/mpegts/satip/satip_satconf.c index 14465cd5b..8fb0465dc 100644 --- a/src/input/mpegts/satip/satip_satconf.c +++ b/src/input/mpegts/satip/satip_satconf.c @@ -317,10 +317,11 @@ satip_satconf_class_network_rend( void *o, const char *lang ) return str; } -static const char * -satip_satconf_class_get_title ( idnode_t *o, const char *lang ) +static void +satip_satconf_class_get_title + ( idnode_t *o, const char *lang, char *dst, size_t size ) { - return ((satip_satconf_t *)o)->sfc_name; + snprintf(dst, size, "%s", ((satip_satconf_t *)o)->sfc_name); } static void @@ -362,7 +363,7 @@ const idclass_t satip_satconf_class = .name = N_("Name"), .desc = N_("Set the display name."), .off = offsetof(satip_satconf_t, sfc_name), - .notify = idnode_notify_title_changed, + .notify = idnode_notify_title_changed_lang, }, { .type = PT_INT, diff --git a/src/input/mpegts/tvhdhomerun/tvhdhomerun.c b/src/input/mpegts/tvhdhomerun/tvhdhomerun.c index 7e4f0d76d..228229c4b 100644 --- a/src/input/mpegts/tvhdhomerun/tvhdhomerun.c +++ b/src/input/mpegts/tvhdhomerun/tvhdhomerun.c @@ -83,15 +83,15 @@ static pthread_t tvhdhomerun_discovery_tid; static pthread_mutex_t tvhdhomerun_discovery_lock; static tvh_cond_t tvhdhomerun_discovery_cond; -static const char * -tvhdhomerun_device_class_get_title( idnode_t *in, const char *lang ) +static void +tvhdhomerun_device_class_get_title + ( idnode_t *in, const char *lang, char *dst, size_t dstsize ) { tvhdhomerun_device_t *hd = (tvhdhomerun_device_t *)in; char ip[64]; tcp_get_str_from_ip(&hd->hd_info.ip_address, ip, sizeof(ip)); - snprintf(prop_sbuf, PROP_SBUF_LEN, + snprintf(dst, dstsize, "%s - %s", hd->hd_info.friendlyname, ip); - return prop_sbuf; } static const void * diff --git a/src/memoryinfo.c b/src/memoryinfo.c index c23b5677f..8039164a5 100644 --- a/src/memoryinfo.c +++ b/src/memoryinfo.c @@ -23,10 +23,11 @@ struct memoryinfo_list memoryinfo_entries; -static const char * -service_class_get_title ( idnode_t *self, const char *lang ) +static void +service_class_get_title + ( idnode_t *self, const char *lang, char *dst, size_t dstsize ) { - return ((memoryinfo_t *)self)->my_name; + snprintf(dst, dstsize, "%s", ((memoryinfo_t *)self)->my_name); } CLASS_DOC(memoryinfo) diff --git a/src/notify.h b/src/notify.h index a49451629..570c93a71 100644 --- a/src/notify.h +++ b/src/notify.h @@ -21,7 +21,8 @@ #include "htsmsg.h" -#define NOTIFY_REWRITE_SUBSCRIPTIONS 1 +#define NOTIFY_REWRITE_TITLE 1 +#define NOTIFY_REWRITE_SUBSCRIPTIONS 2 void notify_by_msg(const char *class, htsmsg_t *m, int rewrite); diff --git a/src/profile.c b/src/profile.c index c8919a2af..df8b03395 100644 --- a/src/profile.c +++ b/src/profile.c @@ -167,14 +167,16 @@ profile_class_save ( idnode_t *in, char *filename, size_t fsize ) return c; } -static const char * -profile_class_get_title ( idnode_t *in, const char *lang ) +static void +profile_class_get_title + ( idnode_t *in, const char *lang, char *dst, size_t dstsize ) { profile_t *pro = (profile_t *)in; - if (pro->pro_name && pro->pro_name[0]) - return pro->pro_name; - snprintf(prop_sbuf, sizeof(prop_sbuf), "%s", idclass_get_caption(in->in_class, lang)); - return prop_sbuf; + if (pro->pro_name && pro->pro_name[0]) { + snprintf(dst, dstsize, "%s", pro->pro_name); + } else { + snprintf(dst, dstsize, "%s", idclass_get_caption(in->in_class, lang)); + } } static void @@ -331,7 +333,7 @@ const idclass_t profile_class = .desc = N_("The name of the profile."), .off = offsetof(profile_t, pro_name), .get_opts = profile_class_name_opts, - .notify = idnode_notify_title_changed, + .notify = idnode_notify_title_changed_lang, .group = 1 }, { diff --git a/src/service.c b/src/service.c index 80b6ac518..beb33c781 100644 --- a/src/service.c +++ b/src/service.c @@ -96,10 +96,12 @@ service_class_channel_set service_mapper_create); } -static const char * -service_class_get_title ( idnode_t *self, const char *lang ) +static void +service_class_get_title + ( idnode_t *self, const char *lang, char *dst, size_t dstsize ) { - return service_get_full_channel_name((service_t *)self); + snprintf(dst, dstsize, "%s", + service_get_full_channel_name((service_t *)self) ?: ""); } static const void * diff --git a/src/subscriptions.c b/src/subscriptions.c index e55f0e0e3..a176c9626 100644 --- a/src/subscriptions.c +++ b/src/subscriptions.c @@ -1069,7 +1069,8 @@ subscription_create_msg(th_subscription_t *s, const char *lang) if (s->ths_prch != NULL) { pro = s->ths_prch->prch_pro; if (pro) - htsmsg_add_str(m, "profile", idnode_get_title(&pro->pro_id, lang)); + htsmsg_add_str(m, "profile", + idnode_get_title(&pro->pro_id, lang, buf, sizeof(buf))); } } else if(s->ths_dvrfile != NULL) diff --git a/src/webui/comet.c b/src/webui/comet.c index 0dfaccaf6..0d3dec0cc 100644 --- a/src/webui/comet.c +++ b/src/webui/comet.c @@ -523,10 +523,28 @@ comet_mailbox_rewrite_str(htsmsg_t *m, const char *key, const char *lang) } } +static void +comet_mailbox_rewrite_title(htsmsg_t *m, const char *lang) +{ + idnode_t *in; + const char *s = htsmsg_get_str(m, "uuid"); + char buf[384]; + if (s) { + idnode_lock(); + in = idnode_find(s, NULL, NULL); + if (in) + htsmsg_set_str(m, "text", idnode_get_title(in, lang, buf, sizeof(buf))); + idnode_unlock(); + } +} + static void comet_mailbox_rewrite_msg(int rewrite, htsmsg_t *m, const char *lang) { switch (rewrite) { + case NOTIFY_REWRITE_TITLE: + comet_mailbox_rewrite_title(m, lang); + break; case NOTIFY_REWRITE_SUBSCRIPTIONS: comet_mailbox_rewrite_str(m, "state", lang); break;