From: Jaroslav Kysela Date: Wed, 10 Feb 2016 16:08:22 +0000 (+0100) Subject: idnode: change config save mechanism (do I/O outside global_lock) X-Git-Tag: v4.2.1~1039 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=bd55aebc4972dae7d25be33bbf4d5e4134036b77;p=thirdparty%2Ftvheadend.git idnode: change config save mechanism (do I/O outside global_lock) --- diff --git a/src/access.c b/src/access.c index d65b79710..b11886f6a 100644 --- a/src/access.c +++ b/src/access.c @@ -1143,19 +1143,6 @@ access_destroy_by_channel_tag(channel_tag_t *ct, int delconf) idnode_list_destroy(&ct->ct_accesses, delconf ? ct : NULL); } -/** - * - */ -void -access_entry_save(access_entry_t *ae) -{ - htsmsg_t *c = htsmsg_create_map(); - char ubuf[UUID_HEX_SIZE]; - idnode_save(&ae->ae_id, c); - hts_settings_save(c, "accesscontrol/%s", idnode_uuid_as_str(&ae->ae_id, ubuf)); - htsmsg_destroy(c); -} - /** * */ @@ -1168,7 +1155,7 @@ access_entry_reindex(void) TAILQ_FOREACH(ae, &access_entries, ae_link) { if (ae->ae_index != i) { ae->ae_index = i; - access_entry_save(ae); + idnode_changed(&ae->ae_id); } i++; } @@ -1178,11 +1165,16 @@ access_entry_reindex(void) * Class definition * **************************************************************************/ -static void -access_entry_class_save(idnode_t *self) +static htsmsg_t * +access_entry_class_save(idnode_t *self, char *filename, size_t fsize) { + access_entry_t *ae = (access_entry_t *)self; + char ubuf[UUID_HEX_SIZE]; + htsmsg_t *c = htsmsg_create_map(); access_entry_update_rights((access_entry_t *)self); - access_entry_save((access_entry_t *)self); + idnode_save(&ae->ae_id, c); + snprintf(filename, fsize, "accesscontrol/%s", idnode_uuid_as_str(&ae->ae_id, ubuf)); + return c; } static void @@ -1778,20 +1770,15 @@ passwd_entry_destroy(passwd_entry_t *pw, int delconf) free(pw); } -void -passwd_entry_save(passwd_entry_t *pw) +static htsmsg_t * +passwd_entry_class_save(idnode_t *self, char *filename, size_t fsize) { - htsmsg_t *c = htsmsg_create_map(); + passwd_entry_t *pw = (passwd_entry_t *)self; char ubuf[UUID_HEX_SIZE]; + htsmsg_t *c = htsmsg_create_map(); idnode_save(&pw->pw_id, c); - hts_settings_save(c, "passwd/%s", idnode_uuid_as_str(&pw->pw_id, ubuf)); - htsmsg_destroy(c); -} - -static void -passwd_entry_class_save(idnode_t *self) -{ - passwd_entry_save((passwd_entry_t *)self); + snprintf(filename, fsize, "passwd/%s", idnode_uuid_as_str(&pw->pw_id, ubuf)); + return c; } static void @@ -1954,20 +1941,15 @@ ipblock_entry_destroy(ipblock_entry_t *ib) free(ib); } -void -ipblock_entry_save(ipblock_entry_t *ib) +static htsmsg_t * +ipblock_entry_class_save(idnode_t *self, char *filename, size_t fsize) { + ipblock_entry_t *ib = (ipblock_entry_t *)self; htsmsg_t *c = htsmsg_create_map(); char ubuf[UUID_HEX_SIZE]; idnode_save(&ib->ib_id, c); - hts_settings_save(c, "ipblock/%s", idnode_uuid_as_str(&ib->ib_id, ubuf)); - htsmsg_destroy(c); -} - -static void -ipblock_entry_class_save(idnode_t *self) -{ - ipblock_entry_save((ipblock_entry_t *)self); + snprintf(filename, fsize, "ipblock/%s", idnode_uuid_as_str(&ib->ib_id, ubuf)); + return c; } static const char * @@ -2109,7 +2091,7 @@ access_init(int createdefault, int noacl) ae->ae_admin = 1; access_entry_update_rights(ae); - access_entry_save(ae); + idnode_changed(&ae->ae_id); tvhlog(LOG_WARNING, "access", "Created default wide open access controle entry"); diff --git a/src/access.h b/src/access.h index 8b5f6a8ff..60462b53d 100644 --- a/src/access.h +++ b/src/access.h @@ -275,12 +275,6 @@ access_entry_create(const char *uuid, htsmsg_t *conf); void access_entry_destroy(access_entry_t *ae, int delconf); -/** - * - */ -void -access_entry_save(access_entry_t *ae); - /** * */ @@ -298,16 +292,12 @@ passwd_entry_t * passwd_entry_create(const char *uuid, htsmsg_t *conf); void passwd_entry_destroy(passwd_entry_t *ae, int delconf); -void -passwd_entry_save(passwd_entry_t *pw); /** * */ ipblock_entry_t * ipblock_entry_create(const char *uuid, htsmsg_t *conf); -void -ipblock_entry_save(ipblock_entry_t *pw); /** * diff --git a/src/api/api_access.c b/src/api/api_access.c index f31ef6413..734d6deeb 100644 --- a/src/api/api_access.c +++ b/src/api/api_access.c @@ -47,7 +47,7 @@ api_passwd_entry_create pthread_mutex_lock(&global_lock); if ((pw = passwd_entry_create(NULL, conf)) != NULL) - passwd_entry_save(pw); + idnode_changed(&pw->pw_id); pthread_mutex_unlock(&global_lock); return 0; @@ -79,7 +79,7 @@ api_ipblock_entry_create pthread_mutex_lock(&global_lock); if ((ib = ipblock_entry_create(NULL, conf)) != NULL) - ipblock_entry_save(ib); + idnode_changed(&ib->ib_id); pthread_mutex_unlock(&global_lock); return 0; @@ -155,7 +155,7 @@ api_access_entry_create pthread_mutex_lock(&global_lock); if ((ae = access_entry_create(NULL, conf)) != NULL) - access_entry_save(ae); + idnode_changed(&ae->ae_id); pthread_mutex_unlock(&global_lock); return 0; diff --git a/src/api/api_bouquet.c b/src/api/api_bouquet.c index 4143f975a..6ed798f68 100644 --- a/src/api/api_bouquet.c +++ b/src/api/api_bouquet.c @@ -75,7 +75,7 @@ api_bouquet_create pthread_mutex_lock(&global_lock); bq = bouquet_create(NULL, conf, NULL, NULL); if (bq) - bouquet_save(bq, 0); + idnode_changed(&bq->bq_id); pthread_mutex_unlock(&global_lock); return 0; diff --git a/src/api/api_channel.c b/src/api/api_channel.c index 79df5c553..2de1c2aad 100644 --- a/src/api/api_channel.c +++ b/src/api/api_channel.c @@ -94,7 +94,7 @@ api_channel_create pthread_mutex_lock(&global_lock); ch = channel_create(NULL, conf, NULL); if (ch) - channel_save(ch); + idnode_changed(&ch->ch_id); pthread_mutex_unlock(&global_lock); return 0; @@ -151,7 +151,7 @@ api_channel_tag_create pthread_mutex_lock(&global_lock); ct = channel_tag_create(NULL, conf); if (ct) - channel_tag_save(ct); + idnode_changed(&ct->ct_id); pthread_mutex_unlock(&global_lock); return 0; diff --git a/src/api/api_dvr.c b/src/api/api_dvr.c index 911965468..3e3d9d637 100644 --- a/src/api/api_dvr.c +++ b/src/api/api_dvr.c @@ -57,7 +57,7 @@ api_dvr_config_create pthread_mutex_lock(&global_lock); if ((cfg = dvr_config_create(NULL, NULL, conf))) - dvr_config_save(cfg); + idnode_changed(&cfg->dvr_id); pthread_mutex_unlock(&global_lock); return 0; @@ -172,7 +172,7 @@ api_dvr_entry_create htsmsg_add_msg(conf, "subtitle", m); } if ((de = dvr_entry_create(NULL, conf, 0))) - dvr_entry_save(de); + idnode_changed(&de->de_id); res = 0; free(lang); @@ -244,7 +244,7 @@ api_dvr_entry_create_by_event NULL, DVR_PRIO_NORMAL, DVR_RET_DVRCONFIG, DVR_RET_DVRCONFIG, comment); if (de) - dvr_entry_save(de); + idnode_changed(&de->de_id); } } pthread_mutex_unlock(&global_lock); @@ -382,10 +382,8 @@ api_dvr_autorec_create if (cfg) { htsmsg_set_str(conf, "config_name", idnode_uuid_as_str(&cfg->dvr_id, ubuf)); dae = dvr_autorec_create(NULL, conf); - if (dae) { - dvr_autorec_save(dae); - dvr_autorec_changed(dae, 1); - } + if (dae) + idnode_changed(&dae->dae_id); } pthread_mutex_unlock(&global_lock); @@ -427,10 +425,8 @@ api_dvr_autorec_create_by_series perm->aa_username, perm->aa_representative, "Created from EPG query"); - if (dae) { - dvr_autorec_save(dae); - dvr_autorec_changed(dae, 1); - } + if (dae) + idnode_changed(&dae->dae_id); } } pthread_mutex_unlock(&global_lock); @@ -467,10 +463,8 @@ api_dvr_timerec_create pthread_mutex_lock(&global_lock); dte = dvr_timerec_create(NULL, conf); - if (dte) { - dvr_timerec_save(dte); - dvr_timerec_check(dte); - } + if (dte) + idnode_changed(&dte->dte_id); pthread_mutex_unlock(&global_lock); return 0; diff --git a/src/api/api_mpegts.c b/src/api/api_mpegts.c index 596b74b01..ea54ad0b4 100644 --- a/src/api/api_mpegts.c +++ b/src/api/api_mpegts.c @@ -128,7 +128,7 @@ api_mpegts_network_create if (mn) { err = 0; *resp = htsmsg_create_map(); - mn->mn_config_save(mn); + idnode_changed(&mn->mn_id); } else { err = EINVAL; } @@ -225,7 +225,7 @@ api_mpegts_network_muxcreate if (!(mm = mn->mn_mux_create2(mn, conf))) goto exit; - mm->mm_config_save(mm); + idnode_changed(&mm->mm_id); err = 0; exit: @@ -319,7 +319,7 @@ api_mpegts_mux_sched_create if (mms) { err = 0; *resp = htsmsg_create_map(); - mpegts_mux_sched_save(mms); + idnode_changed(&mms->mms_id); } else { err = EINVAL; } diff --git a/src/api/api_wizard.c b/src/api/api_wizard.c index d7128e961..d586870fd 100644 --- a/src/api/api_wizard.c +++ b/src/api/api_wizard.c @@ -32,7 +32,7 @@ wizard_page ( const char *page ) if (strcmp(page, config.wizard ?: "")) { free(config.wizard); config.wizard = page[0] ? strdup(page) : NULL; - config_save(); + idnode_changed(&config.idnode); } pthread_mutex_unlock(&global_lock); return 0; diff --git a/src/bouquet.c b/src/bouquet.c index 26f43d7b5..a628f2180 100644 --- a/src/bouquet.c +++ b/src/bouquet.c @@ -206,7 +206,7 @@ bouquet_find_by_source(const char *name, const char *src, int create) tvhwarn("bouquet", "bouquet name '%s' changed to '%s'", bq->bq_name ?: "", name); free(bq->bq_name); bq->bq_name = strdup(name); - bouquet_save(bq, 1); + idnode_changed(&bq->bq_id); } return bq; } @@ -239,7 +239,7 @@ bouquet_tag(bouquet_t *bq, int create) ct = channel_tag_find_by_name(buf, create); if (ct) { bq->bq_chtag_ptr = ct; - bouquet_save(bq, 0); + idnode_changed(&bq->bq_id); } return ct; } @@ -294,10 +294,8 @@ bouquet_map_channel(bouquet_t *bq, service_t *t) else ch = (channel_t *)ilm->ilm_in2; if (ch && bq->bq_chtag) - if (channel_tag_map(bouquet_tag(bq, 1), ch, ch)) { - idnode_notify_changed(&ch->ch_id); - channel_save(ch); - } + if (channel_tag_map(bouquet_tag(bq, 1), ch, ch)) + idnode_changed(&ch->ch_id); } /* @@ -462,8 +460,10 @@ bouquet_completed(bouquet_t *bq, uint32_t seen) bq->bq_active_services = idnode_set_create(1); save: - if (bq->bq_saveflag) - bouquet_save(bq, 1); + if (bq->bq_saveflag) { + bq->bq_saveflag = 0; + idnode_changed(&bq->bq_id); + } } /* @@ -568,28 +568,10 @@ bouquet_delete(bouquet_t *bq) } else { idnode_set_free(bq->bq_services); bq->bq_services = idnode_set_create(1); - bouquet_save(bq, 1); + idnode_changed(&bq->bq_id); } } -/** - * - */ -void -bouquet_save(bouquet_t *bq, int notify) -{ - htsmsg_t *c = htsmsg_create_map(); - char ubuf[UUID_HEX_SIZE]; - idnode_save(&bq->bq_id, c); - hts_settings_save(c, "bouquet/%s", idnode_uuid_as_str(&bq->bq_id, ubuf)); - if (bq->bq_shield) - htsmsg_add_bool(c, "shield", 1); - htsmsg_destroy(c); - bq->bq_saveflag = 0; - if (notify) - idnode_notify_changed(&bq->bq_id); -} - /** * */ @@ -607,10 +589,18 @@ bouquet_change_comment ( bouquet_t *bq, const char *comment, int replace ) * Class definition * **************************************************************************/ -static void -bouquet_class_save(idnode_t *self) +static htsmsg_t * +bouquet_class_save(idnode_t *self, char *filename, size_t fsize) { - bouquet_save((bouquet_t *)self, 0); + bouquet_t *bq = (bouquet_t *)self; + htsmsg_t *c = htsmsg_create_map(); + char ubuf[UUID_HEX_SIZE]; + idnode_save(&bq->bq_id, c); + snprintf(filename, fsize, "bouquet/%s", idnode_uuid_as_str(&bq->bq_id, ubuf)); + if (bq->bq_shield) + htsmsg_add_bool(c, "shield", 1); + bq->bq_saveflag = 0; + return c; } static void diff --git a/src/bouquet.h b/src/bouquet.h index 44b8a75be..1cf3eb9c2 100644 --- a/src/bouquet.h +++ b/src/bouquet.h @@ -96,8 +96,6 @@ void bouquet_change_comment(bouquet_t *bq, const char *comment, int replace); uint64_t bouquet_get_channel_number(bouquet_t *bq, service_t *t); -void bouquet_save(bouquet_t *bq, int notify); - /** * */ diff --git a/src/channels.c b/src/channels.c index c3f15538b..59d649ed0 100644 --- a/src/channels.c +++ b/src/channels.c @@ -69,9 +69,28 @@ ch_id_cmp ( channel_t *a, channel_t *b ) * *************************************************************************/ static void -channel_class_save ( idnode_t *self ) +channel_class_changed ( idnode_t *self ) { - channel_save((channel_t *)self); + channel_t *ch = (channel_t *)self; + + /* update the EPG channel <-> channel mapping here */ + if (ch->ch_enabled && ch->ch_epgauto) + epggrab_channel_add(ch); +} + +static htsmsg_t * +channel_class_save ( idnode_t *self, char *filename, size_t fsize ) +{ + channel_t *ch = (channel_t *)self; + htsmsg_t *c = NULL; + char ubuf[UUID_HEX_SIZE]; + /* save channel (on demand) */ + if (ch->ch_dont_save == 0) { + c = htsmsg_create_map(); + idnode_save(&ch->ch_id, c); + snprintf(filename, fsize, "channel/config/%s", idnode_uuid_as_str(&ch->ch_id, ubuf)); + } + return c; } static void @@ -342,6 +361,7 @@ const idclass_t channel_class = { .ic_class = "channel", .ic_caption = N_("Channel"), .ic_event = "channel", + .ic_changed = channel_class_changed, .ic_save = channel_class_save, .ic_get_title = channel_class_get_title, .ic_delete = channel_class_delete, @@ -768,8 +788,7 @@ channel_get_icon ( channel_t *ch ) if (strncmp(icn, "picon://", 8) == 0) continue; if (check_file(icn)) { icon = ch->ch_icon = strdup(icn); - channel_save(ch); - idnode_notify_changed(&ch->ch_id); + idnode_changed(&ch->ch_id); goto found; } } @@ -857,8 +876,7 @@ channel_get_icon ( channel_t *ch ) if (i > 1 || check_file(buf)) { icon = ch->ch_icon = strdup(buf); - channel_save(ch); - idnode_notify_changed(&ch->ch_id); + idnode_changed(&ch->ch_id); } } @@ -871,8 +889,7 @@ channel_get_icon ( channel_t *ch ) snprintf(buf2, sizeof(buf2), "%s/%s", picon, icn+8); if (i > 1 || check_file(buf2)) { icon = ch->ch_icon = strdup(icn); - channel_save(ch); - idnode_notify_changed(&ch->ch_id); + idnode_changed(&ch->ch_id); break; } } @@ -1026,7 +1043,7 @@ channel_delete ( channel_t *ch, int delconf ) if (delconf) { free(ch1->ch_epg_parent); ch1->ch_epg_parent = NULL; - channel_save(ch1); + idnode_changed(&ch1->ch_id); } } @@ -1046,26 +1063,6 @@ channel_delete ( channel_t *ch, int delconf ) free(ch); } -/* - * Save - */ -void -channel_save ( channel_t *ch ) -{ - htsmsg_t *c; - char ubuf[UUID_HEX_SIZE]; - if (ch->ch_dont_save == 0) { - c = htsmsg_create_map(); - idnode_save(&ch->ch_id, c); - hts_settings_save(c, "channel/config/%s", idnode_uuid_as_str(&ch->ch_id, ubuf)); - htsmsg_destroy(c); - } - /* update the EPG channel <-> channel mapping here */ - if (ch->ch_enabled && ch->ch_epgauto) - epggrab_channel_add(ch); -} - - /** @@ -1252,21 +1249,6 @@ channel_tag_destroy(channel_tag_t *ct, int delconf) free(ct); } -/** - * - */ -void -channel_tag_save(channel_tag_t *ct) -{ - htsmsg_t *c = htsmsg_create_map(); - char ubuf[UUID_HEX_SIZE]; - idnode_save(&ct->ct_id, c); - hts_settings_save(c, "channel/tag/%s", idnode_uuid_as_str(&ct->ct_id, ubuf)); - htsmsg_destroy(c); - htsp_tag_update(ct); -} - - /** * */ @@ -1319,10 +1301,16 @@ chtags_ok: * Channel Tag Class definition * **************************************************************************/ -static void -channel_tag_class_save(idnode_t *self) +static htsmsg_t * +channel_tag_class_save(idnode_t *self, char *filename, size_t fsize) { - channel_tag_save((channel_tag_t *)self); + channel_tag_t *ct = (channel_tag_t *)self; + htsmsg_t *c = htsmsg_create_map(); + char ubuf[UUID_HEX_SIZE]; + idnode_save(&ct->ct_id, c); + snprintf(filename, fsize, "channel/tag/%s", idnode_uuid_as_str(&ct->ct_id, ubuf)); + htsp_tag_update(ct); + return c; } static void @@ -1474,7 +1462,7 @@ channel_tag_find_by_name(const char *name, int create) ct->ct_enabled = 1; tvh_str_update(&ct->ct_name, name); - channel_tag_save(ct); + idnode_changed(&ct->ct_id); return ct; } diff --git a/src/channels.h b/src/channels.h index fe74cec8d..991045fd0 100644 --- a/src/channels.h +++ b/src/channels.h @@ -150,8 +150,6 @@ channel_tag_t *channel_tag_find_by_identifier(uint32_t id); static inline channel_tag_t *channel_tag_find_by_uuid(const char *uuid) { return (channel_tag_t*)idnode_find(uuid, &channel_tag_class, NULL); } -void channel_tag_save(channel_tag_t *ct); - htsmsg_t * channel_tag_class_get_list(void *o, const char *lang); const char * channel_tag_get_icon(channel_tag_t *ct); @@ -165,8 +163,6 @@ void channel_tag_unmap(channel_t *ch, void *origin); int channel_tag_access(channel_tag_t *ct, struct access *a, int disabled); -void channel_save(channel_t *ch); - const char *channel_get_name ( channel_t *ch ); int channel_set_name ( channel_t *ch, const char *name ); diff --git a/src/config.c b/src/config.c index cb3ceddf7..8e6ff9d21 100644 --- a/src/config.c +++ b/src/config.c @@ -1568,7 +1568,7 @@ config_migrate ( int backup ) update: config.version = v; tvh_str_set(&config.full_version, tvheadend_version); - config_save(); + idnode_changed(&config.idnode); return 1; } @@ -1722,7 +1722,7 @@ config_init ( int backup ) config.version = ARRAY_SIZE(config_migrate_table); tvh_str_set(&config.full_version, tvheadend_version); tvh_str_set(&config.server_name, "Tvheadend"); - config_save(); + idnode_changed(&config.idnode); /* Perform migrations */ } else { @@ -1748,24 +1748,20 @@ void config_done ( void ) file_unlock(config_lock, config_lock_fd); } -void config_save ( void ) +/* ************************************************************************** + * Config Class + * *************************************************************************/ + +static htsmsg_t * +config_class_save(idnode_t *self, char *filename, size_t fsize) { htsmsg_t *c = htsmsg_create_map(); idnode_save(&config.idnode, c); #if ENABLE_SATIP_SERVER idnode_save(&satip_server_conf.idnode, c); #endif - hts_settings_save(c, "config"); - htsmsg_destroy(c); -} - -/* ************************************************************************** - * Config Class - * *************************************************************************/ - -static void config_class_save(idnode_t *self) -{ - config_save(); + snprintf(filename, fsize, "config"); + return c; } static int diff --git a/src/config.h b/src/config.h index 306777c0d..1df2d7bd9 100644 --- a/src/config.h +++ b/src/config.h @@ -62,7 +62,6 @@ extern config_t config; void config_boot ( const char *path, gid_t gid, uid_t uid ); void config_init ( int backup ); void config_done ( void ); -void config_save ( void ); const char *config_get_server_name ( void ); const char *config_get_language ( void ); diff --git a/src/descrambler/caclient.c b/src/descrambler/caclient.c index ad73b2a99..83e2ed11b 100644 --- a/src/descrambler/caclient.c +++ b/src/descrambler/caclient.c @@ -37,8 +37,6 @@ const idclass_t *caclient_classes[] = { struct caclient_entry_queue caclients; static pthread_mutex_t caclients_mutex; -static void caclient_class_save ( idnode_t *in ); - static const idclass_t * caclient_class_find(const char *name) { @@ -68,7 +66,7 @@ caclient_reindex(void) TAILQ_FOREACH(cac, &caclients, cac_link) if (cac->cac_save) { cac->cac_save = 0; - caclient_class_save((idnode_t *)cac); + idnode_changed((idnode_t *)cac); } } @@ -129,7 +127,7 @@ caclient_create } pthread_mutex_unlock(&caclients_mutex); if (save) - caclient_class_save((idnode_t *)cac); + idnode_changed((idnode_t *)cac); cac->cac_conf_changed(cac); return cac; } @@ -155,15 +153,20 @@ caclient_delete(caclient_t *cac, int delconf) } static void -caclient_class_save ( idnode_t *in ) +caclient_class_changed ( idnode_t *in ) { - char ubuf[UUID_HEX_SIZE]; caclient_t *cac = (caclient_t *)in; + cac->cac_conf_changed(cac); +} + +static htsmsg_t * +caclient_class_save ( idnode_t *in, char *filename, size_t fsize ) +{ + char ubuf[UUID_HEX_SIZE]; htsmsg_t *c = htsmsg_create_map(); idnode_save(in, c); - hts_settings_save(c, "caclient/%s", idnode_uuid_as_str(in, ubuf)); - htsmsg_destroy(c); - cac->cac_conf_changed(cac); + snprintf(filename, fsize, "caclient/%s", idnode_uuid_as_str(in, ubuf)); + return c; } static const char * @@ -237,6 +240,7 @@ const idclass_t caclient_class = { .ic_class = "caclient", .ic_caption = N_("Conditional access client"), + .ic_changed = caclient_class_changed, .ic_save = caclient_class_save, .ic_event = "caclient", .ic_get_title = caclient_class_get_title, diff --git a/src/dvr/dvr.h b/src/dvr/dvr.h index 4d66b6889..7be02c34d 100644 --- a/src/dvr/dvr.h +++ b/src/dvr/dvr.h @@ -440,8 +440,6 @@ static inline dvr_config_t *dvr_config_find_by_uuid(const char *uuid) void dvr_config_delete(const char *name); -void dvr_config_save(dvr_config_t *cfg); - void dvr_config_destroy_by_profile(profile_t *pro, int delconf); static inline uint32_t dvr_retention_cleanup(uint32_t val) @@ -487,8 +485,6 @@ void dvr_entry_init(void); void dvr_entry_done(void); -void dvr_entry_save(dvr_entry_t *de); - void dvr_entry_destroy_by_config(dvr_config_t *cfg, int delconf); int dvr_entry_set_state(dvr_entry_t *de, dvr_entry_sched_state_t state, @@ -635,8 +631,6 @@ dvr_autorec_add_series_link(const char *dvr_config_name, const char *owner, const char *creator, const char *comment); -void dvr_autorec_save(dvr_autorec_entry_t *dae); - void dvr_autorec_changed(dvr_autorec_entry_t *dae, int purge); static inline dvr_autorec_entry_t * @@ -709,8 +703,6 @@ dvr_timerec_find_by_uuid(const char *uuid) { return (dvr_timerec_entry_t*)idnode_find(uuid, &dvr_timerec_entry_class, NULL); } -void dvr_timerec_save(dvr_timerec_entry_t *dae); - void dvr_timerec_check(dvr_timerec_entry_t *dae); void timerec_destroy_by_config(dvr_config_t *cfg, int delconf); diff --git a/src/dvr/dvr_autorec.c b/src/dvr/dvr_autorec.c index 54fcc94ac..bb08edf28 100644 --- a/src/dvr/dvr_autorec.c +++ b/src/dvr/dvr_autorec.c @@ -87,7 +87,7 @@ dvr_autorec_purge_spawns(dvr_autorec_entry_t *dae, int del, int disabled) } dvr_entry_cancel(de, 0); } else - dvr_entry_save(de); + idnode_changed(&de->de_id); } if (bcast) bcast[i] = NULL; @@ -310,10 +310,8 @@ dvr_autorec_create_htsp(htsmsg_t *conf) dae = dvr_autorec_create(NULL, conf); htsmsg_destroy(conf); - if (dae) { - dvr_autorec_save(dae); - dvr_autorec_changed(dae, 1); - } + if (dae) + idnode_changed(&dae->dae_id); return dae; } @@ -322,8 +320,7 @@ void dvr_autorec_update_htsp(dvr_autorec_entry_t *dae, htsmsg_t *conf) { idnode_update(&dae->dae_id, conf); - dvr_autorec_save(dae); - dvr_autorec_changed(dae, 1); + idnode_changed(&dae->dae_id); tvhlog(LOG_INFO, "autorec", "\"%s\" on \"%s\": Updated", dae->dae_title ? dae->dae_title : "", (dae->dae_channel && dae->dae_channel->ch_name) ? dae->dae_channel->ch_name : "any channel"); } @@ -407,36 +404,31 @@ autorec_entry_destroy(dvr_autorec_entry_t *dae, int delconf) free(dae); } -/** - * - */ -void -dvr_autorec_save(dvr_autorec_entry_t *dae) -{ - htsmsg_t *m = htsmsg_create_map(); - char ubuf[UUID_HEX_SIZE]; - - lock_assert(&global_lock); - - idnode_save(&dae->dae_id, m); - hts_settings_save(m, "dvr/autorec/%s", idnode_uuid_as_str(&dae->dae_id, ubuf)); - htsmsg_destroy(m); -} - /* ************************************************************************** * DVR Autorec Entry Class definition * **************************************************************************/ static void -dvr_autorec_entry_class_save(idnode_t *self) +dvr_autorec_entry_class_changed(idnode_t *self) { dvr_autorec_entry_t *dae = (dvr_autorec_entry_t *)self; - dvr_autorec_save(dae); + dvr_autorec_changed(dae, 1); dvr_autorec_completed(dae, 0); htsp_autorec_entry_update(dae); } +static htsmsg_t * +dvr_autorec_entry_class_save(idnode_t *self, char *filename, size_t fsize) +{ + dvr_autorec_entry_t *dae = (dvr_autorec_entry_t *)self; + htsmsg_t *m = htsmsg_create_map(); + char ubuf[UUID_HEX_SIZE]; + idnode_save(&dae->dae_id, m); + snprintf(filename, fsize, "dvr/autorec/%s", idnode_uuid_as_str(&dae->dae_id, ubuf)); + return m; +} + static void dvr_autorec_entry_class_delete(idnode_t *self) { @@ -981,6 +973,7 @@ const idclass_t dvr_autorec_entry_class = { .ic_class = "dvrautorec", .ic_caption = N_("DVR Auto-record entry"), .ic_event = "dvrautorec", + .ic_changed = dvr_autorec_entry_class_changed, .ic_save = dvr_autorec_entry_class_save, .ic_get_title = dvr_autorec_entry_class_get_title, .ic_delete = dvr_autorec_entry_class_delete, @@ -1409,7 +1402,7 @@ autorec_destroy_by_channel_tag(channel_tag_t *ct, int delconf) dae->dae_channel_tag = NULL; idnode_notify_changed(&dae->dae_id); if (delconf) - dvr_autorec_save(dae); + idnode_changed(&dae->dae_id); } } @@ -1443,7 +1436,7 @@ autorec_destroy_by_config(dvr_config_t *kcfg, int delconf) LIST_INSERT_HEAD(&cfg->dvr_autorec_entries, dae, dae_config_link); dae->dae_config = cfg; if (delconf) - dvr_autorec_save(dae); + idnode_changed(&dae->dae_id); } } diff --git a/src/dvr/dvr_config.c b/src/dvr/dvr_config.c index fcc62ac4f..eff44d30c 100644 --- a/src/dvr/dvr_config.c +++ b/src/dvr/dvr_config.c @@ -74,7 +74,7 @@ dvr_config_find_by_name_default(const char *name) if (dvrdefaultconfig == NULL) { cfg = dvr_config_create("", NULL, NULL); assert(cfg); - dvr_config_save(cfg); + idnode_changed(&cfg->dvr_id); dvrdefaultconfig = cfg; } @@ -508,38 +508,12 @@ dvr_config_delete(const char *name) tvhwarn("dvr", "Attempt to delete default config ignored"); } -/* - * - */ -void -dvr_config_save(dvr_config_t *cfg) -{ - htsmsg_t *m = htsmsg_create_map(); - char ubuf[UUID_HEX_SIZE]; - - lock_assert(&global_lock); - - dvr_config_storage_check(cfg); - if (cfg->dvr_cleanup_threshold_free < 50) - cfg->dvr_cleanup_threshold_free = 50; // as checking is only periodically, lower is not save - if (cfg->dvr_removal_days != DVR_RET_FOREVER && - cfg->dvr_removal_days > cfg->dvr_retention_days) - cfg->dvr_retention_days = DVR_RET_ONREMOVE; - if (cfg->dvr_removal_days > DVR_RET_FOREVER) - cfg->dvr_removal_days = DVR_RET_FOREVER; - if (cfg->dvr_retention_days > DVR_RET_FOREVER) - cfg->dvr_retention_days = DVR_RET_FOREVER; - idnode_save(&cfg->dvr_id, m); - hts_settings_save(m, "dvr/config/%s", idnode_uuid_as_str(&cfg->dvr_id, ubuf)); - htsmsg_destroy(m); -} - /* ************************************************************************** * DVR Config Class definition * **************************************************************************/ static void -dvr_config_class_save(idnode_t *self) +dvr_config_class_changed(idnode_t *self) { dvr_config_t *cfg = (dvr_config_t *)self; if (dvr_config_is_default(cfg)) @@ -551,7 +525,27 @@ dvr_config_class_save(idnode_t *self) } else { dvr_update_pathname_from_booleans(cfg); } - dvr_config_save(cfg); + dvr_config_storage_check(cfg); + if (cfg->dvr_cleanup_threshold_free < 50) + cfg->dvr_cleanup_threshold_free = 50; // as checking is only periodically, lower is not save + if (cfg->dvr_removal_days != DVR_RET_FOREVER && + cfg->dvr_removal_days > cfg->dvr_retention_days) + cfg->dvr_retention_days = DVR_RET_ONREMOVE; + if (cfg->dvr_removal_days > DVR_RET_FOREVER) + cfg->dvr_removal_days = DVR_RET_FOREVER; + if (cfg->dvr_retention_days > DVR_RET_FOREVER) + cfg->dvr_retention_days = DVR_RET_FOREVER; +} + +static htsmsg_t * +dvr_config_class_save(idnode_t *self, char *filename, size_t fsize) +{ + dvr_config_t *cfg = (dvr_config_t *)self; + htsmsg_t *m = htsmsg_create_map(); + char ubuf[UUID_HEX_SIZE]; + idnode_save(&cfg->dvr_id, m); + snprintf(filename, fsize, "dvr/config/%s", idnode_uuid_as_str(&cfg->dvr_id, ubuf)); + return m; } static void @@ -787,6 +781,7 @@ const idclass_t dvr_config_class = { .ic_class = "dvrconfig", .ic_caption = N_("DVR configuration profile"), .ic_event = "dvrconfig", + .ic_changed = dvr_config_class_changed, .ic_save = dvr_config_class_save, .ic_get_title = dvr_config_class_get_title, .ic_delete = dvr_config_class_delete, diff --git a/src/dvr/dvr_db.c b/src/dvr/dvr_db.c index 9a34c9a47..ab1b9e1ab 100644 --- a/src/dvr/dvr_db.c +++ b/src/dvr/dvr_db.c @@ -134,7 +134,7 @@ dvr_entry_dont_rerecord(dvr_entry_t *de, int dont_rerecord) dont_rerecord = dont_rerecord ? 1 : 0; if (de->de_dont_rerecord ? 1 : 0 != dont_rerecord) { de->de_dont_rerecord = dont_rerecord; - dvr_entry_save(de); + idnode_changed(&de->de_id); idnode_notify_changed(&de->de_id); htsp_dvr_entry_update(de); } @@ -162,9 +162,9 @@ dvr_entry_change_parent_child(dvr_entry_t *parent, dvr_entry_t *child, void *ori if (parent->de_child) { p = parent->de_child->de_parent; parent->de_child->de_parent = NULL; - if (save && p && p != origin) dvr_entry_save(p); + if (save && p && p != origin) idnode_changed(&p->de_id); parent->de_child = NULL; - if (save && origin != parent) dvr_entry_save(parent); + if (save && origin != parent) idnode_changed(&parent->de_id); return 1; } return 0; @@ -173,9 +173,9 @@ dvr_entry_change_parent_child(dvr_entry_t *parent, dvr_entry_t *child, void *ori if (child->de_parent) { p = child->de_parent->de_child; child->de_parent->de_child = NULL; - if (save && p && p != origin) dvr_entry_save(p); + if (save && p && p != origin) idnode_changed(&p->de_id); child->de_parent = NULL; - if (save && origin != child) dvr_entry_save(child); + if (save && origin != child) idnode_changed(&child->de_id); return 1; } return 0; @@ -183,17 +183,17 @@ dvr_entry_change_parent_child(dvr_entry_t *parent, dvr_entry_t *child, void *ori if (parent->de_child) { p = parent->de_child->de_parent; parent->de_child->de_parent = NULL; - if (save && p) dvr_entry_save(p); + if (save && p) idnode_changed(&p->de_id); } if (child->de_parent) { p = child->de_parent->de_child; child->de_parent->de_child = NULL; - if (save && p) dvr_entry_save(p); + if (save && p) idnode_changed(&p->de_id); } parent->de_child = child; child->de_parent = parent; - if (save && origin != parent) dvr_entry_save(parent); - if (save && origin != child) dvr_entry_save(child); + if (save && origin != parent) idnode_changed(&parent->de_id); + if (save && origin != child) idnode_changed(&child->de_id); return 1; } @@ -410,7 +410,7 @@ dvr_entry_retention_timer(dvr_entry_t *de) return; } if (save) - dvr_entry_save(de); + idnode_changed(&de->de_id); } if (retention < DVR_RET_ONREMOVE) { @@ -873,7 +873,7 @@ dvr_entry_create_(int enabled, const char *config_uuid, epg_broadcast_t *e, idnode_uuid_as_str(&de->de_id, ubuf), lang_str_get(de->de_title, NULL), DVR_CH_NAME(de), tbuf, creator ?: ""); - dvr_entry_save(de); + idnode_changed(&de->de_id); return de; } @@ -953,7 +953,7 @@ dvr_entry_clone(dvr_entry_t *de) } else { dvr_entry_set_timer(n); } - dvr_entry_save(n); + idnode_changed(&n->de_id); } return n == NULL ? de : n; @@ -1057,7 +1057,7 @@ not_so_good: } else { /* we have already queued similar recordings, mark as resolved */ de->de_dont_rerecord = 1; - dvr_entry_save(de); + idnode_changed(&de->de_id); } return 0; @@ -1389,45 +1389,10 @@ dvr_entry_destroy_by_config(dvr_config_t *cfg, int delconf) if (def) LIST_INSERT_HEAD(&def->dvr_entries, de, de_config_link); if (delconf) - dvr_entry_save(de); - } -} - -/** - * - */ -void -dvr_entry_save(dvr_entry_t *de) -{ - htsmsg_t *m = htsmsg_create_map(), *e, *l, *c, *info; - htsmsg_field_t *f; - char ubuf[UUID_HEX_SIZE]; - const char *filename; - - lock_assert(&global_lock); - - idnode_save(&de->de_id, m); - if (de->de_files) { - l = htsmsg_create_list(); - HTSMSG_FOREACH(f, de->de_files) - if ((e = htsmsg_field_get_map(f)) != NULL) { - filename = htsmsg_get_str(e, "filename"); - info = htsmsg_get_list(e, "info"); - if (filename) { - c = htsmsg_create_map(); - htsmsg_add_str(c, "filename", filename); - if (info) - htsmsg_add_msg(c, "info", htsmsg_copy(info)); - htsmsg_add_msg(l, NULL, c); - } - } - htsmsg_add_msg(m, "files", l); + idnode_changed(&de->de_id); } - hts_settings_save(m, "dvr/log/%s", idnode_uuid_as_str(&de->de_id, ubuf)); - htsmsg_destroy(m); } - /** * */ @@ -1767,7 +1732,7 @@ dvr_event_removed(epg_broadcast_t *e) if (de->de_bcast != e) continue; dvr_entry_assign_broadcast(de, NULL); - dvr_entry_save(de); + idnode_changed(&de->de_id); } } @@ -1921,7 +1886,7 @@ dvr_stop_recording(dvr_entry_t *de, int stopcode, int saveconf, int clone) return; if (saveconf) - dvr_entry_save(de); + idnode_changed(&de->de_id); dvr_entry_retention_timer(de); @@ -2039,16 +2004,44 @@ dvr_entry_purge(dvr_entry_t *de, int delconf) * **************************************************************************/ static void -dvr_entry_class_save(idnode_t *self) +dvr_entry_class_changed(idnode_t *self) { dvr_entry_t *de = (dvr_entry_t *)self; - dvr_entry_save(de); if (dvr_entry_is_valid(de)) dvr_entry_set_timer(de); - htsp_dvr_entry_update(de); } +static htsmsg_t * +dvr_entry_class_save(idnode_t *self, char *filename, size_t fsize) +{ + dvr_entry_t *de = (dvr_entry_t *)self; + htsmsg_t *m = htsmsg_create_map(), *e, *l, *c, *info; + htsmsg_field_t *f; + char ubuf[UUID_HEX_SIZE]; + const char *filename2; + + idnode_save(&de->de_id, m); + if (de->de_files) { + l = htsmsg_create_list(); + HTSMSG_FOREACH(f, de->de_files) + if ((e = htsmsg_field_get_map(f)) != NULL) { + filename2 = htsmsg_get_str(e, "filename"); + info = htsmsg_get_list(e, "info"); + if (filename2) { + c = htsmsg_create_map(); + htsmsg_add_str(c, "filename", filename2); + if (info) + htsmsg_add_msg(c, "info", htsmsg_copy(info)); + htsmsg_add_msg(l, NULL, c); + } + } + htsmsg_add_msg(m, "files", l); + } + snprintf(filename, fsize, "dvr/log/%s", idnode_uuid_as_str(&de->de_id, ubuf)); + return m; +} + static void dvr_entry_class_delete(idnode_t *self) { @@ -2811,6 +2804,7 @@ const idclass_t dvr_entry_class = { .ic_class = "dvrentry", .ic_caption = N_("DVR entry"), .ic_event = "dvrentry", + .ic_changed = dvr_entry_class_changed, .ic_save = dvr_entry_class_save, .ic_get_title = dvr_entry_class_get_title, .ic_delete = dvr_entry_class_delete, diff --git a/src/dvr/dvr_inotify.c b/src/dvr/dvr_inotify.c index 75ceea5fc..0a4d87ce7 100644 --- a/src/dvr/dvr_inotify.c +++ b/src/dvr/dvr_inotify.c @@ -261,7 +261,7 @@ _dvr_inotify_moved if (to) { snprintf(path, sizeof(path), "%s/%s", die->path, to); htsmsg_set_str(m, "filename", path); - dvr_entry_save(de); + idnode_changed(&de->de_id); } else { htsmsg_field_destroy(de->de_files, f); if (htsmsg_is_empty(de->de_files)) diff --git a/src/dvr/dvr_timerec.c b/src/dvr/dvr_timerec.c index bf140a02c..56fb64232 100644 --- a/src/dvr/dvr_timerec.c +++ b/src/dvr/dvr_timerec.c @@ -77,7 +77,7 @@ dvr_timerec_purge_spawn(dvr_timerec_entry_t *dte, int delconf) if (de->de_sched_state == DVR_SCHEDULED) dvr_entry_cancel(de, 0); else - dvr_entry_save(de); + idnode_changed(&de->de_id); } } } @@ -209,10 +209,8 @@ dvr_timerec_create_htsp(htsmsg_t *conf) dte = dvr_timerec_create(NULL, conf); htsmsg_destroy(conf); - if (dte) { - dvr_timerec_save(dte); - dvr_timerec_check(dte); - } + if (dte) + idnode_changed(&dte->dte_id); return dte; } @@ -221,9 +219,7 @@ void dvr_timerec_update_htsp (dvr_timerec_entry_t *dte, htsmsg_t *conf) { idnode_update(&dte->dte_id, conf); - dvr_timerec_save(dte); - dvr_timerec_check(dte); - htsp_timerec_entry_update(dte); + idnode_changed(&dte->dte_id); tvhlog(LOG_INFO, "timerec", "\"%s\" on \"%s\": Updated", dte->dte_title ? dte->dte_title : "", (dte->dte_channel && dte->dte_channel->ch_name) ? dte->dte_channel->ch_name : "any channel"); } @@ -262,35 +258,29 @@ timerec_entry_destroy(dvr_timerec_entry_t *dte, int delconf) free(dte); } -/** - * - */ -void -dvr_timerec_save(dvr_timerec_entry_t *dte) -{ - htsmsg_t *m = htsmsg_create_map(); - char ubuf[UUID_HEX_SIZE]; - - lock_assert(&global_lock); - - idnode_save(&dte->dte_id, m); - hts_settings_save(m, "dvr/timerec/%s", idnode_uuid_as_str(&dte->dte_id, ubuf)); - htsmsg_destroy(m); -} - /* ************************************************************************** * DVR Autorec Entry Class definition * **************************************************************************/ static void -dvr_timerec_entry_class_save(idnode_t *self) +dvr_timerec_entry_class_changed(idnode_t *self) { dvr_timerec_entry_t *dte = (dvr_timerec_entry_t *)self; - dvr_timerec_save(dte); dvr_timerec_check(dte); htsp_timerec_entry_update(dte); } +static htsmsg_t * +dvr_timerec_entry_class_save(idnode_t *self, char *filename, size_t fsize) +{ + dvr_timerec_entry_t *dte = (dvr_timerec_entry_t *)self; + htsmsg_t *m = htsmsg_create_map(); + char ubuf[UUID_HEX_SIZE]; + idnode_save(&dte->dte_id, m); + snprintf(filename, fsize, "dvr/timerec/%s", idnode_uuid_as_str(&dte->dte_id, ubuf)); + return m; +} + static void dvr_timerec_entry_class_delete(idnode_t *self) { @@ -527,6 +517,7 @@ const idclass_t dvr_timerec_entry_class = { .ic_class = "dvrtimerec", .ic_caption = N_("DVR time record entry"), .ic_event = "dvrtimerec", + .ic_changed = dvr_timerec_entry_class_changed, .ic_save = dvr_timerec_entry_class_save, .ic_get_title = dvr_timerec_entry_class_get_title, .ic_delete = dvr_timerec_entry_class_delete, @@ -775,7 +766,7 @@ timerec_destroy_by_config(dvr_config_t *kcfg, int delconf) LIST_INSERT_HEAD(&cfg->dvr_timerec_entries, dte, dte_config_link); dte->dte_config = cfg; if (delconf) - dvr_timerec_save(dte); + idnode_changed(&dte->dte_id); } } diff --git a/src/dvr/dvr_vfsmgr.c b/src/dvr/dvr_vfsmgr.c index ac323fb99..afe03f157 100644 --- a/src/dvr/dvr_vfsmgr.c +++ b/src/dvr/dvr_vfsmgr.c @@ -267,7 +267,7 @@ dvr_disk_space_cleanup(dvr_config_t *cfg) dvr_entry_destroy(oldest, 1); // also delete database entry } else { if (dvr_entry_delete(oldest)) // delete actual file - dvr_entry_save(oldest); + idnode_changed(&oldest->de_id); } } else { tvhlog(LOG_WARNING, "dvr", "%s \"until space needed\" recordings found for config \"%s\", you are running out of disk space very soon!", diff --git a/src/epggrab.c b/src/epggrab.c index c2aa44cc8..8474c6b1b 100644 --- a/src/epggrab.c +++ b/src/epggrab.c @@ -185,14 +185,23 @@ static void _epggrab_load ( void ) xmltv_load(); } -void epggrab_save ( void ) -{ - epggrab_module_t *mod; - htsmsg_t *m, *a; +/* ************************************************************************** + * Class + * *************************************************************************/ +static void +epggrab_class_changed(idnode_t *self) +{ /* Register */ epggrab_confver++; pthread_cond_signal(&epggrab_cond); +} + +static htsmsg_t * +epggrab_class_save(idnode_t *self, char *filename, size_t fsize) +{ + epggrab_module_t *mod; + htsmsg_t *m, *a; /* Save */ m = htsmsg_create_map(); @@ -205,17 +214,8 @@ void epggrab_save ( void ) htsmsg_add_msg(a, mod->id, m); } htsmsg_add_msg(m, "modules", a); - hts_settings_save(m, "epggrab/config"); - htsmsg_destroy(m); -} - -/* ************************************************************************** - * Class - * *************************************************************************/ - -static void epggrab_class_save(idnode_t *self) -{ - epggrab_save(); + snprintf(filename, fsize, "epggrab/config"); + return m; } epggrab_conf_t epggrab_conf = { @@ -243,6 +243,7 @@ const idclass_t epggrab_class = { .ic_caption = N_("EPG grabber configuration"), .ic_event = "epggrab", .ic_perm_def = ACCESS_ADMIN, + .ic_changed = epggrab_class_changed, .ic_save = epggrab_class_save, .ic_groups = (const property_group_t[]) { { diff --git a/src/epggrab.h b/src/epggrab.h index 17bbc2065..73e969588 100644 --- a/src/epggrab.h +++ b/src/epggrab.h @@ -310,7 +310,6 @@ void epggrab_ota_trigger ( int secs ); */ void epggrab_init ( void ); void epggrab_done ( void ); -void epggrab_save ( void ); void epggrab_ota_init ( void ); void epggrab_ota_post ( void ); void epggrab_ota_shutdown ( void ); diff --git a/src/epggrab/channel.c b/src/epggrab/channel.c index 0396319c6..865773f9c 100644 --- a/src/epggrab/channel.c +++ b/src/epggrab/channel.c @@ -171,10 +171,10 @@ epggrab_channel_link ( epggrab_channel_t *ec, channel_t *ch, void *origin ) if (ec->icon && epggrab_conf.channel_reicon) save |= channel_set_icon(ch, ec->icon); if (save) - channel_save(ch); + idnode_changed(&ch->ch_id); if (origin == NULL) - epggrab_channel_save(ec); + idnode_changed(&ec->idnode); return 1; } @@ -198,7 +198,7 @@ int epggrab_channel_set_name ( epggrab_channel_t *ec, const char *name ) LIST_FOREACH(ilm, &ec->channels, ilm_in1_link) { ch = (channel_t *)ilm->ilm_in2; if (channel_set_name(ch, name)) - channel_save(ch); + idnode_changed(&ch->ch_id); } } save = 1; @@ -224,7 +224,7 @@ int epggrab_channel_set_icon ( epggrab_channel_t *ec, const char *icon ) LIST_FOREACH(ilm, &ec->channels, ilm_in1_link) { ch = (channel_t *)ilm->ilm_in2; if (channel_set_icon(ch, icon)) - channel_save(ch); + idnode_changed(&ch->ch_id); } } save = 1; @@ -250,7 +250,7 @@ int epggrab_channel_set_number ( epggrab_channel_t *ec, int major, int minor ) if (channel_set_number(ch, lcn / CHANNEL_SPLIT, lcn % CHANNEL_SPLIT)) - channel_save(ch); + idnode_changed(&ch->ch_id); } } save = 1; @@ -303,7 +303,7 @@ void epggrab_channel_updated ( epggrab_channel_t *ec ) epggrab_channel_autolink(ec); /* Save */ - epggrab_channel_save(ec); + idnode_changed(&ec->idnode); } /* ID comparison */ @@ -387,16 +387,6 @@ epggrab_channel_t *epggrab_channel_find return ec; } -void epggrab_channel_save( epggrab_channel_t *ec ) -{ - htsmsg_t *m = htsmsg_create_map(); - char ubuf[UUID_HEX_SIZE]; - idnode_save(&ec->idnode, m); - hts_settings_save(m, "epggrab/%s/channels/%s", - ec->mod->saveid, idnode_uuid_as_str(&ec->idnode, ubuf)); - htsmsg_destroy(m); -} - void epggrab_channel_destroy( epggrab_channel_t *ec, int delconf, int rb_remove ) { char ubuf[UUID_HEX_SIZE]; @@ -538,10 +528,16 @@ epggrab_channel_class_get_title(idnode_t *self, const char *lang) return prop_sbuf; } -static void -epggrab_channel_class_save(idnode_t *self) +static htsmsg_t * +epggrab_channel_class_save(idnode_t *self, char *filename, size_t fsize) { - epggrab_channel_save((epggrab_channel_t *)self); + epggrab_channel_t *ec = (epggrab_channel_t *)self; + htsmsg_t *m = htsmsg_create_map(); + char ubuf[UUID_HEX_SIZE]; + idnode_save(&ec->idnode, m); + snprintf(filename, fsize, "epggrab/%s/channels/%s", + ec->mod->saveid, idnode_uuid_as_str(&ec->idnode, ubuf)); + return m; } static void diff --git a/src/epggrab/module.c b/src/epggrab/module.c index 3f607d58c..833157018 100644 --- a/src/epggrab/module.c +++ b/src/epggrab/module.c @@ -84,11 +84,12 @@ static const char *epggrab_mod_class_title(idnode_t *self, const char *lang) return prop_sbuf; } -static void epggrab_mod_class_save(idnode_t *self) +static void +epggrab_mod_class_changed(idnode_t *self) { epggrab_module_t *mod = (epggrab_module_t *)self; epggrab_activate_module(mod, mod->enabled); - epggrab_save(); + idnode_changed(&epggrab_conf.idnode); } static const void *epggrab_mod_class_type_get(void *o) @@ -109,7 +110,7 @@ const idclass_t epggrab_mod_class = { .ic_event = "epggrab_mod", .ic_perm_def = ACCESS_ADMIN, .ic_get_title = epggrab_mod_class_title, - .ic_save = epggrab_mod_class_save, + .ic_changed = epggrab_mod_class_changed, .ic_groups = (const property_group_t[]) { { .name = N_("Settings"), diff --git a/src/esfilter.c b/src/esfilter.c index 7f9031ed4..6273781a1 100644 --- a/src/esfilter.c +++ b/src/esfilter.c @@ -26,8 +26,6 @@ struct esfilter_entry_queue esfilters[ESF_CLASS_LAST + 1]; -static void esfilter_class_save(idnode_t *self); - /* * Class masks */ @@ -128,7 +126,7 @@ esfilter_reindex(esfilter_class_t cls) TAILQ_FOREACH(esf, &esfilters[cls], esf_link) if (esf->esf_save) { esf->esf_save = 0; - esfilter_class_save((idnode_t *)esf); + idnode_changed(&esf->esf_id); } } @@ -185,7 +183,7 @@ esfilter_create if (!conf) esfilter_reindex(esf->esf_class); if (save) - esfilter_class_save((idnode_t *)esf); + idnode_changed(&esf->esf_id); return esf; } @@ -205,14 +203,14 @@ esfilter_delete(esfilter_t *esf, int delconf) * Class functions */ -static void -esfilter_class_save(idnode_t *self) +static htsmsg_t * +esfilter_class_save(idnode_t *self, char *filename, size_t fsize) { htsmsg_t *c = htsmsg_create_map(); char ubuf[UUID_HEX_SIZE]; idnode_save(self, c); - hts_settings_save(c, "esfilter/%s", idnode_uuid_as_str(self, ubuf)); - htsmsg_destroy(c); + snprintf(filename, fsize, "esfilter/%s", idnode_uuid_as_str(self, ubuf)); + return c; } static const char * diff --git a/src/idnode.c b/src/idnode.c index 0fe0eaddf..972ab2f57 100644 --- a/src/idnode.c +++ b/src/idnode.c @@ -161,6 +161,11 @@ idnode_unlink(idnode_t *in) RB_REMOVE(in->in_domain, in, in_domain_link); tvhtrace("idnode", "unlink node %s", idnode_uuid_as_str(in, ubuf)); idnode_notify(in, "delete"); + + if (in->in_save) { + TAILQ_REMOVE(&idnodes_save, in->in_save, ise_link); + in->in_save = NULL; + } } /** @@ -1067,18 +1072,30 @@ idnode_class_write_values } static void -idnode_savefn ( idnode_t *self ) +idnode_changedfn ( idnode_t *self ) { const idclass_t *idc = self->in_class; while (idc) { - if (idc->ic_save) { - idc->ic_save(self); + if (idc->ic_changed) { + idc->ic_changed(self); break; } idc = idc->ic_super; } } +static htsmsg_t * +idnode_savefn ( idnode_t *self, char *filename, size_t fsize ) +{ + const idclass_t *idc = self->in_class; + while (idc) { + if (idc->ic_save) + return idc->ic_save(self, filename, fsize); + idc = idc->ic_super; + } + return NULL; +} + static void idnode_save_queue ( idnode_t *self ) { @@ -1100,8 +1117,10 @@ idnode_write0 ( idnode_t *self, htsmsg_t *c, int optmask, int dosave ) int save = 0; const idclass_t *idc = self->in_class; save = idnode_class_write_values(self, idc, c, optmask); - if ((idc->ic_flags & IDCLASS_ALWAYS_SAVE) != 0 || (save && dosave)) + if ((idc->ic_flags & IDCLASS_ALWAYS_SAVE) != 0 || (save && dosave)) { + idnode_changedfn(self); idnode_save_queue(self); + } if (dosave) idnode_notify_changed(self); // Note: always output event if "dosave", reason is that UI updates on @@ -1644,6 +1663,8 @@ static void * save_thread ( void *aux ) { idnode_save_t *ise; + htsmsg_t *m; + char filename[PATH_MAX]; tvhtread_renice(15); @@ -1654,17 +1675,29 @@ save_thread ( void *aux ) pthread_cond_wait(&save_cond, &global_lock); continue; } - idnode_savefn(ise->ise_node); + 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); } while ((ise = TAILQ_FIRST(&idnodes_save)) != NULL) { - idnode_savefn(ise->ise_node); + 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_unlock(&global_lock); diff --git a/src/idnode.h b/src/idnode.h index 28fe3a892..8a032d852 100644 --- a/src/idnode.h +++ b/src/idnode.h @@ -73,7 +73,8 @@ 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_save) (idnode_t *self); + void (*ic_changed) (idnode_t *self); + htsmsg_t *(*ic_save) (idnode_t *self, char *filename, size_t fsize); void (*ic_delete) (idnode_t *self); void (*ic_moveup) (idnode_t *self); void (*ic_movedown) (idnode_t *self); diff --git a/src/imagecache.c b/src/imagecache.c index 2ed82b6dd..4ad03b8f5 100644 --- a/src/imagecache.c +++ b/src/imagecache.c @@ -69,7 +69,7 @@ struct imagecache_config imagecache_conf = { .idnode.in_class = &imagecache_class, }; -static void imagecache_save(idnode_t *self); +static htsmsg_t *imagecache_save(idnode_t *self, char *filename, size_t fsize); const idclass_t imagecache_class = { .ic_snode = (idnode_t *)&imagecache_conf, @@ -507,14 +507,14 @@ imagecache_done ( void ) /* * Save */ -static void -imagecache_save ( idnode_t *self ) +static htsmsg_t * +imagecache_save ( idnode_t *self, char *filename, size_t fsize ) { htsmsg_t *c = htsmsg_create_map(); idnode_save(&imagecache_conf.idnode, c); - hts_settings_save(c, "imagecache/config"); - htsmsg_destroy(c); + snprintf(filename, fsize, "imagecache/config"); pthread_cond_broadcast(&imagecache_cond); + return c; } /* diff --git a/src/input/mpegts.h b/src/input/mpegts.h index 663b9a6dd..f644e3913 100644 --- a/src/input/mpegts.h +++ b/src/input/mpegts.h @@ -327,7 +327,7 @@ struct mpegts_network */ void (*mn_delete) (mpegts_network_t*, int delconf); void (*mn_display_name) (mpegts_network_t*, char *buf, size_t len); - void (*mn_config_save) (mpegts_network_t*); + htsmsg_t * (*mn_config_save) (mpegts_network_t*, char *filename, size_t fsize); mpegts_mux_t* (*mn_create_mux) (mpegts_network_t*, void *origin, uint16_t onid, uint16_t tsid, void *conf, int force); @@ -487,7 +487,7 @@ struct mpegts_mux */ void (*mm_delete) (mpegts_mux_t *mm, int delconf); - void (*mm_config_save) (mpegts_mux_t *mm); + htsmsg_t *(*mm_config_save) (mpegts_mux_t *mm, char *filename, size_t fsize); void (*mm_display_name) (mpegts_mux_t*, char *buf, size_t len); int (*mm_is_enabled) (mpegts_mux_t *mm); void (*mm_stop) (mpegts_mux_t *mm, int force, int reason); diff --git a/src/input/mpegts/dvb_psi.c b/src/input/mpegts/dvb_psi.c index cfa198187..d8b1f7e31 100644 --- a/src/input/mpegts/dvb_psi.c +++ b/src/input/mpegts/dvb_psi.c @@ -461,7 +461,7 @@ dvb_desc_service_list if (bi) dvb_bat_find_service(bi, s, 0, UINT_MAX); if (save) - s->s_config_save((service_t*)s); + idnode_changed(&s->s_id); } } return 0; @@ -493,7 +493,7 @@ dvb_desc_local_channel s->s_dvb_channel_num != lcn) { s->s_dvb_channel_dtag = dtag; s->s_dvb_channel_num = lcn; - s->s_config_save((service_t*)s); + idnode_changed(&s->s_id); service_refresh_channel((service_t*)s); } } @@ -1398,9 +1398,9 @@ dvb_nit_callback tvhdebug(mt->mt_name, "network %04X (%d) [%s]", nbid, nbid, name); save |= mpegts_network_set_network_name(mn, name); if (save) - mn->mn_config_save(mn); + idnode_changed(&mn->mn_id); if (mpegts_mux_set_network_name(mm, name)) - mm->mm_config_save(mm); + idnode_changed(&mm->mm_id); } /* Transport length */ @@ -1734,7 +1734,7 @@ atsc_vct_callback /* Save */ if (save) - s->s_config_save((service_t*)s); + idnode_changed(&s->s_id); } /* Move on */ diff --git a/src/input/mpegts/fastscan.c b/src/input/mpegts/fastscan.c index 14b3ba64b..998955840 100644 --- a/src/input/mpegts/fastscan.c +++ b/src/input/mpegts/fastscan.c @@ -123,8 +123,10 @@ dvb_fastscan_create(htsmsg_t *e) if (bq == NULL) goto fail; bq->bq_shield = 1; - if (bq->bq_saveflag) - bouquet_save(bq, 1); + if (bq->bq_saveflag) { + bq->bq_saveflag = 0; + idnode_changed(&bq->bq_id); + } fs = RB_INSERT_SORTED(&fastscan_rb, fastscan_rb_skel, link, _fs_cmp); if (!fs) { diff --git a/src/input/mpegts/iptv/iptv.c b/src/input/mpegts/iptv/iptv.c index 05882a892..9b47da8ee 100644 --- a/src/input/mpegts/iptv/iptv.c +++ b/src/input/mpegts/iptv/iptv.c @@ -899,15 +899,15 @@ iptv_network_mux_class ( mpegts_network_t *mm ) return &iptv_mux_class; } -static void -iptv_network_config_save ( mpegts_network_t *mn ) +static htsmsg_t * +iptv_network_config_save ( mpegts_network_t *mn, char *filename, size_t fsize ) { htsmsg_t *c = htsmsg_create_map(); char ubuf[UUID_HEX_SIZE]; idnode_save(&mn->mn_id, c); - hts_settings_save(c, "input/iptv/networks/%s/config", - idnode_uuid_as_str(&mn->mn_id, ubuf)); - htsmsg_destroy(c); + snprintf(filename, fsize, "input/iptv/networks/%s/config", + idnode_uuid_as_str(&mn->mn_id, ubuf)); + return c; } iptv_network_t * diff --git a/src/input/mpegts/iptv/iptv_auto.c b/src/input/mpegts/iptv/iptv_auto.c index 8378f27ab..2a4b80bf2 100644 --- a/src/input/mpegts/iptv/iptv_auto.c +++ b/src/input/mpegts/iptv/iptv_auto.c @@ -277,7 +277,7 @@ skip_url: htsmsg_destroy(conf); if (im) { - im->mm_config_save((mpegts_mux_t *)im); + idnode_changed(&im->mm_id); (*total)++; (*count)++; } diff --git a/src/input/mpegts/iptv/iptv_mux.c b/src/input/mpegts/iptv/iptv_mux.c index d6e83c3a0..94ab7315e 100644 --- a/src/input/mpegts/iptv/iptv_mux.c +++ b/src/input/mpegts/iptv/iptv_mux.c @@ -261,17 +261,17 @@ const idclass_t iptv_mux_class = } }; -static void -iptv_mux_config_save ( mpegts_mux_t *mm ) +static htsmsg_t * +iptv_mux_config_save ( mpegts_mux_t *mm, char *filename, size_t fsize ) { char ubuf1[UUID_HEX_SIZE]; char ubuf2[UUID_HEX_SIZE]; htsmsg_t *c = htsmsg_create_map(); mpegts_mux_save(mm, c); - hts_settings_save(c, "input/iptv/networks/%s/muxes/%s/config", - idnode_uuid_as_str(&mm->mm_network->mn_id, ubuf1), - idnode_uuid_as_str(&mm->mm_id, ubuf2)); - htsmsg_destroy(c); + snprintf(filename, fsize, "input/iptv/networks/%s/muxes/%s/config", + idnode_uuid_as_str(&mm->mm_network->mn_id, ubuf1), + idnode_uuid_as_str(&mm->mm_id, ubuf2)); + return c; } static void diff --git a/src/input/mpegts/iptv/iptv_service.c b/src/input/mpegts/iptv/iptv_service.c index 54a80c832..5b5cc40b0 100644 --- a/src/input/mpegts/iptv/iptv_service.c +++ b/src/input/mpegts/iptv/iptv_service.c @@ -22,8 +22,8 @@ extern const idclass_t mpegts_service_class; -static void -iptv_service_config_save ( service_t *s ) +static htsmsg_t * +iptv_service_config_save ( service_t *s, char *filename, size_t fsize ) { mpegts_mux_t *mm = ((mpegts_service_t *)s)->s_dvb_mux; htsmsg_t *c = htsmsg_create_map(); @@ -32,11 +32,11 @@ iptv_service_config_save ( service_t *s ) char ubuf2[UUID_HEX_SIZE]; service_save(s, c); - hts_settings_save(c, "input/iptv/networks/%s/muxes/%s/services/%s", - idnode_uuid_as_str(&mm->mm_network->mn_id, ubuf0), - idnode_uuid_as_str(&mm->mm_id, ubuf1), - idnode_uuid_as_str(&s->s_id, ubuf2)); - htsmsg_destroy(c); + snprintf(filename, fsize, "input/iptv/networks/%s/muxes/%s/services/%s", + idnode_uuid_as_str(&mm->mm_network->mn_id, ubuf0), + idnode_uuid_as_str(&mm->mm_id, ubuf1), + idnode_uuid_as_str(&s->s_id, ubuf2)); + return c; } static void diff --git a/src/input/mpegts/linuxdvb/linuxdvb_adapter.c b/src/input/mpegts/linuxdvb/linuxdvb_adapter.c index b8e6fe464..4988c55b9 100644 --- a/src/input/mpegts/linuxdvb/linuxdvb_adapter.c +++ b/src/input/mpegts/linuxdvb/linuxdvb_adapter.c @@ -45,11 +45,38 @@ * DVB Adapter * **************************************************************************/ -static void -linuxdvb_adapter_class_save ( idnode_t *in ) +static htsmsg_t * +linuxdvb_adapter_class_save ( idnode_t *in, char *filename, size_t fsize ) { linuxdvb_adapter_t *la = (linuxdvb_adapter_t*)in; - linuxdvb_adapter_save(la); + htsmsg_t *m, *l; + linuxdvb_frontend_t *lfe; +#if ENABLE_LINUXDVB_CA + linuxdvb_ca_t *lca; +#endif + char ubuf[UUID_HEX_SIZE]; + + m = htsmsg_create_map(); + idnode_save(&la->th_id, m); + + /* Frontends */ + l = htsmsg_create_map(); + LIST_FOREACH(lfe, &la->la_frontends, lfe_link) + linuxdvb_frontend_save(lfe, l); + htsmsg_add_msg(m, "frontends", l); + + /* CAs */ +#if ENABLE_LINUXDVB_CA + l = htsmsg_create_map(); + LIST_FOREACH(lca, &la->la_ca_devices, lca_link) + linuxdvb_ca_save(lca, l); + htsmsg_add_msg(m, "ca_devices", l); +#endif + + /* Save */ + snprintf(filename, fsize, "input/linuxdvb/adapters/%s", + idnode_uuid_as_str(&la->th_id, ubuf)); + return m; } static idnode_set_t * @@ -98,42 +125,6 @@ const idclass_t linuxdvb_adapter_class = } }; -/* - * Save data - */ -void -linuxdvb_adapter_save ( linuxdvb_adapter_t *la ) -{ - htsmsg_t *m, *l; - linuxdvb_frontend_t *lfe; -#if ENABLE_LINUXDVB_CA - linuxdvb_ca_t *lca; -#endif - char ubuf[UUID_HEX_SIZE]; - - m = htsmsg_create_map(); - idnode_save(&la->th_id, m); - - /* Frontends */ - l = htsmsg_create_map(); - LIST_FOREACH(lfe, &la->la_frontends, lfe_link) - linuxdvb_frontend_save(lfe, l); - htsmsg_add_msg(m, "frontends", l); - - /* CAs */ -#if ENABLE_LINUXDVB_CA - l = htsmsg_create_map(); - LIST_FOREACH(lca, &la->la_ca_devices, lca_link) - linuxdvb_ca_save(lca, l); - htsmsg_add_msg(m, "ca_devices", l); -#endif - - /* Save */ - hts_settings_save(m, "input/linuxdvb/adapters/%s", - idnode_uuid_as_str(&la->th_id, ubuf)); - htsmsg_destroy(m); -} - /* * Check if enabled */ @@ -488,7 +479,7 @@ linuxdvb_adapter_add ( const char *path ) /* Save configuration */ if (save && la) - linuxdvb_adapter_save(la); + linuxdvb_adapter_changed(la); } static void diff --git a/src/input/mpegts/linuxdvb/linuxdvb_ca.c b/src/input/mpegts/linuxdvb/linuxdvb_ca.c index adcc8796a..517513f68 100644 --- a/src/input/mpegts/linuxdvb/linuxdvb_ca.c +++ b/src/input/mpegts/linuxdvb/linuxdvb_ca.c @@ -115,10 +115,10 @@ ciplus13_app_ai_data_rate_info(linuxdvb_ca_t *lca, ciplus13_data_rate_t rate) } static void -linuxdvb_ca_class_save ( idnode_t *in ) +linuxdvb_ca_class_changed ( idnode_t *in ) { linuxdvb_adapter_t *la = ((linuxdvb_ca_t*)in)->lca_adapter; - linuxdvb_adapter_save(la); + linuxdvb_adapter_changed(la); } static void @@ -179,7 +179,7 @@ const idclass_t linuxdvb_ca_class = { .ic_class = "linuxdvb_ca", .ic_caption = N_("Linux DVB CA"), - .ic_save = linuxdvb_ca_class_save, + .ic_changed = linuxdvb_ca_class_changed, .ic_get_title = linuxdvb_ca_class_get_title, .ic_properties = (const property_t[]) { { diff --git a/src/input/mpegts/linuxdvb/linuxdvb_frontend.c b/src/input/mpegts/linuxdvb/linuxdvb_frontend.c index 3303e8751..805c52d4d 100644 --- a/src/input/mpegts/linuxdvb/linuxdvb_frontend.c +++ b/src/input/mpegts/linuxdvb/linuxdvb_frontend.c @@ -45,10 +45,10 @@ linuxdvb_frontend_input_thread ( void *aux ); * *************************************************************************/ static void -linuxdvb_frontend_class_save ( idnode_t *in ) +linuxdvb_frontend_class_changed ( idnode_t *in ) { linuxdvb_adapter_t *la = ((linuxdvb_frontend_t*)in)->lfe_adapter; - linuxdvb_adapter_save(la); + linuxdvb_adapter_changed(la); } const idclass_t linuxdvb_frontend_class = @@ -56,7 +56,7 @@ const idclass_t linuxdvb_frontend_class = .ic_super = &mpegts_input_class, .ic_class = "linuxdvb_frontend", .ic_caption = N_("Linux DVB frontend"), - .ic_save = linuxdvb_frontend_class_save, + .ic_changed = linuxdvb_frontend_class_changed, .ic_properties = (const property_t[]) { { .type = PT_STR, @@ -1836,7 +1836,7 @@ linuxdvb_frontend_wizard_set( tvh_input_t *ti, htsmsg_t *conf, const char *lang } if (linuxdvb_frontend_wizard_network(lfe)) mpegts_input_set_enabled((mpegts_input_t *)lfe, 1); - linuxdvb_adapter_save(lfe->lfe_adapter); + linuxdvb_adapter_changed(lfe->lfe_adapter); } else { htsmsg_destroy(nlist); } diff --git a/src/input/mpegts/linuxdvb/linuxdvb_private.h b/src/input/mpegts/linuxdvb/linuxdvb_private.h index 8d824215f..09b5bcf09 100644 --- a/src/input/mpegts/linuxdvb/linuxdvb_private.h +++ b/src/input/mpegts/linuxdvb/linuxdvb_private.h @@ -356,7 +356,8 @@ void linuxdvb_adapter_init ( void ); void linuxdvb_adapter_done ( void ); -void linuxdvb_adapter_save ( linuxdvb_adapter_t *la ); +static inline void linuxdvb_adapter_changed ( linuxdvb_adapter_t *la ) + { idnode_changed(&la->th_id); } int linuxdvb_adapter_current_weight ( linuxdvb_adapter_t *la ); diff --git a/src/input/mpegts/linuxdvb/linuxdvb_satconf.c b/src/input/mpegts/linuxdvb/linuxdvb_satconf.c index 34629afd4..e72f82843 100644 --- a/src/input/mpegts/linuxdvb/linuxdvb_satconf.c +++ b/src/input/mpegts/linuxdvb/linuxdvb_satconf.c @@ -138,12 +138,12 @@ linuxdvb_satconf_class_get_title ( idnode_t *p, const char *lang ) } static void -linuxdvb_satconf_class_save ( idnode_t *s ) +linuxdvb_satconf_class_changed ( idnode_t *s ) { linuxdvb_satconf_t *ls = (linuxdvb_satconf_t*)s; linuxdvb_frontend_t *lfe = (linuxdvb_frontend_t*)ls->ls_frontend; linuxdvb_adapter_t *la = lfe->lfe_adapter; - linuxdvb_adapter_save(la); + linuxdvb_adapter_changed(la); } static const void * @@ -214,7 +214,7 @@ const idclass_t linuxdvb_satconf_class = .ic_caption = N_("DVB-S satellite configuration"), .ic_event = "linuxdvb_satconf", .ic_get_title = linuxdvb_satconf_class_get_title, - .ic_save = linuxdvb_satconf_class_save, + .ic_changed = linuxdvb_satconf_class_changed, .ic_properties = (const property_t[]) { { .type = PT_BOOL, @@ -1302,10 +1302,10 @@ linuxdvb_satconf_ele_class_get_childs ( idnode_t *o ) } static void -linuxdvb_satconf_ele_class_save ( idnode_t *in ) +linuxdvb_satconf_ele_class_changed ( idnode_t *in ) { linuxdvb_satconf_ele_t *lse = (linuxdvb_satconf_ele_t*)in; - linuxdvb_satconf_class_save(&lse->lse_parent->ls_id); + linuxdvb_satconf_class_changed(&lse->lse_parent->ls_id); } const idclass_t linuxdvb_satconf_ele_class = @@ -1315,7 +1315,7 @@ const idclass_t linuxdvb_satconf_ele_class = .ic_event = "linuxdvb_satconf_ele", .ic_get_title = linuxdvb_satconf_ele_class_get_title, .ic_get_childs = linuxdvb_satconf_ele_class_get_childs, - .ic_save = linuxdvb_satconf_ele_class_save, + .ic_changed = linuxdvb_satconf_ele_class_changed, .ic_properties = (const property_t[]) { { .type = PT_BOOL, @@ -1477,11 +1477,11 @@ linuxdvb_diseqc_class_get_title ( idnode_t *o, const char *lang ) } static void -linuxdvb_diseqc_class_save ( idnode_t *o ) +linuxdvb_diseqc_class_changed ( idnode_t *o ) { linuxdvb_diseqc_t *ld = (linuxdvb_diseqc_t*)o; if (ld->ld_satconf) - linuxdvb_satconf_ele_class_save(&ld->ld_satconf->lse_id); + linuxdvb_satconf_ele_class_changed(&ld->ld_satconf->lse_id); } const idclass_t linuxdvb_diseqc_class = @@ -1490,7 +1490,7 @@ const idclass_t linuxdvb_diseqc_class = .ic_caption = N_("DiseqC"), .ic_event = "linuxdvb_diseqc", .ic_get_title = linuxdvb_diseqc_class_get_title, - .ic_save = linuxdvb_diseqc_class_save, + .ic_changed = linuxdvb_diseqc_class_changed, }; linuxdvb_diseqc_t * diff --git a/src/input/mpegts/mpegts_mux.c b/src/input/mpegts/mpegts_mux.c index c392985d5..44c66a6d9 100644 --- a/src/input/mpegts/mpegts_mux.c +++ b/src/input/mpegts/mpegts_mux.c @@ -288,11 +288,13 @@ mpegts_mux_instance_weight ( mpegts_mux_instance_t *mmi ) * Class definition * ***************************************************************************/ -static void -mpegts_mux_class_save ( idnode_t *self ) +static htsmsg_t * +mpegts_mux_class_save ( idnode_t *self, char *filename, size_t fsize ) { mpegts_mux_t *mm = (mpegts_mux_t*)self; - if (mm->mm_config_save) mm->mm_config_save(mm); + if (mm->mm_config_save) + return mm->mm_config_save(mm, filename, fsize); + return NULL; } static void @@ -696,9 +698,10 @@ mpegts_mux_delete ( mpegts_mux_t *mm, int delconf ) free(mm); } -static void -mpegts_mux_config_save ( mpegts_mux_t *mm ) +static htsmsg_t * +mpegts_mux_config_save ( mpegts_mux_t *mm, char *filename, size_t fsize ) { + return NULL; } static int @@ -1189,8 +1192,7 @@ mpegts_mux_set_onid ( mpegts_mux_t *mm, uint16_t onid ) return 0; mm->mm_onid = onid; mpegts_mux_nice_name(mm, buf, sizeof(buf)); - mm->mm_config_save(mm); - idnode_notify_changed(&mm->mm_id); + idnode_changed(&mm->mm_id); return 1; } @@ -1202,13 +1204,12 @@ mpegts_mux_set_tsid ( mpegts_mux_t *mm, uint16_t tsid, int force ) if (!force && mm->mm_tsid) return 0; mm->mm_tsid = tsid; - mm->mm_config_save(mm); if (tvhtrace_enabled()) { char buf[256]; mpegts_mux_nice_name(mm, buf, sizeof(buf)); tvhtrace("mpegts", "%s - set tsid %04X (%d)", buf, tsid, tsid); } - idnode_notify_changed(&mm->mm_id); + idnode_changed(&mm->mm_id); return 1; } @@ -1218,13 +1219,12 @@ mpegts_mux_set_crid_authority ( mpegts_mux_t *mm, const char *defauth ) if (defauth && !strcmp(defauth, mm->mm_crid_authority ?: "")) return 0; tvh_str_update(&mm->mm_crid_authority, defauth); - mm->mm_config_save(mm); if (tvhtrace_enabled()) { char buf[256]; mpegts_mux_nice_name(mm, buf, sizeof(buf)); tvhtrace("mpegts", "%s - set crid authority %s", buf, defauth); } - idnode_notify_changed(&mm->mm_id); + idnode_changed(&mm->mm_id); return 1; } diff --git a/src/input/mpegts/mpegts_mux_dvb.c b/src/input/mpegts/mpegts_mux_dvb.c index c10034ed5..88c1ef325 100644 --- a/src/input/mpegts/mpegts_mux_dvb.c +++ b/src/input/mpegts/mpegts_mux_dvb.c @@ -896,17 +896,17 @@ const idclass_t dvb_mux_dab_class = * Class methods * *************************************************************************/ -static void -dvb_mux_config_save ( mpegts_mux_t *mm ) +static htsmsg_t * +dvb_mux_config_save ( mpegts_mux_t *mm, char *filename, size_t fsize ) { char ubuf1[UUID_HEX_SIZE]; char ubuf2[UUID_HEX_SIZE]; htsmsg_t *c = htsmsg_create_map(); mpegts_mux_save(mm, c); - hts_settings_save(c, "input/dvb/networks/%s/muxes/%s/config", - idnode_uuid_as_str(&mm->mm_network->mn_id, ubuf1), - idnode_uuid_as_str(&mm->mm_id, ubuf2)); - htsmsg_destroy(c); + snprintf(filename, fsize, "input/dvb/networks/%s/muxes/%s/config", + idnode_uuid_as_str(&mm->mm_network->mn_id, ubuf1), + idnode_uuid_as_str(&mm->mm_id, ubuf2)); + return c; } static void diff --git a/src/input/mpegts/mpegts_mux_sched.c b/src/input/mpegts/mpegts_mux_sched.c index fc1aa5353..1a20181bf 100644 --- a/src/input/mpegts/mpegts_mux_sched.c +++ b/src/input/mpegts/mpegts_mux_sched.c @@ -60,15 +60,22 @@ mpegts_mux_sched_set_timer ( mpegts_mux_sched_t *mms ) } static void -mpegts_mux_sched_class_save ( idnode_t *in ) +mpegts_mux_sched_class_changed ( idnode_t *in ) { mpegts_mux_sched_t *mms = (mpegts_mux_sched_t*)in; /* Update timer */ mpegts_mux_sched_set_timer(mms); +} - /* Save */ - mpegts_mux_sched_save(mms); +static htsmsg_t * +mpegts_mux_sched_class_save ( idnode_t *in, char *filename, size_t fsize ) +{ + htsmsg_t *c = htsmsg_create_map(); + char ubuf[UUID_HEX_SIZE]; + idnode_save(in, c); + snprintf(filename, fsize, "muxsched/%s", idnode_uuid_as_str(in, ubuf)); + return c; } static void @@ -117,6 +124,7 @@ const idclass_t mpegts_mux_sched_class = .ic_class = "mpegts_mux_sched", .ic_caption = N_("Mux schedule entry"), .ic_event = "mpegts_mux_sched", + .ic_changed = mpegts_mux_sched_class_changed, .ic_save = mpegts_mux_sched_class_save, .ic_delete = mpegts_mux_sched_class_delete, .ic_properties = (const property_t[]){ @@ -299,16 +307,6 @@ mpegts_mux_sched_create ( const char *uuid, htsmsg_t *conf ) return mms; } -void -mpegts_mux_sched_save ( mpegts_mux_sched_t *mms ) -{ - htsmsg_t *c = htsmsg_create_map(); - char ubuf[UUID_HEX_SIZE]; - idnode_save(&mms->mms_id, c); - hts_settings_save(c, "muxsched/%s", idnode_uuid_as_str(&mms->mms_id, ubuf)); - htsmsg_destroy(c); -} - void mpegts_mux_sched_delete ( mpegts_mux_sched_t *mms, int delconf ) { diff --git a/src/input/mpegts/mpegts_mux_sched.h b/src/input/mpegts/mpegts_mux_sched.h index c7cd85dff..97d01ed49 100644 --- a/src/input/mpegts/mpegts_mux_sched.h +++ b/src/input/mpegts/mpegts_mux_sched.h @@ -67,7 +67,6 @@ typedef struct mpegts_mux_sched mpegts_mux_sched_t *mpegts_mux_sched_create ( const char *uuid, htsmsg_t *c ); void mpegts_mux_sched_delete ( mpegts_mux_sched_t *mms, int delconf ); -void mpegts_mux_sched_save ( mpegts_mux_sched_t *mms ); void mpegts_mux_sched_init ( void ); void mpegts_mux_sched_done ( void ); diff --git a/src/input/mpegts/mpegts_network.c b/src/input/mpegts/mpegts_network.c index e30c84215..a607ce4e9 100644 --- a/src/input/mpegts/mpegts_network.c +++ b/src/input/mpegts/mpegts_network.c @@ -28,13 +28,14 @@ * Class definition * ***************************************************************************/ -static void +static htsmsg_t * mpegts_network_class_save - ( idnode_t *in ) + ( idnode_t *in, char *filename, size_t fsize ) { mpegts_network_t *mn = (mpegts_network_t*)in; if (mn->mn_config_save) - mn->mn_config_save(mn); + return mn->mn_config_save(mn, filename, fsize); + return NULL; } static const char * @@ -302,11 +303,12 @@ mpegts_network_display_name strncpy(buf, mn->mn_network_name ?: "unknown", len); } -static void +static htsmsg_t * mpegts_network_config_save - ( mpegts_network_t *mn ) + ( mpegts_network_t *mn, char *filename, size_t size ) { // Nothing - leave to child classes + return NULL; } static mpegts_mux_t * @@ -552,7 +554,7 @@ mpegts_network_wizard_create mn = mnb->build(mnb->idc, conf); htsmsg_destroy(conf); if (mn) - mn->mn_config_save(mn); + idnode_changed(&mn->mn_id); found: if (mn && nlist) { diff --git a/src/input/mpegts/mpegts_network_dvb.c b/src/input/mpegts/mpegts_network_dvb.c index e3881da8e..cff0010e5 100644 --- a/src/input/mpegts/mpegts_network_dvb.c +++ b/src/input/mpegts/mpegts_network_dvb.c @@ -83,7 +83,7 @@ dvb_network_scanfile_set ( dvb_network_t *ln, const char *id ) mm = dvb_mux_create0(ln, MPEGTS_ONID_NONE, MPEGTS_TSID_NONE, dmc, NULL, NULL); if (mm) - mm->mm_config_save((mpegts_mux_t *)mm); + idnode_changed(&mm->mm_id); if (tvhtrace_enabled()) { char buf[128]; dvb_mux_conf_str(dmc, buf, sizeof(buf)); @@ -549,16 +549,16 @@ dvb_network_find_mux return (dvb_mux_t *)mm; } -static void -dvb_network_config_save ( mpegts_network_t *mn ) +static htsmsg_t * +dvb_network_config_save ( mpegts_network_t *mn, char *filename, size_t fsize ) { htsmsg_t *c = htsmsg_create_map(); char ubuf[UUID_HEX_SIZE]; idnode_save(&mn->mn_id, c); htsmsg_add_str(c, "class", mn->mn_id.in_class->ic_class); - hts_settings_save(c, "input/dvb/networks/%s/config", - idnode_uuid_as_str(&mn->mn_id, ubuf)); - htsmsg_destroy(c); + snprintf(filename, fsize, "input/dvb/networks/%s/config", + idnode_uuid_as_str(&mn->mn_id, ubuf)); + return c; } const idclass_t * @@ -741,7 +741,7 @@ save: if (mm && save) { mm->mm_dmc_origin = origin; mm->mm_dmc_origin_expire = dispatch_clock + 3600 * 24; /* one day */ - mm->mm_config_save((mpegts_mux_t *)mm); + idnode_changed(&mm->mm_id); } noop: return (mpegts_mux_t *)mm; diff --git a/src/input/mpegts/mpegts_network_scan.c b/src/input/mpegts/mpegts_network_scan.c index 3ec575a5d..08845d5d8 100644 --- a/src/input/mpegts/mpegts_network_scan.c +++ b/src/input/mpegts/mpegts_network_scan.c @@ -79,7 +79,7 @@ mpegts_network_scan_timer_cb ( void *p ) TAILQ_REMOVE(&mn->mn_scan_pend, mm, mm_scan_link); if (mm->mm_scan_result != MM_SCAN_FAIL) { mm->mm_scan_result = MM_SCAN_FAIL; - mm->mm_config_save(mm); + idnode_changed(&mm->mm_id); } mm->mm_scan_state = MM_SCAN_STATE_IDLE; mm->mm_scan_weight = 0; @@ -124,7 +124,7 @@ mpegts_network_scan_mux_done0 if (result != MM_SCAN_NONE && mm->mm_scan_result != result) { mm->mm_scan_result = result; - mm->mm_config_save(mm); + idnode_changed(&mm->mm_id); } /* Re-enable? */ @@ -392,10 +392,9 @@ tsid_lookup: MPEGTS_ONID_NONE, MPEGTS_TSID_NONE, mux, NULL, NULL); - if (mm) - { - mm->mm_config_save(mm); + if (mm) { char buf[256]; + idnode_changed(&mm->mm_id); mn->mn_display_name(mn, buf, sizeof(buf)); tvhinfo("mpegts", "fastscan mux add to network '%s'", buf); } diff --git a/src/input/mpegts/mpegts_service.c b/src/input/mpegts/mpegts_service.c index 8cc75a0c4..76ff2b6b7 100644 --- a/src/input/mpegts/mpegts_service.c +++ b/src/input/mpegts/mpegts_service.c @@ -269,8 +269,8 @@ mpegts_service_is_enabled(service_t *t, int flags) /* * Save */ -static void -mpegts_service_config_save ( service_t *t ) +static htsmsg_t * +mpegts_service_config_save ( service_t *t, char *filename, size_t fsize ) { htsmsg_t *c = htsmsg_create_map(); mpegts_service_t *s = (mpegts_service_t*)t; @@ -278,11 +278,11 @@ mpegts_service_config_save ( service_t *t ) char ubuf1[UUID_HEX_SIZE]; char ubuf2[UUID_HEX_SIZE]; service_save(t, c); - hts_settings_save(c, "input/dvb/networks/%s/muxes/%s/services/%s", - idnode_uuid_as_str(&s->s_dvb_mux->mm_network->mn_id, ubuf0), - idnode_uuid_as_str(&s->s_dvb_mux->mm_id, ubuf1), - idnode_uuid_as_str(&s->s_id, ubuf2)); - htsmsg_destroy(c); + snprintf(filename, fsize, "input/dvb/networks/%s/muxes/%s/services/%s", + idnode_uuid_as_str(&s->s_dvb_mux->mm_network->mn_id, ubuf0), + idnode_uuid_as_str(&s->s_dvb_mux->mm_id, ubuf1), + idnode_uuid_as_str(&s->s_id, ubuf2)); + return c; } /* diff --git a/src/input/mpegts/satip/satip.c b/src/input/mpegts/satip/satip.c index e3226815b..bd32e8c41 100644 --- a/src/input/mpegts/satip/satip.c +++ b/src/input/mpegts/satip/satip.c @@ -117,10 +117,28 @@ satip_device_nicename( satip_device_t *sd, char *buf, int len ) * SAT-IP client */ -static void -satip_device_class_save ( idnode_t *in ) +static htsmsg_t * +satip_device_class_save ( idnode_t *in, char *filename, size_t fsize ) { - satip_device_save((satip_device_t *)in); + satip_device_t *sd = (satip_device_t *)in; + satip_frontend_t *lfe; + htsmsg_t *m, *l; + char ubuf[UUID_HEX_SIZE]; + + if (sd->sd_nosave) + return NULL; + + m = htsmsg_create_map(); + idnode_save(&sd->th_id, m); + + l = htsmsg_create_map(); + TAILQ_FOREACH(lfe, &sd->sd_frontends, sf_link) + satip_frontend_save(lfe, l); + htsmsg_add_msg(m, "frontends", l); + + snprintf(filename, fsize, "input/satip/adapters/%s", + idnode_uuid_as_str(&sd->th_id, ubuf)); + return m; } static idnode_set_t * @@ -655,7 +673,7 @@ satip_device_create( satip_device_info_t *info ) } if (save) - satip_device_save(sd); + satip_device_changed(sd); sd->sd_inload = 0; @@ -694,29 +712,6 @@ satip_device_find_by_descurl( const char *descurl ) return NULL; } -void -satip_device_save( satip_device_t *sd ) -{ - satip_frontend_t *lfe; - htsmsg_t *m, *l; - char ubuf[UUID_HEX_SIZE]; - - if (sd->sd_nosave) - return; - - m = htsmsg_create_map(); - idnode_save(&sd->th_id, m); - - l = htsmsg_create_map(); - TAILQ_FOREACH(lfe, &sd->sd_frontends, sf_link) - satip_frontend_save(lfe, l); - htsmsg_add_msg(m, "frontends", l); - - hts_settings_save(m, "input/satip/adapters/%s", - idnode_uuid_as_str(&sd->th_id, ubuf)); - htsmsg_destroy(m); -} - void satip_device_destroy( satip_device_t *sd ) { diff --git a/src/input/mpegts/satip/satip_frontend.c b/src/input/mpegts/satip/satip_frontend.c index 0b7e65368..72f73f18c 100644 --- a/src/input/mpegts/satip/satip_frontend.c +++ b/src/input/mpegts/satip/satip_frontend.c @@ -94,10 +94,10 @@ satip_frontend_signal_cb( void *aux ) * *************************************************************************/ static void -satip_frontend_class_save ( idnode_t *in ) +satip_frontend_class_changed ( idnode_t *in ) { satip_device_t *la = ((satip_frontend_t*)in)->sf_device; - satip_device_save(la); + satip_device_changed(la); } static int @@ -138,7 +138,7 @@ const idclass_t satip_frontend_class = .ic_super = &mpegts_input_class, .ic_class = "satip_frontend", .ic_caption = N_("SAT>IP DVB frontend"), - .ic_save = satip_frontend_class_save, + .ic_changed = satip_frontend_class_changed, .ic_properties = (const property_t[]) { { .type = PT_INT, @@ -1809,7 +1809,7 @@ satip_frontend_wizard_set( tvh_input_t *ti, htsmsg_t *conf, const char *lang ) htsmsg_destroy(conf); if (satip_frontend_wizard_network(lfe)) mpegts_input_set_enabled((mpegts_input_t *)lfe, 1); - satip_device_save(lfe->sf_device); + satip_device_changed(lfe->sf_device); } else { htsmsg_destroy(nlist); } diff --git a/src/input/mpegts/satip/satip_private.h b/src/input/mpegts/satip/satip_private.h index 21fd4a440..23ec7977a 100644 --- a/src/input/mpegts/satip/satip_private.h +++ b/src/input/mpegts/satip/satip_private.h @@ -197,7 +197,8 @@ void satip_device_init ( void ); void satip_device_done ( void ); -void satip_device_save ( satip_device_t *sd ); +static inline void satip_device_changed ( satip_device_t *sd ) + { idnode_changed(&sd->th_id); } void satip_device_destroy ( satip_device_t *sd ); diff --git a/src/input/mpegts/satip/satip_satconf.c b/src/input/mpegts/satip/satip_satconf.c index 35254c09e..ccc8e6acc 100644 --- a/src/input/mpegts/satip/satip_satconf.c +++ b/src/input/mpegts/satip/satip_satconf.c @@ -169,10 +169,10 @@ satip_satconf_class_get_title ( idnode_t *o, const char *lang ) } static void -satip_satconf_class_save ( idnode_t *in ) +satip_satconf_class_changed ( idnode_t *in ) { satip_satconf_t *sfc = (satip_satconf_t*)in; - satip_device_save(sfc->sfc_lfe->sf_device); + satip_device_changed(sfc->sfc_lfe->sf_device); } const idclass_t satip_satconf_class = @@ -181,7 +181,7 @@ const idclass_t satip_satconf_class = .ic_caption = N_("Satconf"), .ic_event = "satip_satconf", .ic_get_title = satip_satconf_class_get_title, - .ic_save = satip_satconf_class_save, + .ic_changed = satip_satconf_class_changed, .ic_properties = (const property_t[]) { { .type = PT_BOOL, diff --git a/src/input/mpegts/tsfile/tsfile.c b/src/input/mpegts/tsfile/tsfile.c index 51df7b79b..a19ce7369 100644 --- a/src/input/mpegts/tsfile/tsfile.c +++ b/src/input/mpegts/tsfile/tsfile.c @@ -33,9 +33,10 @@ tsfile_input_list_t tsfile_inputs; extern const idclass_t mpegts_service_class; extern const idclass_t mpegts_network_class; -static void -tsfile_service_config_save ( service_t *s ) +static htsmsg_t * +tsfile_service_config_save ( service_t *s, char *filename, size_t fsize ) { + return NULL; } static void diff --git a/src/input/mpegts/tsfile/tsfile_mux.c b/src/input/mpegts/tsfile/tsfile_mux.c index a3fedbbe0..bc6cd724f 100644 --- a/src/input/mpegts/tsfile/tsfile_mux.c +++ b/src/input/mpegts/tsfile/tsfile_mux.c @@ -46,9 +46,10 @@ tsfile_mux_instance_create return mmi; } -static void -iptv_mux_config_save ( mpegts_mux_t *m ) +static htsmsg_t * +iptv_mux_config_save ( mpegts_mux_t *m, char *filename, size_t fsize ) { + return NULL; } mpegts_mux_t * diff --git a/src/input/mpegts/tvhdhomerun/tvhdhomerun.c b/src/input/mpegts/tvhdhomerun/tvhdhomerun.c index 007b69362..b032c4af8 100644 --- a/src/input/mpegts/tvhdhomerun/tvhdhomerun.c +++ b/src/input/mpegts/tvhdhomerun/tvhdhomerun.c @@ -32,10 +32,27 @@ hdhomerun_discover_find_devices_custom_v2 #endif -static void -tvhdhomerun_device_class_save ( idnode_t *in ) +static htsmsg_t * +tvhdhomerun_device_class_save ( idnode_t *in, char *filename, size_t fsize ) { - tvhdhomerun_device_save((tvhdhomerun_device_t *)in); + tvhdhomerun_device_t *hd = (tvhdhomerun_device_t *)in; + tvhdhomerun_frontend_t *lfe; + htsmsg_t *m, *l; + char ubuf[UUID_HEX_SIZE]; + + m = htsmsg_create_map(); + idnode_save(&hd->th_id, m); + + l = htsmsg_create_map(); + TAILQ_FOREACH(lfe, &hd->hd_frontends, hf_link) + tvhdhomerun_frontend_save(lfe, l); + htsmsg_add_msg(m, "frontends", l); + + htsmsg_add_str(m, "fe_override", hd->hd_override_type); + + snprintf(filename, fsize, "input/tvhdhomerun/adapters/%s", + idnode_uuid_as_str(&hd->th_id, ubuf)); + return m; } static idnode_set_t * @@ -189,28 +206,6 @@ const idclass_t tvhdhomerun_device_class = }; -void -tvhdhomerun_device_save( tvhdhomerun_device_t *hd ) -{ - tvhdhomerun_frontend_t *lfe; - htsmsg_t *m, *l; - char ubuf[UUID_HEX_SIZE]; - - m = htsmsg_create_map(); - idnode_save(&hd->th_id, m); - - l = htsmsg_create_map(); - TAILQ_FOREACH(lfe, &hd->hd_frontends, hf_link) - tvhdhomerun_frontend_save(lfe, l); - htsmsg_add_msg(m, "frontends", l); - - htsmsg_add_str(m, "fe_override", hd->hd_override_type); - - hts_settings_save(m, "input/tvhdhomerun/adapters/%s", - idnode_uuid_as_str(&hd->th_id, ubuf)); - htsmsg_destroy(m); -} - static void tvhdhomerun_discovery_destroy(tvhdhomerun_discovery_t *d, int unlink) { @@ -342,7 +337,7 @@ static void tvhdhomerun_device_create(struct hdhomerun_discover_device_t *dInfo) if (save) - tvhdhomerun_device_save(hd); + tvhdhomerun_device_changed(hd); htsmsg_destroy(conf); } diff --git a/src/input/mpegts/tvhdhomerun/tvhdhomerun_frontend.c b/src/input/mpegts/tvhdhomerun/tvhdhomerun_frontend.c index 19393eef1..54c29eb86 100644 --- a/src/input/mpegts/tvhdhomerun/tvhdhomerun_frontend.c +++ b/src/input/mpegts/tvhdhomerun/tvhdhomerun_frontend.c @@ -512,10 +512,10 @@ tvhdhomerun_frontend_network_list ( mpegts_input_t *mi ) } static void -tvhdhomerun_frontend_class_save ( idnode_t *in ) +tvhdhomerun_frontend_class_changed ( idnode_t *in ) { tvhdhomerun_device_t *la = ((tvhdhomerun_frontend_t*)in)->hf_device; - tvhdhomerun_device_save(la); + tvhdhomerun_device_changed(la); } void @@ -540,7 +540,7 @@ const idclass_t tvhdhomerun_frontend_class = .ic_super = &mpegts_input_class, .ic_class = "tvhdhomerun_frontend", .ic_caption = N_("HDHomeRun DVB frontend"), - .ic_save = tvhdhomerun_frontend_class_save, + .ic_changed = tvhdhomerun_frontend_class_changed, .ic_properties = (const property_t[]) { { .type = PT_INT, @@ -628,7 +628,7 @@ tvhdhomerun_frontend_wizard_set( tvh_input_t *ti, htsmsg_t *conf, const char *la htsmsg_destroy(nlist); if (tvhdhomerun_frontend_wizard_network(hfe)) mpegts_input_set_enabled((mpegts_input_t *)hfe, 1); - tvhdhomerun_device_save(hfe->hf_device); + tvhdhomerun_device_changed(hfe->hf_device); } else { htsmsg_destroy(nlist); } diff --git a/src/input/mpegts/tvhdhomerun/tvhdhomerun_private.h b/src/input/mpegts/tvhdhomerun/tvhdhomerun_private.h index c6a255cd9..bf000d6c4 100644 --- a/src/input/mpegts/tvhdhomerun/tvhdhomerun_private.h +++ b/src/input/mpegts/tvhdhomerun/tvhdhomerun_private.h @@ -134,7 +134,9 @@ tvhdhomerun_frontend_create( tvhdhomerun_device_t *hd, struct hdhomerun_discover void tvhdhomerun_frontend_delete ( tvhdhomerun_frontend_t *lfe ); -void tvhdhomerun_device_save ( tvhdhomerun_device_t *sd ); +static inline void tvhdhomerun_device_changed ( tvhdhomerun_device_t *sd ) + { idnode_changed(&sd->th_id); } + void tvhdhomerun_frontend_save ( tvhdhomerun_frontend_t *lfe, htsmsg_t *m ); #endif diff --git a/src/profile.c b/src/profile.c index 81002f711..17982a1d5 100644 --- a/src/profile.c +++ b/src/profile.c @@ -41,8 +41,6 @@ static LIST_HEAD(,profile_chain) profile_chains; static profile_t *profile_default; -static void profile_class_save ( idnode_t *in ); - /* * */ @@ -114,7 +112,7 @@ profile_create pro->pro_refcount = 1; TAILQ_INSERT_TAIL(&profiles, pro, pro_link); if (save) - profile_class_save((idnode_t *)pro); + idnode_changed(&pro->pro_id); if (pro->pro_conf_changed) pro->pro_conf_changed(pro); return pro; @@ -146,8 +144,8 @@ profile_delete(profile_t *pro, int delconf) profile_release(pro); } -static void -profile_class_save ( idnode_t *in ) +static htsmsg_t * +profile_class_save ( idnode_t *in, char *filename, size_t fsize ) { profile_t *pro = (profile_t *)in; htsmsg_t *c = htsmsg_create_map(); @@ -157,10 +155,10 @@ profile_class_save ( idnode_t *in ) idnode_save(in, c); if (pro->pro_shield) htsmsg_add_bool(c, "shield", 1); - hts_settings_save(c, "profile/%s", idnode_uuid_as_str(in, ubuf)); - htsmsg_destroy(c); + snprintf(filename, fsize, "profile/%s", idnode_uuid_as_str(in, ubuf)); if (pro->pro_conf_changed) pro->pro_conf_changed(pro); + return c; } static const char * @@ -224,7 +222,7 @@ profile_class_default_set(void *o, const void *v) old = profile_default; profile_default = pro; if (old) - profile_class_save(&old->pro_id); + idnode_changed(&old->pro_id); return 1; } return 0; diff --git a/src/satip/server.c b/src/satip/server.c index 8b6d3f5b9..090ce4a16 100644 --- a/src/satip/server.c +++ b/src/satip/server.c @@ -550,9 +550,9 @@ struct satip_server_conf satip_server_conf = { .satip_allow_remote_weight = 1 }; -static void satip_server_class_save(idnode_t *self) +static void satip_server_class_changed(idnode_t *self) { - config_save(); + idnode_changed(&config.idnode); satip_server_save(); } @@ -572,7 +572,7 @@ const idclass_t satip_server_class = { .ic_caption = N_("SAT>IP server"), .ic_event = "satip_server", .ic_perm_def = ACCESS_ADMIN, - .ic_save = satip_server_class_save, + .ic_changed = satip_server_class_changed, .ic_groups = (const property_group_t[]) { { .name = N_("General"), @@ -745,7 +745,6 @@ static void satip_server_save(void) int descramble, rewrite_pmt, muxcnf; char *nat_ip; - config_save(); if (!satip_server_rtsp_port_locked) { satips_rtsp_port(0); if (satip_server_rtsp_port > 0) { @@ -849,7 +848,7 @@ void satip_server_register(void) } if (save) - config_save(); + idnode_changed(&config.idnode); satips_upnp_discovery = upnp_service_create(upnp_service); if (satips_upnp_discovery == NULL) { diff --git a/src/service.c b/src/service.c index 5790e3b19..2c3f3d00e 100644 --- a/src/service.c +++ b/src/service.c @@ -51,7 +51,7 @@ static void service_data_timeout(void *aux); static void service_class_delete(struct idnode *self); -static void service_class_save(struct idnode *self); +static htsmsg_t *service_class_save(struct idnode *self, char *filename, size_t fsize); struct service_queue service_all; struct service_queue service_raw_all; @@ -1391,12 +1391,13 @@ service_class_delete(struct idnode *self) /** * */ -static void -service_class_save(struct idnode *self) +static htsmsg_t * +service_class_save(struct idnode *self, char *filename, size_t fsize) { service_t *s = (service_t *)self; if (s->s_config_save) - s->s_config_save(s); + return s->s_config_save(s, filename, fsize); + return NULL; } /** @@ -1426,7 +1427,7 @@ service_saver(void *aux) pthread_mutex_lock(&global_lock); if(t->s_status != SERVICE_ZOMBIE && t->s_config_save) - t->s_config_save(t); + idnode_changed(&t->s_id); if(t->s_status == SERVICE_RUNNING && restart) service_restart(t); service_unref(t); diff --git a/src/service.h b/src/service.h index 7fa2bcff5..8783823a3 100644 --- a/src/service.h +++ b/src/service.h @@ -319,7 +319,7 @@ typedef struct service { void (*s_stop_feed)(struct service *t); - void (*s_config_save)(struct service *t); + htsmsg_t *(*s_config_save)(struct service *t, char *filename, size_t fsize); void (*s_setsourceinfo)(struct service *t, struct source_info *si); diff --git a/src/service_mapper.c b/src/service_mapper.c index 3ca9cadf3..7b63324e8 100644 --- a/src/service_mapper.c +++ b/src/service_mapper.c @@ -268,8 +268,7 @@ service_mapper_process } /* save */ - idnode_notify_changed(&chn->ch_id); - channel_save(chn); + idnode_changed(&chn->ch_id); } if (!bq) { service_mapper_stat.ok++; @@ -421,19 +420,21 @@ service_mapper_reset_stats (void) /* * Save settings */ -static void service_mapper_conf_class_save ( idnode_t *self ) +static htsmsg_t * +service_mapper_conf_class_save ( idnode_t *self, char *filename, size_t fsize ) { htsmsg_t *m; m = htsmsg_create_map(); idnode_save(&service_mapper_conf.idnode, m); - hts_settings_save(m, "service_mapper/config"); - htsmsg_destroy(m); + snprintf(filename, fsize, "service_mapper/config"); if (!htsmsg_is_empty(service_mapper_conf.services)) service_mapper_start(&service_mapper_conf.d, service_mapper_conf.services); htsmsg_destroy(service_mapper_conf.services); service_mapper_conf.services = NULL; + + return m; } /* diff --git a/src/tvhlog.c b/src/tvhlog.c index d540dc52c..d265ff613 100644 --- a/src/tvhlog.c +++ b/src/tvhlog.c @@ -477,10 +477,6 @@ tvhlog_end ( void ) * Configuration */ -static void tvhlog_class_save(idnode_t *self) -{ -} - static const void * tvhlog_class_path_get ( void *o ) { @@ -626,7 +622,6 @@ const idclass_t tvhlog_conf_class = { .ic_caption = N_("Debugging"), .ic_event = "tvhlog_conf", .ic_perm_def = ACCESS_ADMIN, - .ic_save = tvhlog_class_save, .ic_groups = (const property_group_t[]) { { .name = N_("Settings"), diff --git a/src/wizard.c b/src/wizard.c index ec201bf8a..f0b426338 100644 --- a/src/wizard.c +++ b/src/wizard.c @@ -120,7 +120,7 @@ typedef struct wizard_hello { } wizard_hello_t; -static void hello_save(idnode_t *in) +static void hello_changed(idnode_t *in) { wizard_page_t *p = (wizard_page_t *)in; wizard_hello_t *w = p->aux; @@ -146,7 +146,7 @@ static void hello_save(idnode_t *in) save = 1; } if (save) - config_save(); + idnode_changed(&config.idnode); } BASIC_STR_OPS(wizard_hello_t, ui_lang) @@ -252,7 +252,7 @@ wizard_page_t *wizard_hello(const char *lang) ic->ic_properties = props; ic->ic_groups = groups; - ic->ic_save = hello_save; + ic->ic_changed = hello_changed; page->aux = w = calloc(1, sizeof(wizard_hello_t)); if (config.language_ui) @@ -288,7 +288,7 @@ typedef struct wizard_login { } wizard_login_t; -static void login_save(idnode_t *in) +static void login_changed(idnode_t *in) { wizard_page_t *p = (wizard_page_t *)in; wizard_login_t *w = p->aux; @@ -324,7 +324,7 @@ static void login_save(idnode_t *in) ae = access_entry_create(NULL, conf); if (ae) { ae->ae_wizard = 1; - access_entry_save(ae); + idnode_changed(&ae->ae_id); } htsmsg_destroy(conf); @@ -336,7 +336,7 @@ static void login_save(idnode_t *in) pw = passwd_entry_create(NULL, conf); if (pw) { pw->pw_wizard = 1; - passwd_entry_save(pw); + idnode_changed(&pw->pw_id); } htsmsg_destroy(conf); } @@ -355,7 +355,7 @@ static void login_save(idnode_t *in) ae = access_entry_create(NULL, conf); if (ae) { ae->ae_wizard = 1; - access_entry_save(ae); + idnode_changed(&ae->ae_id); } htsmsg_destroy(conf); @@ -367,7 +367,7 @@ static void login_save(idnode_t *in) pw = passwd_entry_create(NULL, conf); if (pw) { pw->pw_wizard = 1; - passwd_entry_save(pw); + idnode_changed(&pw->pw_id); } htsmsg_destroy(conf); } @@ -484,7 +484,7 @@ wizard_page_t *wizard_login(const char *lang) ic->ic_properties = props; ic->ic_groups = groups; - ic->ic_save = login_save; + ic->ic_changed = login_changed; page->aux = w = calloc(1, sizeof(wizard_login_t)); TAILQ_FOREACH(ae, &access_entries, ae_link) { @@ -539,7 +539,7 @@ static void network_free(wizard_page_t *page) page_free(page); } -static void network_save(idnode_t *in) +static void network_changed(idnode_t *in) { wizard_page_t *p = (wizard_page_t *)in; wizard_network_t *w = p->aux; @@ -720,7 +720,7 @@ wizard_page_t *wizard_network(const char *lang) page->aux = w = calloc(1, sizeof(wizard_network_t)); ic->ic_groups = groups; ic->ic_properties = w->props; - ic->ic_save = network_save; + ic->ic_changed = network_changed; page->free = network_free; snprintf(w->lang, sizeof(w->lang), "%s", lang ?: ""); @@ -777,7 +777,7 @@ static void muxes_free(wizard_page_t *page) page_free(page); } -static void muxes_save(idnode_t *in) +static void muxes_changed(idnode_t *in) { wizard_page_t *p = (wizard_page_t *)in; wizard_muxes_t *w = p->aux; @@ -989,7 +989,7 @@ wizard_page_t *wizard_muxes(const char *lang) page->aux = w = calloc(1, sizeof(wizard_muxes_t)); ic->ic_groups = groups; ic->ic_properties = w->props; - ic->ic_save = muxes_save; + ic->ic_changed = muxes_changed; page->free = muxes_free; snprintf(w->lang, sizeof(w->lang), "%s", lang ?: ""); @@ -1084,7 +1084,7 @@ typedef struct wizard_mapping { int nettags; } wizard_mapping_t; -static void mapping_save(idnode_t *in) +static void mapping_changed(idnode_t *in) { wizard_page_t *p = (wizard_page_t *)in; wizard_mapping_t *w = p->aux; @@ -1162,7 +1162,7 @@ wizard_page_t *wizard_mapping(const char *lang) idclass_t *ic = (idclass_t *)page->idnode.in_class; wizard_mapping_t *w; ic->ic_properties = props; - ic->ic_save = mapping_save; + ic->ic_changed = mapping_changed; page->aux = w = calloc(1, sizeof(wizard_mapping_t)); w->provtags = service_mapper_conf.d.provider_tags; w->nettags = service_mapper_conf.d.network_tags; @@ -1173,7 +1173,7 @@ wizard_page_t *wizard_mapping(const char *lang) * Discovered channels */ -static void channels_save(idnode_t *in) +static void channels_changed(idnode_t *in) { access_entry_t *ae, *ae_next; @@ -1226,7 +1226,7 @@ wizard_page_t *wizard_channels(const char *lang) ic->ic_properties = props; ic->ic_flags |= IDCLASS_ALWAYS_SAVE; - ic->ic_save = channels_save; + ic->ic_changed = channels_changed; /* do we have an admin created by wizard? */ TAILQ_FOREACH(ae, &access_entries, ae_link) if (ae->ae_admin && ae->ae_wizard) break;