From: Jaroslav Kysela Date: Mon, 4 May 2015 08:33:01 +0000 (+0200) Subject: idnode: notification cleanups and grouping X-Git-Tag: v4.1~64 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=174ecc8580cb333e0ec4e4699a061ceff2bb611f;p=thirdparty%2Ftvheadend.git idnode: notification cleanups and grouping --- diff --git a/src/bouquet.c b/src/bouquet.c index b55762e46..ad846d992 100644 --- a/src/bouquet.c +++ b/src/bouquet.c @@ -283,7 +283,7 @@ bouquet_add_service(bouquet_t *bq, service_t *s, uint64_t lcn, uint32_t tag) if (lcn != tl->sl_lcn) { tl->sl_lcn = lcn; LIST_FOREACH(csm, &s->s_channels, csm_svc_link) - idnode_notify_simple(&csm->csm_chn->ch_id); + idnode_notify_changed(&csm->csm_chn->ch_id); } tl->sl_seen = 1; @@ -456,7 +456,7 @@ bouquet_notify_channels(bouquet_t *bq) t = (service_t *)bq->bq_services->is_array[z]; LIST_FOREACH(csm, &t->s_channels, csm_svc_link) if (csm->csm_chn->ch_bouquet == bq) - idnode_notify_simple(&csm->csm_chn->ch_id); + idnode_notify_changed(&csm->csm_chn->ch_id); } } @@ -511,7 +511,7 @@ bouquet_save(bouquet_t *bq, int notify) htsmsg_destroy(c); bq->bq_saveflag = 0; if (notify) - idnode_notify_simple(&bq->bq_id); + idnode_notify_changed(&bq->bq_id); } /* ************************************************************************** diff --git a/src/channels.c b/src/channels.c index 099af46f5..b560c4456 100644 --- a/src/channels.c +++ b/src/channels.c @@ -710,7 +710,7 @@ channel_get_icon ( channel_t *ch ) if (i > 1 || check_file(buf)) { icon = ch->ch_icon = strdup(buf); channel_save(ch); - idnode_notify_simple(&ch->ch_id); + idnode_notify_changed(&ch->ch_id); } } @@ -725,7 +725,7 @@ channel_get_icon ( channel_t *ch ) if (i > 1 || check_file(buf2)) { icon = ch->ch_icon = strdup(icn); channel_save(ch); - idnode_notify_simple(&ch->ch_id); + idnode_notify_changed(&ch->ch_id); break; } } @@ -1009,7 +1009,7 @@ channel_tag_unmap(channel_t *ch, channel_tag_t *ct) LIST_REMOVE(ctm, ctm_tag_link); free(ctm); channel_save(ch); - idnode_notify_simple(&ch->ch_id); + idnode_notify_changed(&ch->ch_id); if (ct->ct_enabled && !ct->ct_internal) { htsp_tag_update(ct); htsp_channel_update(ch); diff --git a/src/descrambler/caclient.c b/src/descrambler/caclient.c index 63fb2f26d..44beb6d08 100644 --- a/src/descrambler/caclient.c +++ b/src/descrambler/caclient.c @@ -320,7 +320,7 @@ caclient_set_status(caclient_t *cac, caclient_status_t status) { if (cac->cac_status != status) { cac->cac_status = status; - idnode_notify_simple(&cac->cac_id); + idnode_notify_changed(&cac->cac_id); } } diff --git a/src/dvr/dvr_autorec.c b/src/dvr/dvr_autorec.c index d874f1be1..9f5570f06 100644 --- a/src/dvr/dvr_autorec.c +++ b/src/dvr/dvr_autorec.c @@ -1207,7 +1207,7 @@ autorec_destroy_by_channel_tag(channel_tag_t *ct, int delconf) while((dae = LIST_FIRST(&ct->ct_autorecs)) != NULL) { LIST_REMOVE(dae, dae_channel_tag_link); dae->dae_channel_tag = NULL; - idnode_notify_simple(&dae->dae_id); + idnode_notify_changed(&dae->dae_id); if (delconf) dvr_autorec_save(dae); } diff --git a/src/dvr/dvr_db.c b/src/dvr/dvr_db.c index ce9c91a9f..c41a10cee 100644 --- a/src/dvr/dvr_db.c +++ b/src/dvr/dvr_db.c @@ -1066,7 +1066,7 @@ dvr_stop_recording(dvr_entry_t *de, int stopcode, int saveconf) if (saveconf) dvr_entry_save(de); - idnode_notify_simple(&de->de_id); + idnode_notify_changed(&de->de_id); htsp_dvr_entry_update(de); gtimer_arm_abs(&de->de_timer, dvr_timer_expire, de, diff --git a/src/dvr/dvr_inotify.c b/src/dvr/dvr_inotify.c index 1ee3ab877..0ad32f54a 100644 --- a/src/dvr/dvr_inotify.c +++ b/src/dvr/dvr_inotify.c @@ -207,7 +207,7 @@ _dvr_inotify_moved dvr_inotify_del(de); htsp_dvr_entry_update(de); - idnode_notify_simple(&de->de_id); + idnode_notify_changed(&de->de_id); } /* @@ -235,7 +235,7 @@ _dvr_inotify_moved_all while ((de = LIST_FIRST(&die->entries))) { htsp_dvr_entry_update(de); - idnode_notify_simple(&de->de_id); + idnode_notify_changed(&de->de_id); dvr_inotify_del(de); } } diff --git a/src/dvr/dvr_rec.c b/src/dvr/dvr_rec.c index 4834284fc..62b3301d9 100644 --- a/src/dvr/dvr_rec.c +++ b/src/dvr/dvr_rec.c @@ -316,7 +316,7 @@ static void dvr_notify(dvr_entry_t *de, int now) { if (now || de->de_last_notify + 5 < dispatch_clock) { - idnode_notify_simple(&de->de_id); + idnode_notify_changed(&de->de_id); de->de_last_notify = dispatch_clock; htsp_dvr_entry_update(de); } diff --git a/src/htsmsg.c b/src/htsmsg.c index 24172d561..90bf4f5c7 100644 --- a/src/htsmsg.c +++ b/src/htsmsg.c @@ -289,7 +289,7 @@ htsmsg_add_binptr(htsmsg_t *msg, const char *name, const void *bin, size_t len) /* * */ -void +htsmsg_t * htsmsg_add_msg(htsmsg_t *msg, const char *name, htsmsg_t *sub) { htsmsg_field_t *f; @@ -301,6 +301,11 @@ htsmsg_add_msg(htsmsg_t *msg, const char *name, htsmsg_t *sub) f->hmf_msg.hm_islist = sub->hm_islist; TAILQ_MOVE(&f->hmf_msg.hm_fields, &sub->hm_fields, hmf_link); free(sub); + + if (f->hmf_type == (f->hmf_msg.hm_islist ? HMF_LIST : HMF_MAP)) + return &f->hmf_msg; + + return NULL; } diff --git a/src/htsmsg.h b/src/htsmsg.h index 4d59c6cab..4964c2bfa 100644 --- a/src/htsmsg.h +++ b/src/htsmsg.h @@ -161,7 +161,7 @@ int htsmsg_set_str(htsmsg_t *msg, const char *name, const char *str); /** * Add an field where source is a list or map message. */ -void htsmsg_add_msg(htsmsg_t *msg, const char *name, htsmsg_t *sub); +htsmsg_t *htsmsg_add_msg(htsmsg_t *msg, const char *name, htsmsg_t *sub); /** * Add an field where source is a double diff --git a/src/idnode.c b/src/idnode.c index 75aedee30..d1c13a715 100644 --- a/src/idnode.c +++ b/src/idnode.c @@ -178,7 +178,7 @@ idnode_insert(idnode_t *in, const char *uuid, const idclass_t *class, int flags) assert(c == NULL); /* Fire event */ - idnode_notify_simple(in); + idnode_notify_changed(in); return 0; } @@ -193,14 +193,14 @@ idnode_unlink(idnode_t *in) RB_REMOVE(&idnodes, in, in_link); RB_REMOVE(in->in_domain, in, in_domain_link); tvhtrace("idnode", "unlink node %s", idnode_uuid_as_str(in)); - idnode_notify_simple(in); + idnode_notify(in, "delete"); } /** * */ static void -idnode_handler(size_t off, idnode_t *in) +idnode_handler(size_t off, idnode_t *in, const char *action) { void (**fcn)(idnode_t *); lock_assert(&global_lock); @@ -208,29 +208,32 @@ idnode_handler(size_t off, idnode_t *in) while (idc) { fcn = (void *)idc + off; if (*fcn) { + if (action) + idnode_notify(in, action); (*fcn)(in); break; } idc = idc->ic_super; } + } void idnode_delete(idnode_t *in) { - return idnode_handler(offsetof(idclass_t, ic_delete), in); + idnode_handler(offsetof(idclass_t, ic_delete), in, NULL); } void idnode_moveup(idnode_t *in) { - return idnode_handler(offsetof(idclass_t, ic_moveup), in); + return idnode_handler(offsetof(idclass_t, ic_moveup), in, "moveup"); } void idnode_movedown(idnode_t *in) { - return idnode_handler(offsetof(idclass_t, ic_movedown), in); + return idnode_handler(offsetof(idclass_t, ic_movedown), in, "movedown"); } /* ************************************************************************** @@ -1094,7 +1097,7 @@ idnode_write0 ( idnode_t *self, htsmsg_t *c, int optmask, int dosave ) if (save && dosave) idnode_savefn(self); if (dosave) - idnode_notify_simple(self); + idnode_notify_changed(self); // Note: always output event if "dosave", reason is that UI updates on // these, but there are some subtle cases where it will expect // an update and not get one. This include fields being set for @@ -1106,7 +1109,7 @@ idnode_write0 ( idnode_t *self, htsmsg_t *c, int optmask, int dosave ) void idnode_changed( idnode_t *self ) { - idnode_notify_simple(self); + idnode_notify_changed(self); idnode_savefn(self); } @@ -1339,67 +1342,57 @@ idnode_serialize0(idnode_t *self, htsmsg_t *list, int optmask) * Delayed notification */ static void -idnode_notify_delayed ( idnode_t *in, const char *uuid, const char *event ) +idnode_notify_delayed + ( const char *uuid, const char *event, const char *action ) { + htsmsg_t *m = NULL, *e = NULL; + htsmsg_field_t *f; + pthread_mutex_lock(&idnode_mutex); - if (!idnode_queue) + if (idnode_queue == NULL) { idnode_queue = htsmsg_create_map(); - htsmsg_set_str(idnode_queue, uuid, event); + } else { + m = htsmsg_get_map(idnode_queue, event); + } + if (m == NULL) { + m = htsmsg_add_msg(idnode_queue, event, htsmsg_create_map()); + } else { + e = htsmsg_get_list(m, action); + } + if (e == NULL) + e = htsmsg_add_msg(m, action, htsmsg_create_list()); + HTSMSG_FOREACH(f, e) + if (strcmp(htsmsg_field_get_str(f) ?: "", uuid) == 0) + goto skip; + htsmsg_add_str(e, NULL, uuid); pthread_cond_signal(&idnode_cond); +skip: pthread_mutex_unlock(&idnode_mutex); } /** - * Update internal event pipes - */ -static void -idnode_notify_event ( idnode_t *in ) -{ - const idclass_t *ic = in->in_class; - const char *uuid = idnode_uuid_as_str(in); - while (ic) { - if (ic->ic_event) - idnode_notify_delayed(in, uuid, ic->ic_event); - ic = ic->ic_super; - } -} - -/** - * Notify on a given channel + * Notify about a change */ void -idnode_notify - (idnode_t *in, int event) +idnode_notify ( idnode_t *in, const char *action ) { + const idclass_t *ic = in->in_class; const char *uuid = idnode_uuid_as_str(in); if (!tvheadend_running) return; - /* Immediate */ - if (!event) { - - const idclass_t *ic = in->in_class; - - while (ic) { - if (ic->ic_event) { - htsmsg_t *m = htsmsg_create_map(); - htsmsg_add_str(m, "uuid", uuid); - notify_by_msg(ic->ic_event, m); - } - ic = ic->ic_super; - } - - /* Rate-limited */ - } else { - idnode_notify_event(in); + while (ic) { + if (ic->ic_event) + idnode_notify_delayed(uuid, ic->ic_event, action); + ic = ic->ic_super; } } void -idnode_notify_simple (void *in) +idnode_notify_changed (void *in) { - idnode_notify(in, 1); + idnode_notify(in, "change"); } void @@ -1409,7 +1402,7 @@ idnode_notify_title_changed (void *in) htsmsg_add_str(m, "uuid", idnode_uuid_as_str(in)); htsmsg_add_str(m, "text", idnode_get_title(in)); notify_by_msg("title", m); - idnode_notify_event(in); + idnode_notify_changed(in); } /* @@ -1418,10 +1411,8 @@ idnode_notify_title_changed (void *in) void* idnode_thread ( void *p ) { - idnode_t *node; - htsmsg_t *m, *q = NULL; + htsmsg_t *q = NULL; htsmsg_field_t *f; - const char *event; pthread_mutex_lock(&idnode_mutex); @@ -1439,17 +1430,8 @@ idnode_thread ( void *p ) /* Process */ pthread_mutex_lock(&global_lock); - HTSMSG_FOREACH(f, q) { - node = idnode_find(f->hmf_name, NULL, NULL); - event = htsmsg_field_get_str(f); - if (event) { - m = htsmsg_create_map(); - htsmsg_add_str(m, "uuid", f->hmf_name); - if (!node) - htsmsg_add_u32(m, "removed", 1); - notify_by_msg(event, m); - } - } + HTSMSG_FOREACH(f, q) + notify_by_msg(f->hmf_name, htsmsg_detach_submsg(f)); /* Finished */ pthread_mutex_unlock(&global_lock); diff --git a/src/idnode.h b/src/idnode.h index 9cc8935be..add334a2b 100644 --- a/src/idnode.h +++ b/src/idnode.h @@ -160,8 +160,8 @@ void *idnode_find (const char *uuid, const idclass_t *idc, const idno idnode_set_t *idnode_find_all(const idclass_t *idc, const idnodes_rb_t *nodes); -void idnode_notify (idnode_t *in, int event); -void idnode_notify_simple (void *in); +void idnode_notify (idnode_t *in, const char *action); +void idnode_notify_changed (void *in); void idnode_notify_title_changed (void *in); void idclass_register ( const idclass_t *idc ); diff --git a/src/input/mpegts/mpegts_input.c b/src/input/mpegts/mpegts_input.c index 4a6b634c3..63446348f 100644 --- a/src/input/mpegts/mpegts_input.c +++ b/src/input/mpegts/mpegts_input.c @@ -1601,14 +1601,14 @@ mpegts_input_add_network ( mpegts_input_t *mi, mpegts_network_t *mn ) mnl->mnl_network = mn; LIST_INSERT_HEAD(&mi->mi_networks, mnl, mnl_mi_link); LIST_INSERT_HEAD(&mn->mn_inputs, mnl, mnl_mn_link); - idnode_notify_simple(&mnl->mnl_network->mn_id); + idnode_notify_changed(&mnl->mnl_network->mn_id); return 1; } static void mpegts_input_del_network ( mpegts_network_link_t *mnl ) { - idnode_notify_simple(&mnl->mnl_network->mn_id); + idnode_notify_changed(&mnl->mnl_network->mn_id); LIST_REMOVE(mnl, mnl_mn_link); LIST_REMOVE(mnl, mnl_mi_link); free(mnl); diff --git a/src/input/mpegts/mpegts_mux.c b/src/input/mpegts/mpegts_mux.c index 8204a63df..376913035 100644 --- a/src/input/mpegts/mpegts_mux.c +++ b/src/input/mpegts/mpegts_mux.c @@ -1089,7 +1089,7 @@ mpegts_mux_set_onid ( mpegts_mux_t *mm, uint16_t onid ) mpegts_mux_nice_name(mm, buf, sizeof(buf)); mm->mm_config_save(mm); tvhtrace("mpegts", "%s - set onid %04X (%d)", buf, onid, onid); - //idnode_notify(NULL, &mm->mm_id, 0, NULL); + idnode_notify_changed(&mm->mm_id); return 1; } @@ -1107,7 +1107,7 @@ mpegts_mux_set_tsid ( mpegts_mux_t *mm, uint16_t tsid, int force ) mpegts_mux_nice_name(mm, buf, sizeof(buf)); tvhtrace("mpegts", "%s - set tsid %04X (%d)", buf, tsid, tsid); #endif - //idnode_notify(NULL, &mm->mm_id, 0, NULL); + idnode_notify_changed(&mm->mm_id); return 1; } @@ -1123,7 +1123,7 @@ mpegts_mux_set_crid_authority ( mpegts_mux_t *mm, const char *defauth ) mpegts_mux_nice_name(mm, buf, sizeof(buf)); tvhtrace("mpegts", "%s - set crid authority %s", buf, defauth); #endif - //idnode_notify(NULL, &mm->mm_id, 0, NULL); + idnode_notify_changed(&mm->mm_id); return 1; } diff --git a/src/input/mpegts/mpegts_network.c b/src/input/mpegts/mpegts_network.c index 0268409c3..9311ffc8d 100644 --- a/src/input/mpegts/mpegts_network.c +++ b/src/input/mpegts/mpegts_network.c @@ -294,7 +294,7 @@ mpegts_network_mux_create2 static void mpegts_network_link_delete ( mpegts_network_link_t *mnl ) { - idnode_notify_simple(&mnl->mnl_input->ti_id); + idnode_notify_changed(&mnl->mnl_input->ti_id); LIST_REMOVE(mnl, mnl_mn_link); LIST_REMOVE(mnl, mnl_mi_link); free(mnl); diff --git a/src/input/mpegts/mpegts_network_scan.c b/src/input/mpegts/mpegts_network_scan.c index 1b3b2760b..debeb2ced 100644 --- a/src/input/mpegts/mpegts_network_scan.c +++ b/src/input/mpegts/mpegts_network_scan.c @@ -27,8 +27,8 @@ static void mpegts_network_scan_notify ( mpegts_mux_t *mm ) { - idnode_notify_simple(&mm->mm_id); - idnode_notify_simple(&mm->mm_network->mn_id); + idnode_notify_changed(&mm->mm_id); + idnode_notify_changed(&mm->mm_network->mn_id); } static int diff --git a/src/input/mpegts/mpegts_service.c b/src/input/mpegts/mpegts_service.c index ee8627b41..28d73ee2c 100644 --- a/src/input/mpegts/mpegts_service.c +++ b/src/input/mpegts/mpegts_service.c @@ -632,8 +632,8 @@ mpegts_service_create0 tvhlog(LOG_DEBUG, "mpegts", "%s - add service %04X %s", buf, s->s_dvb_service_id, s->s_dvb_svcname); /* Notification */ - idnode_notify_simple(&mm->mm_id); - idnode_notify_simple(&mm->mm_network->mn_id); + idnode_notify_changed(&mm->mm_id); + idnode_notify_changed(&mm->mm_network->mn_id); /* Save the create time */ if (s->s_dvb_created == dispatch_clock) diff --git a/src/service.c b/src/service.c index e8e715e42..757d2c5c8 100644 --- a/src/service.c +++ b/src/service.c @@ -120,7 +120,7 @@ service_class_channel_set /* no save - the link information is in the saved channel record */ /* only send a notify about the change to other clients */ - idnode_notify_simple(&svc->s_id); + idnode_notify_changed(&svc->s_id); return 0; } @@ -871,7 +871,7 @@ service_set_enabled(service_t *t, int enabled, int _auto) t->s_auto = _auto; service_class_notify_enabled(t); service_request_save(t, 0); - idnode_notify_simple(&t->s_id); + idnode_notify_changed(&t->s_id); } } diff --git a/src/service_mapper.c b/src/service_mapper.c index a2c5a9d0d..2f8062cea 100644 --- a/src/service_mapper.c +++ b/src/service_mapper.c @@ -184,11 +184,11 @@ service_mapper_notify ( channel_service_mapping_t *csm, void *origin ) if (origin == NULL) return; if (origin == csm->csm_svc) { - idnode_notify_simple(&csm->csm_chn->ch_id); + idnode_notify_changed(&csm->csm_chn->ch_id); channel_save(csm->csm_chn); } if (origin == csm->csm_chn) - idnode_notify_simple(&csm->csm_svc->s_id); + idnode_notify_changed(&csm->csm_svc->s_id); } /* @@ -315,7 +315,7 @@ service_mapper_process ( service_t *s, bouquet_t *bq ) channel_tag_map(chn, channel_tag_find_by_name(prov, 1)); /* save */ - idnode_notify_simple(&chn->ch_id); + idnode_notify_changed(&chn->ch_id); channel_save(chn); } if (!bq) {