diff options
Diffstat (limited to 'src/common/pubsub.h')
-rw-r--r-- | src/common/pubsub.h | 179 |
1 files changed, 0 insertions, 179 deletions
diff --git a/src/common/pubsub.h b/src/common/pubsub.h deleted file mode 100644 index 2bee3af085..0000000000 --- a/src/common/pubsub.h +++ /dev/null @@ -1,179 +0,0 @@ -/* Copyright (c) 2016-2017, The Tor Project, Inc. */ -/* See LICENSE for licensing information */ - -/** - * \file pubsub.h - * \brief Macros to implement publish/subscribe abstractions. - * - * To use these macros, call DECLARE_PUBSUB_TOPIC() with an identifier to use - * as your topic. Below, I'm going to assume you say DECLARE_PUBSUB_TOPIC(T). - * - * Doing this will declare the following types: - * typedef struct T_event_data_t T_event_data_t; // you define this struct - * typedef struct T_subscriber_data_t T_subscriber_data_t; // this one too. - * typedef struct T_subscriber_t T_subscriber_t; // opaque - * typedef int (*T_subscriber_fn_t)(T_event_data_t*, T_subscriber_data_t*); - * - * and it will declare the following functions: - * const T_subscriber_t *T_subscribe(T_subscriber_fn_t, - * T_subscriber_data_t *, - * unsigned flags, - * unsigned priority); - * int T_unsubscribe(const T_subscriber_t *) - * - * Elsewhere you can say DECLARE_NOTIFY_PUBSUB_TOPIC(static, T), which - * declares: - * - * static int T_notify(T_event_data_t *, unsigned notify_flags); - * static void T_clear(void); - * - * And in some C file, you would define these functions with: - * IMPLEMENT_PUBSUB_TOPIC(static, T). - * - * The implementations will be small typesafe wrappers over generic versions - * of the above functions. - * - * To use the typesafe functions, you add any number of subscribers with - * T_subscribe(). Each has an associated function pointer, data pointer, - * and priority. Later, you can invoke T_notify() to declare that the - * event has occurred. Each of the subscribers will be invoked once. - **/ - -#ifndef TOR_PUBSUB_H -#define TOR_PUBSUB_H - -#include "torint.h" - -/** - * Flag for T_subscribe: die with an assertion failure if the event - * have ever been published before. Used when a subscriber must absolutely - * never have missed an event. - */ -#define SUBSCRIBE_ATSTART (1u<<0) - -#define DECLARE_PUBSUB_STRUCT_TYPES(name) \ - /* You define this type. */ \ - typedef struct name ## _event_data_t name ## _event_data_t; \ - /* You define this type. */ \ - typedef struct name ## _subscriber_data_t name ## _subscriber_data_t; - -#define DECLARE_PUBSUB_TOPIC(name) \ - /* This type is opaque. */ \ - typedef struct name ## _subscriber_t name ## _subscriber_t; \ - /* You declare functions matching this type. */ \ - typedef int (*name ## _subscriber_fn_t)( \ - name ## _event_data_t *data, \ - name ## _subscriber_data_t *extra); \ - /* Call this function to subscribe to a topic. */ \ - const name ## _subscriber_t *name ## _subscribe( \ - name##_subscriber_fn_t subscriber, \ - name##_subscriber_data_t *extra_data, \ - unsigned flags, \ - unsigned priority); \ - /* Call this function to unsubscribe from a topic. */ \ - int name ## _unsubscribe(const name##_subscriber_t *s); - -#define DECLARE_NOTIFY_PUBSUB_TOPIC(linkage, name) \ - /* Call this function to notify all subscribers. Flags not yet used. */ \ - linkage int name ## _notify(name ## _event_data_t *data, unsigned flags); \ - /* Call this function to release storage held by the topic. */ \ - linkage void name ## _clear(void); - -/** - * Type used to hold a generic function for a subscriber. - * - * [Yes, it is safe to cast to this, so long as we cast back to the original - * type before calling. From C99: "A pointer to a function of one type may be - * converted to a pointer to a function of another type and back again; the - * result shall compare equal to the original pointer."] -*/ -typedef int (*pubsub_subscriber_fn_t)(void *, void *); - -/** - * Helper type to implement pubsub abstraction. Don't use this directly. - * It represents a subscriber. - */ -typedef struct pubsub_subscriber_t { - /** Function to invoke when the event triggers. */ - pubsub_subscriber_fn_t fn; - /** Data associated with this subscriber. */ - void *subscriber_data; - /** Priority for this subscriber. Low priorities happen first. */ - unsigned priority; - /** Flags set on this subscriber. Not yet used.*/ - unsigned subscriber_flags; -} pubsub_subscriber_t; - -/** - * Helper type to implement pubsub abstraction. Don't use this directly. - * It represents a topic, and keeps a record of subscribers. - */ -typedef struct pubsub_topic_t { - /** List of subscribers to this topic. May be NULL. */ - struct smartlist_t *subscribers; - /** Total number of times that pubsub_notify_() has ever been called on this - * topic. */ - uint64_t n_events_fired; - /** True iff we're running 'notify' on this topic, and shouldn't allow - * any concurrent modifications or events. */ - unsigned locked; -} pubsub_topic_t; - -const pubsub_subscriber_t *pubsub_subscribe_(pubsub_topic_t *topic, - pubsub_subscriber_fn_t fn, - void *subscriber_data, - unsigned subscribe_flags, - unsigned priority); -int pubsub_unsubscribe_(pubsub_topic_t *topic, const pubsub_subscriber_t *sub); -void pubsub_clear_(pubsub_topic_t *topic); -typedef int (*pubsub_notify_fn_t)(pubsub_subscriber_t *subscriber, - void *notify_data); -int pubsub_notify_(pubsub_topic_t *topic, pubsub_notify_fn_t notify_fn, - void *notify_data, unsigned notify_flags); - -#define IMPLEMENT_PUBSUB_TOPIC(notify_linkage, name) \ - static pubsub_topic_t name ## _topic_ = { NULL, 0, 0 }; \ - const name ## _subscriber_t * \ - name ## _subscribe(name##_subscriber_fn_t subscriber, \ - name##_subscriber_data_t *extra_data, \ - unsigned flags, \ - unsigned priority) \ - { \ - const pubsub_subscriber_t *s; \ - s = pubsub_subscribe_(&name##_topic_, \ - (pubsub_subscriber_fn_t)subscriber, \ - extra_data, \ - flags, \ - priority); \ - return (const name##_subscriber_t *)s; \ - } \ - int \ - name ## _unsubscribe(const name##_subscriber_t *subscriber) \ - { \ - return pubsub_unsubscribe_(&name##_topic_, \ - (const pubsub_subscriber_t *)subscriber); \ - } \ - static int \ - name##_call_the_notify_fn_(pubsub_subscriber_t *subscriber, \ - void *notify_data) \ - { \ - name ## _subscriber_fn_t fn; \ - fn = (name ## _subscriber_fn_t) subscriber->fn; \ - return fn(notify_data, subscriber->subscriber_data); \ - } \ - notify_linkage int \ - name ## _notify(name ## _event_data_t *event_data, unsigned flags) \ - { \ - return pubsub_notify_(&name##_topic_, \ - name##_call_the_notify_fn_, \ - event_data, \ - flags); \ - } \ - notify_linkage void \ - name ## _clear(void) \ - { \ - pubsub_clear_(&name##_topic_); \ - } - -#endif /* !defined(TOR_PUBSUB_H) */ - |