diff --git a/include/villas/hook.h b/include/villas/hook.h index 05606064c..aa1653785 100644 --- a/include/villas/hook.h +++ b/include/villas/hook.h @@ -70,9 +70,11 @@ int hook_periodic(struct hook *h); int hook_restart(struct hook *h); int hook_read(struct hook *h, struct sample *smps[], unsigned *cnt); +int hook_process(struct hook *h, struct sample *smps[], unsigned *cnt); int hook_write(struct hook *h, struct sample *smps[], unsigned *cnt); int hook_read_list(struct list *hs, struct sample *smps[], unsigned cnt); +int hook_process_list(struct list *hs, struct sample *smps[], unsigned cnt); int hook_write_list(struct list *hs, struct sample *smps[], unsigned cnt); /** Compare two hook functions with their priority. Used by list_sort() */ diff --git a/include/villas/hook_type.h b/include/villas/hook_type.h index edebde0a5..d7c10af61 100644 --- a/include/villas/hook_type.h +++ b/include/villas/hook_type.h @@ -61,6 +61,7 @@ struct hook_type { int (*periodic)(struct hook *h);/**< Called periodically. Period is set by global 'stats' option in the configuration file. */ int (*restart)(struct hook *h); /**< Called whenever a new simulation case is started. This is detected by a sequence no equal to zero. */ - int (*read)(struct hook *h, struct sample *smps[], unsigned *cnt); /**< Called for every single received samples. */ - int (*write)(struct hook *h, struct sample *smps[], unsigned *cnt); /**< Called for every single sample which will be sent. */ + int (*read)(struct hook *h, struct sample *smps[], unsigned *cnt); /**< Called whenever samples have been read from a node. */ + int (*process)(struct hook *h, struct sample *smps[], unsigned *cnt); /**< Called whenever muxed samples are processed. */ + int (*write)(struct hook *h, struct sample *smps[], unsigned *cnt); /**< Called whenever samples are written to a node. */ }; diff --git a/lib/hook.c b/lib/hook.c index 6a8d0e848..3f2200e37 100644 --- a/lib/hook.c +++ b/lib/hook.c @@ -151,6 +151,13 @@ int hook_read(struct hook *h, struct sample *smps[], unsigned *cnt) return h->_vt->read ? h->_vt->read(h, smps, cnt) : 0; } +int hook_process(struct hook *h, struct sample *smps[], unsigned *cnt) +{ + debug(LOG_HOOK | 10, "Running hook %s: type=process, priority=%d, cnt=%u", plugin_name(h->_vt), h->priority, *cnt); + + return h->_vt->process ? h->_vt->process(h, smps, cnt) : 0; +} + int hook_write(struct hook *h, struct sample *smps[], unsigned *cnt) { debug(LOG_HOOK | 10, "Running hook %s: type=write, priority=%d, cnt=%u", plugin_name(h->_vt), h->priority, *cnt); @@ -158,14 +165,14 @@ int hook_write(struct hook *h, struct sample *smps[], unsigned *cnt) return h->_vt->write ? h->_vt->write(h, smps, cnt) : 0; } -int hook_read_list(struct list *hs, struct sample *smps[], unsigned cnt) +static int hook_run_list(struct list *hs, struct sample *smps[], unsigned cnt, int (*func)(struct hook *, struct sample **, unsigned *)) { unsigned ret; for (size_t i = 0; i < list_length(hs); i++) { struct hook *h = list_at(hs, i); - ret = hook_read(h, smps, &cnt); + ret = func(h, smps, &cnt); if (ret || !cnt) /* Abort hook processing if earlier hooks removed all samples * or they returned something non-zero */ @@ -175,21 +182,19 @@ int hook_read_list(struct list *hs, struct sample *smps[], unsigned cnt) return cnt; } +int hook_read_list(struct list *hs, struct sample *smps[], unsigned cnt) +{ + return hook_run_list(hs, smps, cnt, hook_read); +} + +int hook_process_list(struct list *hs, struct sample *smps[], unsigned cnt) +{ + return hook_run_list(hs, smps, cnt, hook_process); +} + int hook_write_list(struct list *hs, struct sample *smps[], unsigned cnt) { - unsigned ret; - - for (size_t i = 0; i < list_length(hs); i++) { - struct hook *h = list_at(hs, i); - - ret = hook_write(h, smps, &cnt); - if (ret || !cnt) - /* Abort hook processing if earlier hooks removed all samples - * or they returned something non-zero */ - break; - } - - return cnt; + return hook_run_list(hs, smps, cnt, hook_write); } int hook_cmp_priority(const void *a, const void *b)