static int randfd = 0;
static RB_HEAD(,idnode) idnodes;
+static pthread_cond_t idnode_cond;
+static pthread_mutex_t idnode_mutex;
+static htsmsg_t *idnode_queue;
+static void* idnode_thread(void* p);
/* **************************************************************************
* Utilities
void
idnode_init(void)
{
+ pthread_t tid;
+
+
randfd = open("/dev/urandom", O_RDONLY);
if(randfd == -1)
exit(1);
+
+ idnode_queue = NULL;
+ pthread_mutex_init(&idnode_mutex, NULL);
+ pthread_cond_init(&idnode_cond, NULL);
+ pthread_create(&tid, NULL, idnode_thread, NULL);
}
/**
{
int save = 0;
const idclass_t *idc = self->in_class;
- htsmsg_t *updated = htsmsg_create_map();
for (; idc; idc = idc->ic_super)
- save |= prop_write_values(self, idc->ic_properties, c, optmask, updated);
- if (save && dosave)
- idnode_notify(NULL, self, optmask, updated);
- htsmsg_destroy(updated);
+ save |= prop_write_values(self, idc->ic_properties, c, optmask, NULL);
+ if (save) {
+ if (dosave) {
+ for(; idc != NULL; idc = idc->ic_super) {
+ if(idc->ic_save != NULL) {
+ idc->ic_save(self);
+ break;
+ }
+ }
+ }
+ idnode_notify(self, NULL, 0);
+ }
return save;
}
* *************************************************************************/
/**
- *
+ * Notify on a given channel
*/
void
-idnode_notify_title_changed(void *obj)
+idnode_notify
+ (idnode_t *in, const char *chn, int force)
{
- idnode_t *in = obj;
- htsmsg_t *m = htsmsg_create_map();
- htsmsg_add_str(m, "id", idnode_uuid_as_str(in));
- htsmsg_add_str(m, "text", idnode_get_title(in));
- notify_by_msg("idnodeNameChanged", m);
+ /* Forced */
+ if (chn || force) {
+ htsmsg_t *m = idnode_serialize0(in, 0);
+ notify_by_msg(chn ?: "idnodeParamsChanged", m);
+
+ /* Rate-limited */
+ } else {
+ pthread_mutex_lock(&idnode_mutex);
+ if (!idnode_queue)
+ idnode_queue = htsmsg_create_map();
+ htsmsg_set_u32(idnode_queue, idnode_uuid_as_str(in), 1);
+ pthread_cond_signal(&idnode_cond);
+ pthread_mutex_unlock(&idnode_mutex);
+ }
}
-/**
- * Notify on a given channel
- */
void
-idnode_notify
- (const char *chn, idnode_t *in, int optmask, htsmsg_t *inc)
+idnode_notify_simple (void *in)
{
- const idclass_t *ic = in->in_class;
-
- /* Save */
- for(; ic != NULL; ic = ic->ic_super) {
- if(ic->ic_save != NULL) {
- ic->ic_save(in);
- break;
- }
- }
+ idnode_notify(in, NULL, 0);
+}
- /* Notification */
+/*
+ * Thread for handling notifications
+ */
+void*
+idnode_thread ( void *p )
+{
+ idnode_t *node;
+ htsmsg_t *m, *q;
+ htsmsg_field_t *f;
- htsmsg_t *m = htsmsg_create_map();
- htsmsg_add_str(m, "id", idnode_uuid_as_str(in));
+ pthread_mutex_lock(&idnode_mutex);
- htsmsg_t *p = htsmsg_create_list();
- add_params(in, in->in_class, p, optmask, inc);
- htsmsg_add_msg(m, "params", p);
+ while (1) {
- notify_by_msg(chn ?: "idnodeParamsChanged", m);
+ /* Get queue */
+ if (!idnode_queue) {
+ pthread_cond_wait(&idnode_cond, &idnode_mutex);
+ continue;
+ }
+ q = idnode_queue;
+ idnode_queue = NULL;
+ pthread_mutex_unlock(&idnode_mutex);
+
+ /* Process */
+ pthread_mutex_lock(&global_lock);
+
+ HTSMSG_FOREACH(f, q) {
+ node = idnode_find(f->hmf_name, NULL);
+ if (node) {
+ m = idnode_serialize0(node, 0);
+ if (m)
+ notify_by_msg("idnodeUpdated", m);
+ } else {
+ m = htsmsg_create_map();
+ htsmsg_add_str(m, "uuid", f->hmf_name);
+ notify_by_msg("idnodeDeleted", m);
+ }
+ }
+
+ /* Finished */
+ pthread_mutex_unlock(&global_lock);
+ htsmsg_destroy(q);
+ pthread_mutex_lock(&idnode_mutex);
+ }
+
+ return NULL;
}
/******************************************************************************
mpegts_mux_t *mm, uint16_t sid, uint16_t pmt_pid, htsmsg_t *conf )
{
char buf[256];
- static htsmsg_t *inc = NULL;
service_create0((service_t*)s, class, uuid, S_MPEG_TS, conf);
/* Create */
tvhlog(LOG_DEBUG, "mpegts", "%s - add service %04X %s", buf, s->s_dvb_service_id, s->s_dvb_svcname);
/* Notification */
- if (!inc) {
- inc = htsmsg_create_map();
- htsmsg_set_u32(inc, "num_mux", 1);
- htsmsg_set_u32(inc, "num_svc", 1);
- }
- idnode_notify(NULL, &s->s_dvb_mux->mm_id, 0, inc);
- idnode_notify(NULL, &s->s_dvb_mux->mm_network->mn_id, 0, inc);
+ idnode_updated(&mm->mm_id);
+ idnode_updated(&mm->mm_network->mn_id);
return s;
}