X-Git-Url: https://gerrit.automotivelinux.org/gerrit/gitweb?a=blobdiff_plain;f=src%2Fafb-evt.c;h=a75cbbcc2a9ce00aa139300dbec1415adb8fec23;hb=60cd11786766ebc148b7ec088962dd6e112f8762;hp=9937c1a681387a7b9ba9ffc6cf38a625eb96aeb1;hpb=1430e5aca4864a093534a0c91f056a97a4a26056;p=src%2Fapp-framework-binder.git diff --git a/src/afb-evt.c b/src/afb-evt.c index 9937c1a6..a75cbbcc 100644 --- a/src/afb-evt.c +++ b/src/afb-evt.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2015, 2016, 2017 "IoT.bzh" + * Copyright (C) 2015-2019 "IoT.bzh" * Author José Bollo * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -24,8 +24,8 @@ #include #include -#include -#include +#include +#include #include "afb-evt.h" #include "afb-hook.h" @@ -50,8 +50,8 @@ struct afb_evt_listener { /* head of the list of events listened */ struct afb_evt_watch *watchs; - /* mutex of the listener */ - pthread_mutex_t mutex; + /* rwlock of the listener */ + pthread_rwlock_t rwlock; /* count of reference to the listener */ int refcount; @@ -63,7 +63,7 @@ struct afb_evt_listener { struct afb_evtid { /* interface */ - struct afb_eventid eventid; + struct afb_event_x2 eventid; /* next event */ struct afb_evtid *next; @@ -71,11 +71,13 @@ struct afb_evtid { /* head of the list of listeners watching the event */ struct afb_evt_watch *watchs; - /* mutex of the event */ - pthread_mutex_t mutex; + /* rwlock of the event */ + pthread_rwlock_t rwlock; +#if WITH_AFB_HOOK /* hooking */ int hookflags; +#endif /* refcount */ int refcount; @@ -84,7 +86,7 @@ struct afb_evtid { int id; /* fullname of the event */ - char fullname[1]; + char fullname[]; }; /* @@ -109,7 +111,7 @@ struct afb_evt_watch { }; /* the interface for events */ -static struct afb_eventid_itf afb_evt_eventid_itf = { +static struct afb_event_x2_itf afb_evt_event_x2_itf = { .broadcast = (void*)afb_evt_evtid_broadcast, .push = (void*)afb_evt_evtid_push, .unref = (void*)afb_evt_evtid_unref, @@ -117,21 +119,23 @@ static struct afb_eventid_itf afb_evt_eventid_itf = { .addref = (void*)afb_evt_evtid_addref }; +#if WITH_AFB_HOOK /* the interface for events */ -static struct afb_eventid_itf afb_evt_hooked_eventid_itf = { +static struct afb_event_x2_itf afb_evt_hooked_event_x2_itf = { .broadcast = (void*)afb_evt_evtid_hooked_broadcast, .push = (void*)afb_evt_evtid_hooked_push, .unref = (void*)afb_evt_evtid_hooked_unref, .name = (void*)afb_evt_evtid_hooked_name, .addref = (void*)afb_evt_evtid_hooked_addref }; +#endif /* head of the list of listeners */ -static pthread_mutex_t listeners_mutex = PTHREAD_MUTEX_INITIALIZER; +static pthread_rwlock_t listeners_rwlock = PTHREAD_RWLOCK_INITIALIZER; static struct afb_evt_listener *listeners = NULL; /* handling id of events */ -static pthread_mutex_t events_mutex = PTHREAD_MUTEX_INITIALIZER; +static pthread_rwlock_t events_rwlock = PTHREAD_RWLOCK_INITIALIZER; static struct afb_evtid *evtids = NULL; static int event_id_counter = 0; static int event_id_wrapped = 0; @@ -147,7 +151,8 @@ static int broadcast(const char *event, struct json_object *obj, int id) struct afb_evt_listener *listener; result = 0; - pthread_mutex_lock(&listeners_mutex); + + pthread_rwlock_rdlock(&listeners_rwlock); listener = listeners; while(listener) { if (listener->itf->broadcast != NULL) { @@ -156,11 +161,22 @@ static int broadcast(const char *event, struct json_object *obj, int id) } listener = listener->next; } - pthread_mutex_unlock(&listeners_mutex); + pthread_rwlock_unlock(&listeners_rwlock); json_object_put(obj); return result; } +/* + * Broadcasts the event 'evtid' with its 'object' + * 'object' is released (like json_object_put) + * Returns the count of listener that received the event. + */ +int afb_evt_evtid_broadcast(struct afb_evtid *evtid, struct json_object *object) +{ + return broadcast(evtid->fullname, object, evtid->id); +} + +#if WITH_AFB_HOOK /* * Broadcasts the 'event' of 'id' with its 'obj' * 'obj' is released (like json_object_put) @@ -186,16 +202,6 @@ static int hooked_broadcast(const char *event, struct json_object *obj, int id, return result; } -/* - * Broadcasts the event 'evtid' with its 'object' - * 'object' is released (like json_object_put) - * Returns the count of listener that received the event. - */ -int afb_evt_evtid_broadcast(struct afb_evtid *evtid, struct json_object *object) -{ - return broadcast(evtid->fullname, object, evtid->id); -} - /* * Broadcasts the event 'evtid' with its 'object' * 'object' is released (like json_object_put) @@ -205,6 +211,7 @@ int afb_evt_evtid_hooked_broadcast(struct afb_evtid *evtid, struct json_object * { return hooked_broadcast(evtid->fullname, object, evtid->id, evtid->hookflags); } +#endif /* * Broadcasts the 'event' with its 'object' @@ -213,7 +220,11 @@ int afb_evt_evtid_hooked_broadcast(struct afb_evtid *evtid, struct json_object * */ int afb_evt_broadcast(const char *event, struct json_object *object) { +#if WITH_AFB_HOOK return hooked_broadcast(event, object, 0, -1); +#else + return broadcast(event, object, 0); +#endif } /* @@ -228,7 +239,7 @@ int afb_evt_evtid_push(struct afb_evtid *evtid, struct json_object *obj) struct afb_evt_listener *listener; result = 0; - pthread_mutex_lock(&evtid->mutex); + pthread_rwlock_rdlock(&evtid->rwlock); watch = evtid->watchs; while(watch) { listener = watch->listener; @@ -239,36 +250,7 @@ int afb_evt_evtid_push(struct afb_evtid *evtid, struct json_object *obj) } watch = watch->next_by_evtid; } - pthread_mutex_unlock(&evtid->mutex); - json_object_put(obj); - return result; -} - -/* - * Pushes the event 'evtid' with 'obj' to its listeners - * 'obj' is released (like json_object_put) - * Emits calls to hooks. - * Returns the count of listener taht received the event. - */ -int afb_evt_evtid_hooked_push(struct afb_evtid *evtid, struct json_object *obj) -{ - int result; - - /* lease the object */ - json_object_get(obj); - - /* hook before push */ - if (evtid->hookflags & afb_hook_flag_evt_push_before) - afb_hook_evt_push_before(evtid->fullname, evtid->id, obj); - - /* push */ - result = afb_evt_evtid_push(evtid, obj); - - /* hook after push */ - if (evtid->hookflags & afb_hook_flag_evt_push_after) - afb_hook_evt_push_after(evtid->fullname, evtid->id, obj, result); - - /* release the object */ + pthread_rwlock_unlock(&evtid->rwlock); json_object_put(obj); return result; } @@ -314,12 +296,12 @@ struct afb_evtid *afb_evt_evtid_create(const char *fullname) /* allocates the event */ len = strlen(fullname); - evtid = malloc(len + sizeof * evtid); + evtid = malloc(len + 1 + sizeof * evtid); if (evtid == NULL) goto error; /* allocates the id */ - pthread_mutex_lock(&events_mutex); + pthread_rwlock_wrlock(&events_rwlock); do { if (++event_id_counter < 0) { event_id_wrapped = 1; @@ -335,15 +317,20 @@ struct afb_evtid *afb_evt_evtid_create(const char *fullname) /* initialize the event */ memcpy(evtid->fullname, fullname, len + 1); evtid->next = evtids; + evtid->refcount = 1; evtid->watchs = NULL; evtid->id = event_id_counter; - pthread_mutex_init(&evtid->mutex, NULL); + pthread_rwlock_init(&evtid->rwlock, NULL); evtids = evtid; +#if WITH_AFB_HOOK evtid->hookflags = afb_hook_flags_evt(evtid->fullname); - evtid->eventid.itf = evtid->hookflags ? &afb_evt_hooked_eventid_itf : &afb_evt_eventid_itf; + evtid->eventid.itf = evtid->hookflags ? &afb_evt_hooked_event_x2_itf : &afb_evt_event_x2_itf; if (evtid->hookflags & afb_hook_flag_evt_create) afb_hook_evt_create(evtid->fullname, evtid->id); - pthread_mutex_unlock(&events_mutex); +#else + evtid->eventid.itf = &afb_evt_event_x2_itf; +#endif + pthread_rwlock_unlock(&events_rwlock); /* returns the event */ return evtid; @@ -352,22 +339,32 @@ error: } /* - * increment the reference count of the event 'evtid' + * Creates an event of name 'prefix'/'name' and returns it or NULL on error. */ -struct afb_evtid *afb_evt_evtid_addref(struct afb_evtid *evtid) +struct afb_evtid *afb_evt_evtid_create2(const char *prefix, const char *name) { - __atomic_add_fetch(&evtid->refcount, 1, __ATOMIC_RELAXED); - return evtid; + size_t prelen, postlen; + char *fullname; + + /* makes the event fullname */ + prelen = strlen(prefix); + postlen = strlen(name); + fullname = alloca(prelen + postlen + 2); + memcpy(fullname, prefix, prelen); + fullname[prelen] = '/'; + memcpy(fullname + prelen + 1, name, postlen + 1); + + /* create the event */ + return afb_evt_evtid_create(fullname); } /* * increment the reference count of the event 'evtid' */ -struct afb_evtid *afb_evt_evtid_hooked_addref(struct afb_evtid *evtid) +struct afb_evtid *afb_evt_evtid_addref(struct afb_evtid *evtid) { - if (evtid->hookflags & afb_hook_flag_evt_addref) - afb_hook_evt_addref(evtid->fullname, evtid->id); - return afb_evt_evtid_addref(evtid); + __atomic_add_fetch(&evtid->refcount, 1, __ATOMIC_RELAXED); + return evtid; } /* @@ -382,14 +379,14 @@ void afb_evt_evtid_unref(struct afb_evtid *evtid) if (!__atomic_sub_fetch(&evtid->refcount, 1, __ATOMIC_RELAXED)) { /* unlinks the event if valid! */ - pthread_mutex_lock(&events_mutex); + pthread_rwlock_wrlock(&events_rwlock); found = 0; prv = &evtids; while (*prv && !(found = (*prv == evtid))) prv = &(*prv)->next; if (found) *prv = evtid->next; - pthread_mutex_unlock(&events_mutex); + pthread_rwlock_unlock(&events_rwlock); /* destroys the event */ if (!found) @@ -398,31 +395,20 @@ void afb_evt_evtid_unref(struct afb_evtid *evtid) /* removes all watchers */ while(evtid->watchs != NULL) { listener = evtid->watchs->listener; - pthread_mutex_lock(&listener->mutex); - pthread_mutex_lock(&evtid->mutex); + pthread_rwlock_wrlock(&listener->rwlock); + pthread_rwlock_wrlock(&evtid->rwlock); remove_watch(evtid->watchs); - pthread_mutex_unlock(&evtid->mutex); - pthread_mutex_unlock(&listener->mutex); + pthread_rwlock_unlock(&evtid->rwlock); + pthread_rwlock_unlock(&listener->rwlock); } /* free */ - pthread_mutex_destroy(&evtid->mutex); + pthread_rwlock_destroy(&evtid->rwlock); free(evtid); } } } -/* - * decrement the reference count of the event 'evtid' - * and destroy it when the count reachs zero - */ -void afb_evt_evtid_hooked_unref(struct afb_evtid *evtid) -{ - if (evtid->hookflags & afb_hook_flag_evt_unref) - afb_hook_evt_unref(evtid->fullname, evtid->id); - afb_evt_evtid_unref(evtid); -} - /* * Returns the true name of the 'event' */ @@ -440,17 +426,6 @@ const char *afb_evt_evtid_name(struct afb_evtid *evtid) return name ? name + 1 : evtid->fullname; } -/* - * Returns the name associated to the event 'evtid'. - */ -const char *afb_evt_evtid_hooked_name(struct afb_evtid *evtid) -{ - const char *result = afb_evt_evtid_name(evtid); - if (evtid->hookflags & afb_hook_flag_evt_name) - afb_hook_evt_name(evtid->fullname, evtid->id, result); - return result; -} - /* * Returns the id of the 'event' */ @@ -469,7 +444,7 @@ struct afb_evt_listener *afb_evt_listener_create(const struct afb_evt_itf *itf, struct afb_evt_listener *listener; /* search if an instance already exists */ - pthread_mutex_lock(&listeners_mutex); + pthread_rwlock_wrlock(&listeners_rwlock); listener = listeners; while (listener != NULL) { if (listener->itf == itf && listener->closure == closure) { @@ -487,12 +462,12 @@ struct afb_evt_listener *afb_evt_listener_create(const struct afb_evt_itf *itf, listener->closure = closure; listener->watchs = NULL; listener->refcount = 1; - pthread_mutex_init(&listener->mutex, NULL); + pthread_rwlock_init(&listener->rwlock, NULL); listener->next = listeners; listeners = listener; } found: - pthread_mutex_unlock(&listeners_mutex); + pthread_rwlock_unlock(&listeners_rwlock); return listener; } @@ -514,28 +489,28 @@ void afb_evt_listener_unref(struct afb_evt_listener *listener) struct afb_evt_listener **prv; struct afb_evtid *evtid; - if (!__atomic_sub_fetch(&listener->refcount, 1, __ATOMIC_RELAXED)) { + if (listener && !__atomic_sub_fetch(&listener->refcount, 1, __ATOMIC_RELAXED)) { /* unlink the listener */ - pthread_mutex_lock(&listeners_mutex); + pthread_rwlock_wrlock(&listeners_rwlock); prv = &listeners; while (*prv != listener) prv = &(*prv)->next; *prv = listener->next; - pthread_mutex_unlock(&listeners_mutex); + pthread_rwlock_unlock(&listeners_rwlock); /* remove the watchers */ - pthread_mutex_lock(&listener->mutex); + pthread_rwlock_wrlock(&listener->rwlock); while (listener->watchs != NULL) { evtid = listener->watchs->evtid; - pthread_mutex_lock(&evtid->mutex); + pthread_rwlock_wrlock(&evtid->rwlock); remove_watch(listener->watchs); - pthread_mutex_unlock(&evtid->mutex); + pthread_rwlock_unlock(&evtid->rwlock); } - pthread_mutex_unlock(&listener->mutex); + pthread_rwlock_unlock(&listener->rwlock); /* free the listener */ - pthread_mutex_destroy(&listener->mutex); + pthread_rwlock_destroy(&listener->rwlock); free(listener); } } @@ -555,7 +530,7 @@ int afb_evt_watch_add_evtid(struct afb_evt_listener *listener, struct afb_evtid } /* search the existing watch for the listener */ - pthread_mutex_lock(&listener->mutex); + pthread_rwlock_wrlock(&listener->rwlock); watch = listener->watchs; while(watch != NULL) { if (watch->evtid == evtid) @@ -566,7 +541,7 @@ int afb_evt_watch_add_evtid(struct afb_evt_listener *listener, struct afb_evtid /* not found, allocate a new */ watch = malloc(sizeof *watch); if (watch == NULL) { - pthread_mutex_unlock(&listener->mutex); + pthread_rwlock_unlock(&listener->rwlock); errno = ENOMEM; return -1; } @@ -577,16 +552,16 @@ int afb_evt_watch_add_evtid(struct afb_evt_listener *listener, struct afb_evtid watch->listener = listener; watch->next_by_listener = listener->watchs; listener->watchs = watch; - pthread_mutex_lock(&evtid->mutex); + pthread_rwlock_wrlock(&evtid->rwlock); watch->next_by_evtid = evtid->watchs; evtid->watchs = watch; - pthread_mutex_unlock(&evtid->mutex); + pthread_rwlock_unlock(&evtid->rwlock); found: if (watch->activity == 0 && listener->itf->add != NULL) listener->itf->add(listener->closure, evtid->fullname, evtid->id); watch->activity++; - pthread_mutex_unlock(&listener->mutex); + pthread_rwlock_unlock(&listener->rwlock); return 0; } @@ -600,7 +575,7 @@ int afb_evt_watch_sub_evtid(struct afb_evt_listener *listener, struct afb_evtid struct afb_evt_watch *watch; /* search the existing watch */ - pthread_mutex_lock(&listener->mutex); + pthread_rwlock_wrlock(&listener->rwlock); watch = listener->watchs; while(watch != NULL) { if (watch->evtid == evtid) { @@ -609,37 +584,22 @@ int afb_evt_watch_sub_evtid(struct afb_evt_listener *listener, struct afb_evtid if (watch->activity == 0 && listener->itf->remove != NULL) listener->itf->remove(listener->closure, evtid->fullname, evtid->id); } - pthread_mutex_unlock(&listener->mutex); + pthread_rwlock_unlock(&listener->rwlock); return 0; } watch = watch->next_by_listener; } - pthread_mutex_unlock(&listener->mutex); + pthread_rwlock_unlock(&listener->rwlock); errno = ENOENT; return -1; } -/* - * update the hooks for events - */ -void afb_evt_update_hooks() -{ - struct afb_evtid *evtid; - - pthread_mutex_lock(&events_mutex); - for (evtid = evtids ; evtid ; evtid = evtid->next) { - evtid->hookflags = afb_hook_flags_evt(evtid->fullname); - evtid->eventid.itf = evtid->hookflags ? &afb_evt_hooked_eventid_itf : &afb_evt_eventid_itf; - } - pthread_mutex_unlock(&events_mutex); -} - -inline struct afb_evtid *afb_evt_eventid_to_evtid(struct afb_eventid *eventid) +inline struct afb_evtid *afb_evt_event_x2_to_evtid(struct afb_event_x2 *eventid) { return (struct afb_evtid*)eventid; } -inline struct afb_eventid *afb_evt_eventid_from_evtid(struct afb_evtid *evtid) +inline struct afb_event_x2 *afb_evt_event_x2_from_evtid(struct afb_evtid *evtid) { return &evtid->eventid; } @@ -648,26 +608,35 @@ inline struct afb_eventid *afb_evt_eventid_from_evtid(struct afb_evtid *evtid) * Creates an event of 'fullname' and returns it. * Returns an event with closure==NULL in case of error. */ -struct afb_eventid *afb_evt_eventid_create(const char *fullname) +struct afb_event_x2 *afb_evt_event_x2_create(const char *fullname) +{ + return afb_evt_event_x2_from_evtid(afb_evt_evtid_create(fullname)); +} + +/* + * Creates an event of name 'prefix'/'name' and returns it. + * Returns an event with closure==NULL in case of error. + */ +struct afb_event_x2 *afb_evt_event_x2_create2(const char *prefix, const char *name) { - return afb_evt_eventid_from_evtid(afb_evt_evtid_create(fullname)); + return afb_evt_event_x2_from_evtid(afb_evt_evtid_create2(prefix, name)); } /* * Returns the fullname of the 'eventid' */ -const char *afb_evt_eventid_fullname(struct afb_eventid *eventid) +const char *afb_evt_event_x2_fullname(struct afb_event_x2 *eventid) { - struct afb_evtid *evtid = afb_evt_eventid_to_evtid(eventid); + struct afb_evtid *evtid = afb_evt_event_x2_to_evtid(eventid); return evtid ? evtid->fullname : NULL; } /* * Returns the id of the 'eventid' */ -int afb_evt_eventid_id(struct afb_eventid *eventid) +int afb_evt_event_x2_id(struct afb_event_x2 *eventid) { - struct afb_evtid *evtid = afb_evt_eventid_to_evtid(eventid); + struct afb_evtid *evtid = afb_evt_event_x2_to_evtid(eventid); return evtid ? evtid->id : 0; } @@ -675,9 +644,9 @@ int afb_evt_eventid_id(struct afb_eventid *eventid) * Makes the 'listener' watching 'eventid' * Returns 0 in case of success or else -1. */ -int afb_evt_eventid_add_watch(struct afb_evt_listener *listener, struct afb_eventid *eventid) +int afb_evt_event_x2_add_watch(struct afb_evt_listener *listener, struct afb_event_x2 *eventid) { - struct afb_evtid *evtid = afb_evt_eventid_to_evtid(eventid); + struct afb_evtid *evtid = afb_evt_event_x2_to_evtid(eventid); /* check parameter */ if (!evtid) { @@ -693,9 +662,9 @@ int afb_evt_eventid_add_watch(struct afb_evt_listener *listener, struct afb_even * Avoids the 'listener' to watch 'eventid' * Returns 0 in case of success or else -1. */ -int afb_evt_eventid_remove_watch(struct afb_evt_listener *listener, struct afb_eventid *eventid) +int afb_evt_event_x2_remove_watch(struct afb_evt_listener *listener, struct afb_event_x2 *eventid) { - struct afb_evtid *evtid = afb_evt_eventid_to_evtid(eventid); + struct afb_evtid *evtid = afb_evt_event_x2_to_evtid(eventid); /* check parameter */ if (!evtid) { @@ -707,43 +676,132 @@ int afb_evt_eventid_remove_watch(struct afb_evt_listener *listener, struct afb_e return afb_evt_watch_sub_evtid(listener, evtid); } -int afb_evt_eventid_push(struct afb_eventid *eventid, struct json_object *object) +int afb_evt_event_x2_push(struct afb_event_x2 *eventid, struct json_object *object) +#if WITH_AFB_HOOK { - struct afb_evtid *evtid = afb_evt_eventid_to_evtid(eventid); + struct afb_evtid *evtid = afb_evt_event_x2_to_evtid(eventid); if (evtid) return afb_evt_evtid_hooked_push(evtid, object); json_object_put(object); return 0; } +#else + __attribute__((alias("afb_evt_event_x2_unhooked_push"))); +#endif -int afb_evt_eventid_unhooked_push(struct afb_eventid *eventid, struct json_object *object) +int afb_evt_event_x2_unhooked_push(struct afb_event_x2 *eventid, struct json_object *object) { - struct afb_evtid *evtid = afb_evt_eventid_to_evtid(eventid); + struct afb_evtid *evtid = afb_evt_event_x2_to_evtid(eventid); if (evtid) return afb_evt_evtid_push(evtid, object); json_object_put(object); return 0; } -struct afb_event afb_evt_event_from_evtid(struct afb_evtid *evtid) +#if WITH_LEGACY_BINDING_V1 || WITH_LEGACY_BINDING_V2 +struct afb_event_x1 afb_evt_event_from_evtid(struct afb_evtid *evtid) { return evtid - ? (struct afb_event){ .itf = &afb_evt_hooked_eventid_itf, .closure = &evtid->eventid } - : (struct afb_event){ .itf = NULL, .closure = NULL }; +#if WITH_AFB_HOOK + ? (struct afb_event_x1){ .itf = &afb_evt_hooked_event_x2_itf, .closure = &evtid->eventid } +#else + ? (struct afb_event_x1){ .itf = &afb_evt_event_x2_itf, .closure = &evtid->eventid } +#endif + : (struct afb_event_x1){ .itf = NULL, .closure = NULL }; } +#endif -void afb_evt_eventid_unref(struct afb_eventid *eventid) +void afb_evt_event_x2_unref(struct afb_event_x2 *eventid) { - struct afb_evtid *evtid = afb_evt_eventid_to_evtid(eventid); + struct afb_evtid *evtid = afb_evt_event_x2_to_evtid(eventid); if (evtid) afb_evt_evtid_unref(evtid); } -struct afb_eventid *afb_evt_eventid_addref(struct afb_eventid *eventid) +struct afb_event_x2 *afb_evt_event_x2_addref(struct afb_event_x2 *eventid) { - struct afb_evtid *evtid = afb_evt_eventid_to_evtid(eventid); + struct afb_evtid *evtid = afb_evt_event_x2_to_evtid(eventid); if (evtid) afb_evt_evtid_addref(evtid); return eventid; } +#if WITH_AFB_HOOK +/* + * Pushes the event 'evtid' with 'obj' to its listeners + * 'obj' is released (like json_object_put) + * Emits calls to hooks. + * Returns the count of listener taht received the event. + */ +int afb_evt_evtid_hooked_push(struct afb_evtid *evtid, struct json_object *obj) +{ + + int result; + + /* lease the object */ + json_object_get(obj); + + /* hook before push */ + if (evtid->hookflags & afb_hook_flag_evt_push_before) + afb_hook_evt_push_before(evtid->fullname, evtid->id, obj); + + /* push */ + result = afb_evt_evtid_push(evtid, obj); + + /* hook after push */ + if (evtid->hookflags & afb_hook_flag_evt_push_after) + afb_hook_evt_push_after(evtid->fullname, evtid->id, obj, result); + + /* release the object */ + json_object_put(obj); + return result; +} + +/* + * increment the reference count of the event 'evtid' + */ +struct afb_evtid *afb_evt_evtid_hooked_addref(struct afb_evtid *evtid) +{ + if (evtid->hookflags & afb_hook_flag_evt_addref) + afb_hook_evt_addref(evtid->fullname, evtid->id); + return afb_evt_evtid_addref(evtid); +} + +/* + * decrement the reference count of the event 'evtid' + * and destroy it when the count reachs zero + */ +void afb_evt_evtid_hooked_unref(struct afb_evtid *evtid) +{ + if (evtid->hookflags & afb_hook_flag_evt_unref) + afb_hook_evt_unref(evtid->fullname, evtid->id); + afb_evt_evtid_unref(evtid); +} + +/* + * Returns the name associated to the event 'evtid'. + */ +const char *afb_evt_evtid_hooked_name(struct afb_evtid *evtid) +{ + const char *result = afb_evt_evtid_name(evtid); + if (evtid->hookflags & afb_hook_flag_evt_name) + afb_hook_evt_name(evtid->fullname, evtid->id, result); + return result; +} + +/* + * update the hooks for events + */ +void afb_evt_update_hooks() +{ + struct afb_evtid *evtid; + + pthread_rwlock_rdlock(&events_rwlock); + for (evtid = evtids ; evtid ; evtid = evtid->next) { + evtid->hookflags = afb_hook_flags_evt(evtid->fullname); + evtid->eventid.itf = evtid->hookflags ? &afb_evt_hooked_event_x2_itf : &afb_evt_event_x2_itf; + } + pthread_rwlock_unlock(&events_rwlock); +} +#endif +