+ struct afb_evt_watch *watch, **pwatch;
+
+ /* search the existing watch */
+ pthread_rwlock_wrlock(&listener->rwlock);
+ pwatch = &listener->watchs;
+ for (;;) {
+ watch = *pwatch;
+ if (!watch) {
+ pthread_rwlock_unlock(&listener->rwlock);
+ errno = ENOENT;
+ return -1;
+ }
+ if (evtid == watch->evtid) {
+ *pwatch = watch->next_by_listener;
+ pthread_rwlock_unlock(&listener->rwlock);
+ listener_unwatch(listener, evtid, watch, 1);
+ return 0;
+ }
+ pwatch = &watch->next_by_listener;
+ }
+}
+
+/*
+ * Avoids the 'listener' to watch 'eventid'
+ * Returns 0 in case of success or else -1.
+ */
+int afb_evt_listener_unwatch_id(struct afb_evt_listener *listener, uint16_t eventid)
+{
+ struct afb_evt_watch *watch, **pwatch;
+ struct afb_evtid *evtid;
+
+ /* search the existing watch */
+ pthread_rwlock_wrlock(&listener->rwlock);
+ pwatch = &listener->watchs;
+ for (;;) {
+ watch = *pwatch;
+ if (!watch) {
+ pthread_rwlock_unlock(&listener->rwlock);
+ errno = ENOENT;
+ return -1;
+ }
+ evtid = watch->evtid;
+ if (evtid->id == eventid) {
+ *pwatch = watch->next_by_listener;
+ pthread_rwlock_unlock(&listener->rwlock);
+ listener_unwatch(listener, evtid, watch, 1);
+ return 0;
+ }
+ pwatch = &watch->next_by_listener;
+ }
+}
+
+/*
+ * Avoids the 'listener' to watch any event, calling the callback
+ * 'remove' of the interface if 'remoe' is not zero.
+ */
+void afb_evt_listener_unwatch_all(struct afb_evt_listener *listener, int remove)
+{
+ struct afb_evt_watch *watch, *nwatch;
+
+ /* search the existing watch */
+ pthread_rwlock_wrlock(&listener->rwlock);
+ watch = listener->watchs;
+ listener->watchs = NULL;
+ pthread_rwlock_unlock(&listener->rwlock);
+ while(watch) {
+ nwatch = watch->next_by_listener;
+ listener_unwatch(listener, watch->evtid, watch, remove);
+ watch = nwatch;
+ }
+}
+
+#if WITH_AFB_HOOK
+/*
+ * 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
+
+inline struct afb_evtid *afb_evt_event_x2_to_evtid(struct afb_event_x2 *eventid)
+{
+ return (struct afb_evtid*)eventid;
+}
+
+inline struct afb_event_x2 *afb_evt_event_x2_from_evtid(struct afb_evtid *evtid)
+{
+ return &evtid->eventid;
+}
+
+/*
+ * Creates an event of 'fullname' and returns it.
+ * Returns an event with closure==NULL in case of error.
+ */
+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_event_x2_from_evtid(afb_evt_evtid_create2(prefix, name));
+}
+
+/*
+ * Returns the fullname of the 'eventid'
+ */
+const char *afb_evt_event_x2_fullname(struct afb_event_x2 *eventid)
+{
+ struct afb_evtid *evtid = afb_evt_event_x2_to_evtid(eventid);
+ return evtid ? evtid->fullname : NULL;
+}
+
+/*
+ * Returns the id of the 'eventid'
+ */
+uint16_t afb_evt_event_x2_id(struct afb_event_x2 *eventid)
+{
+ struct afb_evtid *evtid = afb_evt_event_x2_to_evtid(eventid);
+ return evtid ? evtid->id : 0;
+}
+
+/*
+ * Makes the 'listener' watching 'eventid'
+ * Returns 0 in case of success or else -1.
+ */
+int afb_evt_listener_watch_x2(struct afb_evt_listener *listener, struct afb_event_x2 *eventid)
+{
+ struct afb_evtid *evtid = afb_evt_event_x2_to_evtid(eventid);