changeset 26726:e3129a5210e4

lib: Allow events to store internal pointers These pointers are independent of event fields, so they're ignored by event matching, exporting and importing. Their main purpose is to allow storing internal state to an event and allow it to be accessed by any code that can access the event.
author Timo Sirainen <timo.sirainen@open-xchange.com>
date Fri, 29 Nov 2019 15:25:21 +0200
parents f5c592fad74f
children 6fb3e5087326
files src/lib/lib-event-private.h src/lib/lib-event.c src/lib/lib-event.h
diffstat 3 files changed, 53 insertions(+), 3 deletions(-) [+]
line wrap: on
line diff
--- a/src/lib/lib-event-private.h	Wed Dec 04 19:39:10 2019 +0200
+++ b/src/lib/lib-event-private.h	Fri Nov 29 15:25:21 2019 +0200
@@ -1,6 +1,11 @@
 #ifndef LIB_EVENT_PRIVATE_H
 #define LIB_EVENT_PRIVATE_H
 
+struct event_pointer {
+	const char *key;
+	void *value;
+};
+
 struct event {
 	struct event_passthrough event_passthrough;
 	/* linked list of all events, newest first */
@@ -17,6 +22,7 @@
 	void *log_prefix_callback_context;
 	event_log_message_callback_t *log_message_callback;
 	void *log_message_callback_context;
+	ARRAY(struct event_pointer) pointers;
 	enum log_type min_log_level;
 	bool log_prefix_from_system_pool:1;
 	bool log_prefix_replace:1;
--- a/src/lib/lib-event.c	Wed Dec 04 19:39:10 2019 +0200
+++ b/src/lib/lib-event.c	Fri Nov 29 15:25:21 2019 +0200
@@ -591,6 +591,40 @@
 	return event->min_log_level;
 }
 
+struct event *event_set_ptr(struct event *event, const char *key, void *value)
+{
+	struct event_pointer *p;
+
+	if (!array_is_created(&event->pointers))
+		p_array_init(&event->pointers, event->pool, 4);
+	else {
+		/* replace existing pointer if the key already exists */
+		array_foreach_modifiable(&event->pointers, p) {
+			if (strcmp(p->key, key) == 0) {
+				p->value = value;
+				return event;
+			}
+		}
+	}
+	p = array_append_space(&event->pointers);
+	p->key = p_strdup(event->pool, key);
+	p->value = value;
+	return event;
+}
+
+void *event_get_ptr(struct event *event, const char *key)
+{
+	const struct event_pointer *p;
+
+	if (!array_is_created(&event->pointers))
+		return NULL;
+	array_foreach(&event->pointers, p) {
+		if (strcmp(p->key, key) == 0)
+			return p->value;
+	}
+	return NULL;
+}
+
 struct event_category *event_category_find_registered(const char *name)
 {
 	struct event_category *const *catp;
--- a/src/lib/lib-event.h	Wed Dec 04 19:39:10 2019 +0200
+++ b/src/lib/lib-event.h	Fri Nov 29 15:25:21 2019 +0200
@@ -100,19 +100,20 @@
    Only the fields in the events themselves are checked. Parent events' fields are not checked. */
 bool event_has_all_fields(struct event *event, const struct event *other);
 
-/* Returns the source event duplicated into a new event. */
+/* Returns the source event duplicated into a new event. Event pointers are
+   dropped. */
 struct event *event_dup(const struct event *source);
 /* Returns a flattened version of the source event.
    Both categories and fields will be flattened.
    A new reference to the source event is returned if no flattening was
-   needed. */
+   needed. Event pointers are dropped if a new event was created. */
 struct event *event_flatten(struct event *src);
 /* Returns a minimized version of the source event.
    Remove parents with no fields or categories, attempt to flatten fields
    and categories to avoid sending one-off parent events.  (There is a more
    detailed description in a comment above the function implementation.)
    A new reference to the source event is returned if no simplification
-   occured. */
+   occured. Event pointers are dropped if a new event was created. */
 struct event *event_minimize(struct event *src);
 /* Copy all categories from source to dest.
    Only the categories in source event itself are copied.
@@ -238,6 +239,15 @@
 struct event *event_set_min_log_level(struct event *event, enum log_type level);
 enum log_type event_get_min_log_level(const struct event *event);
 
+/* Add an internal pointer to an event. It can be looked up only with
+   event_get_ptr(). The keys are in their own namespace and won't conflict
+   with event fields. The pointers are specific to this specific event only -
+   they will be dropped from any duplicated/flattened/minimized events. */
+struct event *event_set_ptr(struct event *event, const char *key, void *value);
+/* Return a pointer set with event_set_ptr(), or NULL if it doesn't exist.
+   The pointer is looked up only from the event itself, not its parents. */
+void *event_get_ptr(struct event *event, const char *key);
+
 /* Add NULL-terminated list of categories to the event. The categories pointer
    doesn't need to stay valid afterwards, but the event_category structs
    themselves must be. Returns the event parameter. */