in libs/framework/include/celix/dm/ServiceDependency_Impl.h [486:559]
void ServiceDependency<T,I>::setupCallbacks() {
int(*cset)(void*, void *, const celix_properties_t*) {nullptr};
int(*cadd)(void*, void *, const celix_properties_t*) {nullptr};
int(*crem)(void*, void *, const celix_properties_t*) {nullptr};
if (setFp || setFpUsingSharedPtr) {
cset = [](void* handle, void* rawSvc, const celix_properties_t* rawProps) -> int {
int rc = 0;
auto dep = (ServiceDependency<T,I>*) handle;
if (dep->setFp) {
rc = dep->invokeCallback(dep->setFp, rawProps, rawSvc);
}
if (dep->setFpUsingSharedPtr) {
auto svcId = dep->setService.second ? dep->setService.second->getAsLong(celix::SERVICE_ID, -1) : -1;
std::weak_ptr<I> replacedSvc = dep->setService.first;
std::weak_ptr<const celix::Properties> replacedProps = dep->setService.second;
auto svc = std::shared_ptr<I>{static_cast<I*>(rawSvc), [](I*){/*nop*/}};
auto props = rawProps ? std::make_shared<const celix::Properties>(celix::Properties::wrap(rawProps)) : nullptr;
dep->setService = std::make_pair(std::move(svc), std::move(props));
dep->setFpUsingSharedPtr(dep->setService.first, dep->setService.second);
dep->waitForExpired(replacedSvc, svcId, "service pointer");
dep->waitForExpired(replacedProps, svcId, "service properties");
}
return rc;
};
}
if (addFp || addFpUsingSharedPtr) {
cadd = [](void* handle, void *rawSvc, const celix_properties_t* rawProps) -> int {
int rc = 0;
auto dep = (ServiceDependency<T,I>*) handle;
if (dep->addFp) {
rc = dep->invokeCallback(dep->addFp, rawProps, rawSvc);
}
if (dep->addFpUsingSharedPtr) {
auto props = std::make_shared<const celix::Properties>(celix::Properties::wrap(rawProps));
auto svc = std::shared_ptr<I>{static_cast<I*>(rawSvc), [](I*){/*nop*/}};
auto svcId = props->getAsLong(celix::SERVICE_ID, -1);
dep->addFpUsingSharedPtr(svc, props);
dep->addedServices.template emplace(svcId, std::make_pair(std::move(svc), std::move(props)));
}
return rc;
};
}
if (removeFp || removeFpUsingSharedPtr) {
crem = [](void* handle, void *rawSvc, const celix_properties_t* rawProps) -> int {
int rc = 0;
auto dep = (ServiceDependency<T,I>*) handle;
if (dep->removeFp) {
rc = dep->invokeCallback(dep->removeFp, rawProps, rawSvc);
}
if (dep->removeFpUsingSharedPtr) {
auto svcId = celix_properties_getAsLong(rawProps, celix::SERVICE_ID, -1);
auto it = dep->addedServices.find(svcId);
if (it != dep->addedServices.end()) {
std::weak_ptr<I> removedSvc = it->second.first;
std::weak_ptr<const celix::Properties> removedProps = it->second.second;
dep->removeFpUsingSharedPtr(it->second.first, it->second.second);
dep->addedServices.erase(it);
dep->template waitForExpired(removedSvc, svcId, "service pointer");
dep->template waitForExpired(removedProps, svcId, "service properties");
}
}
return rc;
};
}
celix_dmServiceDependency_setCallbackHandle(this->cServiceDependency(), this);
celix_dm_service_dependency_callback_options_t opts;
std::memset(&opts, 0, sizeof(opts));
opts.setWithProps = cset;
opts.addWithProps = cadd;
opts.removeWithProps = crem;
celix_dmServiceDependency_setCallbacksWithOptions(this->cServiceDependency(), &opts);
}