+struct afb_evtid *afb_evt_evtid_create(const char *fullname)
+{
+ size_t len;
+ struct afb_evtid *evtid, *oevt;
+
+ /* allocates the event */
+ len = strlen(fullname);
+ evtid = malloc(len + 1 + sizeof * evtid);
+ if (evtid == NULL)
+ goto error;
+
+ /* allocates the id */
+ pthread_rwlock_wrlock(&events_rwlock);
+ do {
+ if (++event_id_counter < 0) {
+ event_id_wrapped = 1;
+ event_id_counter = 1024; /* heuristic: small numbers are not destroyed */
+ }
+ if (!event_id_wrapped)
+ break;
+ oevt = evtids;
+ while(oevt != NULL && oevt->id != event_id_counter)
+ oevt = oevt->next;
+ } while (oevt != NULL);
+
+ /* initialize the event */
+ memcpy(evtid->fullname, fullname, len + 1);
+ evtid->next = evtids;
+ evtid->refcount = 1;
+ evtid->watchs = NULL;
+ evtid->id = event_id_counter;
+ evtid->has_client = 0;
+ pthread_rwlock_init(&evtid->rwlock, NULL);
+ evtids = evtid;
+ evtid->hookflags = afb_hook_flags_evt(evtid->fullname);
+ evtid->eventid.itf = evtid->hookflags ? &afb_evt_hooked_eventid_itf : &afb_evt_event_x2_itf;
+ if (evtid->hookflags & afb_hook_flag_evt_create)
+ afb_hook_evt_create(evtid->fullname, evtid->id);
+ pthread_rwlock_unlock(&events_rwlock);
+
+ /* returns the event */
+ return evtid;
+error:
+ 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)