in bundles/event_admin/event_admin/src/celix_event_admin.c [356:436]
int celix_eventAdmin_addEventHandlerWithProperties(void* handle, void* svc, const celix_properties_t* props) {
assert(handle != NULL);
assert(svc != NULL);
assert(props != NULL);
celix_event_admin_t* ea = (celix_event_admin_t*)handle;
const char *topics = celix_properties_get(props, CELIX_EVENT_TOPIC, NULL);
if (topics == NULL) {
celix_logHelper_error(ea->logHelper, "Failed to add event handler. No %s property set", CELIX_EVENT_TOPIC);
return CELIX_ILLEGAL_ARGUMENT;
}
long serviceId = celix_properties_getAsLong(props, CELIX_FRAMEWORK_SERVICE_ID, -1L);
assert(serviceId >= 0);
celix_autofree celix_event_handler_t *handler = calloc(1, sizeof(*handler));
if (handler == NULL) {
celix_logHelper_error(ea->logHelper, "Failed to create event handler.");
return CELIX_ENOMEM;
}
handler->service = svc;
handler->serviceId = serviceId;
handler->serviceDescription = celix_properties_get(props, CELIX_FRAMEWORK_SERVICE_DESCRIPTION, "Unknown");
const char *deliver = celix_properties_get(props, CELIX_EVENT_DELIVERY, NULL);
handler->asyncOrdered = (deliver == NULL || strstr(deliver,CELIX_EVENT_DELIVERY_ASYNC_ORDERED) != NULL);
handler->eventFilter = NULL;
handler->blackListed = false;
handler->handlingAsyncEventCnt = 0;
celix_autofree char* topicsCopy = celix_utils_strdup(topics);
if (topicsCopy == NULL) {
celix_logHelper_error(ea->logHelper, "Failed to dup topics %s.", topics);
return CELIX_ENOMEM;
}
celix_autoptr(celix_string_hash_map_t) topicsMap = celix_stringHashMap_create();//avoid topic duplicates
if (topicsMap == NULL) {
celix_logHelper_logTssErrors(ea->logHelper, CELIX_LOG_LEVEL_ERROR);
celix_logHelper_error(ea->logHelper, "Failed to create topics map.");
return CELIX_ENOMEM;
}
char* savePtr = NULL;
char* token = strtok_r(topicsCopy, ",", &savePtr);
while (token != NULL) {
char *trimmedToken = celix_utils_trimInPlace(token);
if (celix_stringHashMap_put(topicsMap, trimmedToken, NULL) != CELIX_SUCCESS) {
celix_logHelper_logTssErrors(ea->logHelper, CELIX_LOG_LEVEL_ERROR);
celix_logHelper_error(ea->logHelper, "Failed to add topic %s to topics map.", trimmedToken);
return CELIX_ENOMEM;
}
token = strtok_r(NULL, ",", &savePtr);
}
celix_autoptr(celix_filter_t) eventFilter = NULL;
const char* eventFilterStr = celix_properties_get(props, CELIX_EVENT_FILTER, NULL);
if (eventFilterStr) {
eventFilter = handler->eventFilter = celix_filter_create(eventFilterStr);
if (eventFilter == NULL) {
celix_logHelper_logTssErrors(ea->logHelper, CELIX_LOG_LEVEL_ERROR);
celix_logHelper_error(ea->logHelper, "Failed to create event filter for %s.", eventFilterStr);
return CELIX_BUNDLE_EXCEPTION;
}
}
celix_auto(celix_rwlock_wlock_guard_t) wLockGuard = celixRwlockWlockGuard_init(&ea->lock);
celix_status_t status = celix_longHashMap_put(ea->eventHandlers, handler->serviceId, handler);
if (status != CELIX_SUCCESS) {
celix_logHelper_logTssErrors(ea->logHelper, CELIX_LOG_LEVEL_ERROR);
celix_logHelper_error(ea->logHelper, "Failed to add event handler(%s).", handler->serviceDescription);
return status;
}
CELIX_STRING_HASH_MAP_ITERATE(topicsMap, iter) {
celix_eventAdmin_subscribeTopicFor(ea, iter.key, handler);
}
celix_logHelper_debug(ea->logHelper, "Added event handler(%s) for topics %s", handler->serviceDescription, topics);
celix_steal_ptr(eventFilter);
celix_steal_ptr(handler);
return CELIX_SUCCESS;
}