in libs/framework/src/bundle_context.c [428:496]
static long celix_bundleContext_registerServiceWithOptionsInternal(bundle_context_t *ctx, const celix_service_registration_options_t *opts, bool async) {
bool valid = opts->serviceName != NULL && strncmp("", opts->serviceName, 1) != 0;
if (!valid) {
fw_log(ctx->framework->logger, CELIX_LOG_LEVEL_ERROR, "Required serviceName argument is NULL or empty");
return -1;
}
valid = opts->svc != NULL || opts->factory != NULL;
if (!valid) {
fw_log(ctx->framework->logger, CELIX_LOG_LEVEL_ERROR, "Required svc or factory argument is NULL");
return -1;
}
//set properties
celix_autoptr(celix_properties_t) props = opts->properties;
if (props == NULL) {
props = celix_properties_create();
}
if (opts->serviceVersion != NULL && strncmp("", opts->serviceVersion, 1) != 0) {
celix_autoptr(celix_version_t) version = celix_version_createVersionFromString(opts->serviceVersion);
if (!version) {
celix_framework_logTssErrors(ctx->framework->logger, CELIX_LOG_LEVEL_ERROR);
fw_log(
ctx->framework->logger, CELIX_LOG_LEVEL_ERROR, "Cannot parse service version %s", opts->serviceVersion);
return -1;
}
celix_status_t rc =
celix_properties_assignVersion(props, CELIX_FRAMEWORK_SERVICE_VERSION, celix_steal_ptr(version));
if (rc != CELIX_SUCCESS) {
celix_framework_logTssErrors(ctx->framework->logger, CELIX_LOG_LEVEL_ERROR);
fw_log(ctx->framework->logger, CELIX_LOG_LEVEL_ERROR, "Cannot set service version %s", opts->serviceVersion);
return -1;
}
}
celix_status_t correctionStatus = celix_bundleContext_correctServicePropertiesValueTypes(ctx, props);
if (correctionStatus != CELIX_SUCCESS) {
celix_framework_logTssErrors(ctx->framework->logger, CELIX_LOG_LEVEL_ERROR);
fw_log(ctx->framework->logger, CELIX_LOG_LEVEL_ERROR, "Cannot correct service properties value types");
return -1;
}
long svcId;
if (!async && celix_framework_isCurrentThreadTheEventLoop(ctx->framework)) {
/*
* Note already on event loop, cannot register the service async, because we cannot wait a future event (the
* service registration) the event loop.
*
* So in this case we handle the service registration the "traditional way" and call the sync fw service
* registrations versions on the event loop thread
*/
svcId = celix_framework_registerService(ctx->framework, ctx->bundle, opts->serviceName, opts->svc, opts->factory, celix_steal_ptr(props));
} else {
void (*asyncCallback)(void *data, long serviceId) = async ? opts->asyncCallback : NULL; //NOTE for not async call do not use the callback.
svcId = celix_framework_registerServiceAsync(ctx->framework, ctx->bundle, opts->serviceName, opts->svc, opts->factory, celix_steal_ptr(props), opts->asyncData, asyncCallback, NULL, NULL);
if (!async && svcId >= 0) {
//note on event loop thread, but in a sync call, so waiting till service registration is concluded
celix_bundleContext_waitForAsyncRegistration(ctx, svcId);
}
}
if (svcId >= 0) {
celixThreadRwlock_writeLock(&ctx->lock);
celix_arrayList_addLong(ctx->svcRegistrations, svcId);
celixThreadRwlock_unlock(&ctx->lock);
}
return svcId;
}