+ return NULL;
+}
+
+/*
+ * Creates an event of name 'prefix'/'name' and returns it or NULL on error.
+ */
+struct afb_evtid *afb_evt_evtid_create2(const char *prefix, const char *name)
+{
+ 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_addref(struct afb_evtid *evtid)
+{
+ __atomic_add_fetch(&evtid->refcount, 1, __ATOMIC_RELAXED);
+ return evtid;
+}
+
+/*
+ * 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_unref(struct afb_evtid *evtid)
+{
+ int found;
+ struct afb_evtid **prv;
+ struct afb_evt_listener *listener;
+
+ if (!__atomic_sub_fetch(&evtid->refcount, 1, __ATOMIC_RELAXED)) {
+ /* unlinks the event if valid! */
+ pthread_rwlock_wrlock(&events_rwlock);
+ found = 0;
+ prv = &evtids;
+ while (*prv && !(found = (*prv == evtid)))
+ prv = &(*prv)->next;
+ if (found)
+ *prv = evtid->next;
+ pthread_rwlock_unlock(&events_rwlock);
+
+ /* destroys the event */
+ if (!found)
+ ERROR("event not found");
+ else {
+ /* removes all watchers */
+ while(evtid->watchs != NULL) {
+ listener = evtid->watchs->listener;
+ pthread_rwlock_wrlock(&listener->rwlock);
+ pthread_rwlock_wrlock(&evtid->rwlock);
+ remove_watch(evtid->watchs);
+ pthread_rwlock_unlock(&evtid->rwlock);
+ pthread_rwlock_unlock(&listener->rwlock);
+ }
+
+ /* free */
+ 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'
+ */
+const char *afb_evt_evtid_fullname(struct afb_evtid *evtid)
+{
+ return evtid->fullname;