tor
master
|
Macros to implement publish/subscribe abstractions. More...
#include "torint.h"
Go to the source code of this file.
Data Structures | |
struct | pubsub_subscriber_t |
struct | pubsub_topic_t |
Macros | |
#define | SUBSCRIBE_ATSTART (1u<<0) |
#define | DECLARE_PUBSUB_STRUCT_TYPES(name) |
#define | DECLARE_PUBSUB_TOPIC(name) |
#define | DECLARE_NOTIFY_PUBSUB_TOPIC(linkage, name) |
#define | IMPLEMENT_PUBSUB_TOPIC(notify_linkage, name) |
Typedefs | |
typedef int(* | pubsub_subscriber_fn_t) (void *, void *) |
typedef struct pubsub_subscriber_t | pubsub_subscriber_t |
typedef struct pubsub_topic_t | pubsub_topic_t |
typedef int(* | pubsub_notify_fn_t) (pubsub_subscriber_t *subscriber, void *notify_data) |
Functions | |
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) |
int | pubsub_notify_ (pubsub_topic_t *topic, pubsub_notify_fn_t notify_fn, void *notify_data, unsigned notify_flags) |
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.
#define DECLARE_NOTIFY_PUBSUB_TOPIC | ( | linkage, | |
name | |||
) |
#define DECLARE_PUBSUB_STRUCT_TYPES | ( | name | ) |
#define DECLARE_PUBSUB_TOPIC | ( | name | ) |
#define SUBSCRIBE_ATSTART (1u<<0) |
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.
typedef int(* pubsub_subscriber_fn_t) (void *, 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 struct pubsub_subscriber_t pubsub_subscriber_t |
Helper type to implement pubsub abstraction. Don't use this directly. It represents a subscriber.
typedef struct pubsub_topic_t pubsub_topic_t |
Helper type to implement pubsub abstraction. Don't use this directly. It represents a topic, and keeps a record of subscribers.
void pubsub_clear_ | ( | pubsub_topic_t * | topic | ) |
Release all storage held by topic.
int pubsub_notify_ | ( | pubsub_topic_t * | topic, |
pubsub_notify_fn_t | notify_fn, | ||
void * | event_data, | ||
unsigned | notify_flags | ||
) |
For every subscriber s in topic, invoke notify_fn on s and event_data. Return 0 if there were no nonzero return values, and -1 if there were any.
const pubsub_subscriber_t* pubsub_subscribe_ | ( | pubsub_topic_t * | topic, |
pubsub_subscriber_fn_t | fn, | ||
void * | subscriber_data, | ||
unsigned | subscribe_flags, | ||
unsigned | priority | ||
) |
Add a new subscriber to topic, where (when an event is triggered), we'll notify the function fn by passing it subscriber_data. Return a handle to the subscribe which can later be passed to pubsub_unsubscribe_().
Functions are called in priority order, from lowest to highest.
See pubsub.h for subscribe_flags.
int pubsub_unsubscribe_ | ( | pubsub_topic_t * | topic, |
const pubsub_subscriber_t * | s | ||
) |
Remove the subscriber s from topic. After calling this function, s may no longer be used.