summary |
shortlog |
log |
commit | commitdiff |
review |
tree
raw |
patch |
inline | side by side (from parent 1:
769cec6)
Change-Id: I6c3e855030af9064335028e51d10c41db85a3f3c
Signed-off-by: José Bollo <jose.bollo@iot.bzh>
+/*
+ * Structure for event listeners
+ */
struct afb_evt_listener {
struct afb_evt_listener {
+
+ /* chaining listeners */
struct afb_evt_listener *next;
struct afb_evt_listener *next;
+
+ /* callback on event */
void (*send)(void *closure, const char *event, struct json_object *object);
void (*send)(void *closure, const char *event, struct json_object *object);
+
+ /* closure for the callback */
+
+ /* head of the list of events listened */
struct afb_evt_watch *watchs;
struct afb_evt_watch *watchs;
+
+ /* count of reference to the listener */
+/*
+ * Structure for describing events
+ */
+
+ /* head of the list of listeners watching the event */
struct afb_evt_watch *watchs;
struct afb_evt_watch *watchs;
+
+ /* name of the event */
+/*
+ * Structure for associating events and listeners
+ */
struct afb_evt_event *event;
struct afb_evt_event *event;
+
+ /* link to the next listener for the same event */
struct afb_evt_watch *next_by_event;
struct afb_evt_watch *next_by_event;
struct afb_evt_listener *listener;
struct afb_evt_listener *listener;
+
+ /* link to the next event for the same listener */
struct afb_evt_watch *next_by_listener;
};
struct afb_evt_watch *next_by_listener;
};
static int evt_broadcast(struct afb_evt_event *evt, struct json_object *obj);
static int evt_push(struct afb_evt_event *evt, struct json_object *obj);
static int evt_broadcast(struct afb_evt_event *evt, struct json_object *obj);
static int evt_push(struct afb_evt_event *evt, struct json_object *obj);
-static void evt_drop(struct afb_evt_event *evt);
+static void evt_destroy(struct afb_evt_event *evt);
+/* the interface for events */
static struct afb_event_itf afb_evt_event_itf = {
.broadcast = (void*)evt_broadcast,
.push = (void*)evt_push,
static struct afb_event_itf afb_evt_event_itf = {
.broadcast = (void*)evt_broadcast,
.push = (void*)evt_push,
- .drop = (void*)evt_drop
+ .drop = (void*)evt_destroy
+/* head of the list of listeners */
static struct afb_evt_listener *listeners = NULL;
static struct afb_evt_listener *listeners = NULL;
+/*
+ * Broadcasts the event 'evt' with its 'object'
+ * 'object' is released (like json_object_put)
+ * Returns the count of listener that received the event.
+ */
static int evt_broadcast(struct afb_evt_event *evt, struct json_object *object)
{
return afb_evt_broadcast(evt->name, object);
}
static int evt_broadcast(struct afb_evt_event *evt, struct json_object *object)
{
return afb_evt_broadcast(evt->name, object);
}
+/*
+ * Broadcasts the 'event' with its 'object'
+ * 'object' is released (like json_object_put)
+ * Returns the count of listener having receive the event.
+ */
int afb_evt_broadcast(const char *event, struct json_object *object)
{
int result;
int afb_evt_broadcast(const char *event, struct json_object *object)
{
int result;
while(listener) {
listener->send(listener->closure, event, json_object_get(object));
listener = listener->next;
while(listener) {
listener->send(listener->closure, event, json_object_get(object));
listener = listener->next;
}
json_object_put(object);
return result;
}
}
json_object_put(object);
return result;
}
+/*
+ * Broadcasts the event 'evt' with its 'object'
+ * 'object' is released (like json_object_put)
+ * Returns the count of listener taht received the event.
+ */
static int evt_push(struct afb_evt_event *evt, struct json_object *obj)
{
int result;
static int evt_push(struct afb_evt_event *evt, struct json_object *obj)
{
int result;
listener = watch->listener;
listener->send(listener->closure, evt->name, json_object_get(obj));
watch = watch->next_by_event;
listener = watch->listener;
listener->send(listener->closure, evt->name, json_object_get(obj));
watch = watch->next_by_event;
}
json_object_put(obj);
return result;
}
}
json_object_put(obj);
return result;
}
+/*
+ * remove the 'watch'
+ */
static void remove_watch(struct afb_evt_watch *watch)
{
struct afb_evt_watch **prv;
static void remove_watch(struct afb_evt_watch *watch)
{
struct afb_evt_watch **prv;
+ /* unlink the watch for its event */
prv = &watch->event->watchs;
while(*prv != watch)
prv = &(*prv)->next_by_event;
*prv = watch->next_by_event;
prv = &watch->event->watchs;
while(*prv != watch)
prv = &(*prv)->next_by_event;
*prv = watch->next_by_event;
+ /* unlink the watch for its listener */
prv = &watch->listener->watchs;
while(*prv != watch)
prv = &(*prv)->next_by_listener;
*prv = watch->next_by_listener;
prv = &watch->listener->watchs;
while(*prv != watch)
prv = &(*prv)->next_by_listener;
*prv = watch->next_by_listener;
-static void evt_drop(struct afb_evt_event *evt)
+/*
+ * Destroys the event 'evt'
+ */
+static void evt_destroy(struct afb_evt_event *evt)
+ /* removes all watchers */
while(evt->watchs != NULL)
remove_watch(evt->watchs);
free(evt);
}
}
while(evt->watchs != NULL)
remove_watch(evt->watchs);
free(evt);
}
}
+/*
+ * Creates an event of 'name' and returns it.
+ * Returns an event with closure==NULL in case of error.
+ */
struct afb_event afb_evt_create_event(const char *name)
{
size_t len;
struct afb_event afb_evt_create_event(const char *name)
{
size_t len;
return (struct afb_event){ .itf = &afb_evt_event_itf, .closure = evt };
}
return (struct afb_event){ .itf = &afb_evt_event_itf, .closure = evt };
}
+/*
+ * Returns an instance of the listener defined by the 'send' callback
+ * and the 'closure'.
+ * Returns NULL in case of memory depletion.
+ */
struct afb_evt_listener *afb_evt_listener_create(void (*send)(void *closure, const char *event, struct json_object *object), void *closure)
{
struct afb_evt_listener *listener;
struct afb_evt_listener *afb_evt_listener_create(void (*send)(void *closure, const char *event, struct json_object *object), void *closure)
{
struct afb_evt_listener *listener;
+/*
+ * Increases the reference count of 'listener' and returns it
+ */
struct afb_evt_listener *afb_evt_listener_addref(struct afb_evt_listener *listener)
{
listener->refcount++;
return listener;
}
struct afb_evt_listener *afb_evt_listener_addref(struct afb_evt_listener *listener)
{
listener->refcount++;
return listener;
}
+/*
+ * Decreases the reference count of the 'listener' and destroys it
+ * when no more used.
+ */
void afb_evt_listener_unref(struct afb_evt_listener *listener)
{
if (0 == --listener->refcount) {
void afb_evt_listener_unref(struct afb_evt_listener *listener)
{
if (0 == --listener->refcount) {
+/*
+ * Makes the 'listener' watching 'event'
+ * Returns 0 in case of success or else -1.
+ */
int afb_evt_add_watch(struct afb_evt_listener *listener, struct afb_event event)
{
struct afb_evt_watch *watch;
int afb_evt_add_watch(struct afb_evt_listener *listener, struct afb_event event)
{
struct afb_evt_watch *watch;
+/*
+ * Avoids the 'listener' to watch 'event'
+ * Returns 0 in case of success or else -1.
+ */
int afb_evt_remove_watch(struct afb_evt_listener *listener, struct afb_event event)
{
struct afb_evt_watch *watch;
int afb_evt_remove_watch(struct afb_evt_listener *listener, struct afb_event event)
{
struct afb_evt_watch *watch;