26 #include "celix_constants.h"
27 #include "celix_properties.h"
38 auto start = std::chrono::system_clock::now();
39 while (!observe.expired()) {
40 auto now = std::chrono::system_clock::now();
41 auto durationInMilli = std::chrono::duration_cast<std::chrono::milliseconds>(now - start);
42 if (durationInMilli > warningTimoutForNonExpiredSvcObject) {
48 CELIX_LOG_LEVEL_WARNING,
49 "celix::dm::ServiceDependency: Cannot remove %s associated with service.id %li, because it is still in use. Current shared_ptr use count is %i",
52 (
int)observe.use_count());
57 std::this_thread::sleep_for(std::chrono::milliseconds{50});
62 bool alreadyAdded = depAddedToCmp.exchange(
true);
76 "BaseServiceDependency::wait: Cannot wait for Celix event queue on the Celix event queue thread! "
77 "Use async DepMan API instead.");
88 template<
class T,
typename I>
94 template<
class T,
typename I>
96 this->versionRange = serviceVersionRange;
101 template<
class T,
typename I>
104 this->setupService();
108 template<
class T,
typename I>
110 const char* cversion = this->versionRange.empty() ? nullptr : versionRange.c_str();
111 const char* cfilter = filter.empty() ? nullptr : filter.c_str();
115 template<
class T,
typename I>
117 celix_serviceDependency_setAddCLanguageFilter(this->cServiceDependency(), addLang);
118 this->setupService();
122 template<
class T,
typename I>
128 template<
class T,
typename I>
130 this->setDepStrategy(strategy);
135 template<
class T,
typename I>
137 this->setCallbacks([
this, set](
const I* service, [[gnu::unused]]
Properties&& properties) {
138 T *cmp = this->componentInstance;
139 (cmp->*set)(service);
144 template<
class T,
typename I>
146 this->setCallbacks([
this, set](
const I* service,
Properties&& properties) {
147 T *cmp = this->componentInstance;
148 (cmp->*set)(service, std::move(properties));
153 template<
class T,
typename I>
156 this->setupCallbacks();
161 template<
class T,
typename I>
163 void (T::*add)(
const I* service),
164 void (T::*remove)(
const I* service)) {
166 [
this, add](
const I* service, [[gnu::unused]]
Properties&& properties) {
167 T *cmp = this->componentInstance;
168 (cmp->*add)(service);
170 [
this, remove](
const I* service, [[gnu::unused]]
Properties&& properties) {
171 T *cmp = this->componentInstance;
172 (cmp->*remove)(service);
178 template<
class T,
typename I>
180 void (T::*add)(
const I* service,
Properties&& properties),
181 void (T::*remove)(
const I* service,
Properties&& properties)
184 [
this, add](
const I* service,
Properties&& properties) {
185 T *cmp = this->componentInstance;
186 (cmp->*add)(service, std::move(properties));
188 [
this, remove](
const I* service,
Properties&& properties) {
189 T *cmp = this->componentInstance;
190 (cmp->*remove)(service, std::move(properties));
196 template<
class T,
typename I>
199 this->removeFp = remove;
200 this->setupCallbacks();
205 template<
class T,
typename I>
207 int(*cset)(
void*,
void *,
const celix_properties_t*) {
nullptr};
208 int(*cadd)(
void*,
void *,
const celix_properties_t*) {
nullptr};
209 int(*crem)(
void*,
void *,
const celix_properties_t*) {
nullptr};
212 cset = [](
void* handle,
void *service,
const celix_properties_t *props) ->
int {
214 return dep->invokeCallback(dep->setFp, props, service);
218 cadd = [](
void* handle,
void *service,
const celix_properties_t *props) ->
int {
220 return dep->invokeCallback(dep->addFp, props, service);
224 crem= [](
void* handle,
void *service,
const celix_properties_t *props) ->
int {
226 return dep->invokeCallback(dep->removeFp, props, service);
231 std::memset(&opts, 0,
sizeof(opts));
238 template<
class T,
typename I>
241 const char* key {
nullptr};
242 const char* value {
nullptr};
244 if (props !=
nullptr) {
245 CELIX_PROPERTIES_FOR_EACH(props, key) {
246 value = celix_properties_get(props, key,
"");
248 properties[key] = value;
252 const I* srv = (
const I*) service;
254 fp(srv, std::move(properties));
259 template<
class T,
class I>
266 template<
class T,
class I>
272 template<
class T,
class I>
277 this->setupService();
281 template<
class T,
class I>
283 std::string n = name;
285 n = celix::typeName<I>();
288 const char* v = versionRange.empty() ? nullptr : versionRange.c_str();
292 template<
class T,
class I>
299 template<
class T,
class I>
306 template<
class T,
class I>
308 versionRange = _versionRange;
314 template<
class T,
class I>
316 this->addCxxLanguageFilter = addLang;
322 template<
class T,
class I>
324 this->setCallbacks([
this, set](I* srv, [[gnu::unused]]
Properties&& props) {
325 T *cmp = this->componentInstance;
331 template<
class T,
class I>
333 this->setCallbacks([
this, set](I* srv,
Properties&& props) {
334 T *cmp = this->componentInstance;
335 (cmp->*set)(srv, std::move(props));
340 template<
class T,
class I>
343 this->setupCallbacks();
347 template<
class T,
class I>
349 this->setCallbacks([
this, set](
const std::shared_ptr<I>& service,
const std::shared_ptr<const celix::Properties>& properties) {
350 T *cmp = this->componentInstance;
351 (cmp->*set)(std::move(service), properties);
356 template<
class T,
class I>
358 this->setFpUsingSharedPtr = std::move(set);
359 this->setupCallbacks();
363 template<
class T,
class I>
365 this->setCallbacks([
this, set](
const std::shared_ptr<I>& service) {
366 T *cmp = this->componentInstance;
367 (cmp->*set)(service);
372 template<
class T,
class I>
374 this->setCallbacks([set](
const std::shared_ptr<I>& service,
const std::shared_ptr<const celix::Properties>& ) {
382 template<
class T,
class I>
384 void (T::*add)(I* service),
385 void (T::*remove)(I* service)) {
387 [
this, add](I* srv, [[gnu::unused]]
Properties&& props) {
388 T *cmp = this->componentInstance;
391 [
this, remove](I* srv, [[gnu::unused]]
Properties&& props) {
392 T *cmp = this->componentInstance;
399 template<
class T,
class I>
401 void (T::*add)(I* service,
Properties&& properties),
402 void (T::*remove)(I* service,
Properties&& properties)
406 T *cmp = this->componentInstance;
407 (cmp->*add)(srv, std::move(props));
410 T *cmp = this->componentInstance;
411 (cmp->*remove)(srv, std::move(props));
418 template<
class T,
class I>
420 std::function<
void(I* service,
Properties&& properties)> add,
421 std::function<
void(I* service,
Properties&& properties)> remove) {
423 this->removeFp = remove;
424 this->setupCallbacks();
428 template<
class T,
class I>
430 void (T::*add)(
const std::shared_ptr<I>& service,
const std::shared_ptr<const celix::Properties>& properties),
431 void (T::*remove)(
const std::shared_ptr<I>& service,
const std::shared_ptr<const celix::Properties>& properties)
434 [
this, add](
const std::shared_ptr<I>& service,
const std::shared_ptr<const celix::Properties>& properties) {
435 T *cmp = this->componentInstance;
436 (cmp->*add)(service, properties);
438 [
this, remove](
const std::shared_ptr<I>& service,
const std::shared_ptr<const celix::Properties>& properties) {
439 T *cmp = this->componentInstance;
440 (cmp->*remove)(service, properties);
447 template<
class T,
class I>
449 std::function<
void(
const std::shared_ptr<I>& service,
const std::shared_ptr<const celix::Properties>& properties)> add,
450 std::function<
void(
const std::shared_ptr<I>& service,
const std::shared_ptr<const celix::Properties>& properties)> remove) {
451 this->addFpUsingSharedPtr = std::move(add);
452 this->removeFpUsingSharedPtr = std::move(remove);
453 this->setupCallbacks();
457 template<
class T,
class I>
459 void (T::*add)(
const std::shared_ptr<I>& service),
460 void (T::*remove)(
const std::shared_ptr<I>& service)
463 [
this, add](
const std::shared_ptr<I>& service,
const std::shared_ptr<const celix::Properties>& ) {
464 T *cmp = this->componentInstance;
465 (cmp->*add)(service);
467 [
this, remove](
const std::shared_ptr<I>& service,
const std::shared_ptr<const celix::Properties>& ) {
468 T *cmp = this->componentInstance;
469 (cmp->*remove)(service);
476 template<
class T,
class I>
478 std::function<
void(
const std::shared_ptr<I>& service)> add,
479 std::function<
void(
const std::shared_ptr<I>& service)> remove) {
481 [add](
const std::shared_ptr<I>& service,
const std::shared_ptr<const celix::Properties>& ) {
484 [remove](
const std::shared_ptr<I>& service,
const std::shared_ptr<const celix::Properties>& ) {
492 template<
class T,
class I>
498 template<
class T,
class I>
500 this->setDepStrategy(strategy);
504 template<
class T,
class I>
506 I *svc = (I*)service;
509 const char* key {
nullptr};
510 const char* value {
nullptr};
512 if (props !=
nullptr) {
513 CELIX_PROPERTIES_FOR_EACH(props, key) {
514 value = celix_properties_get(props, key,
"");
516 properties[key] = value;
520 fp(svc, std::move(properties));
524 template<
class T,
class I>
526 int(*cset)(
void*,
void *,
const celix_properties_t*) {
nullptr};
527 int(*cadd)(
void*,
void *,
const celix_properties_t*) {
nullptr};
528 int(*crem)(
void*,
void *,
const celix_properties_t*) {
nullptr};
530 if (setFp || setFpUsingSharedPtr) {
531 cset = [](
void* handle,
void* rawSvc,
const celix_properties_t* rawProps) ->
int {
535 rc = dep->invokeCallback(dep->setFp, rawProps, rawSvc);
537 if (dep->setFpUsingSharedPtr) {
538 auto svcId = dep->setService.second ? dep->setService.second->getAsLong(
celix::SERVICE_ID, -1) : -1;
539 std::weak_ptr<I> replacedSvc = dep->setService.first;
540 std::weak_ptr<const celix::Properties> replacedProps = dep->setService.second;
541 auto svc = std::shared_ptr<I>{
static_cast<I*
>(rawSvc), [](I*){}};
542 auto props = rawProps ? celix::Properties::wrap(rawProps) : nullptr;
543 dep->setService = std::make_pair(std::move(svc), std::move(props));
544 dep->setFpUsingSharedPtr(dep->setService.first, dep->setService.second);
545 dep->waitForExpired(replacedSvc, svcId,
"service pointer");
546 dep->waitForExpired(replacedProps, svcId,
"service properties");
551 if (addFp || addFpUsingSharedPtr) {
552 cadd = [](
void* handle,
void *rawSvc,
const celix_properties_t* rawProps) ->
int {
556 rc = dep->invokeCallback(dep->addFp, rawProps, rawSvc);
558 if (dep->addFpUsingSharedPtr) {
559 auto props = celix::Properties::wrap(rawProps);
560 auto svc = std::shared_ptr<I>{
static_cast<I*
>(rawSvc), [](I*){}};
562 dep->addFpUsingSharedPtr(svc, props);
563 dep->addedServices.template emplace(svcId, std::make_pair(std::move(svc), std::move(props)));
568 if (removeFp || removeFpUsingSharedPtr) {
569 crem = [](
void* handle,
void *rawSvc,
const celix_properties_t* rawProps) ->
int {
573 rc = dep->invokeCallback(dep->removeFp, rawProps, rawSvc);
575 if (dep->removeFpUsingSharedPtr) {
577 auto it = dep->addedServices.find(svcId);
578 if (it != dep->addedServices.end()) {
579 std::weak_ptr<I> removedSvc = it->second.first;
580 std::weak_ptr<const celix::Properties> removedProps = it->second.second;
581 dep->removeFpUsingSharedPtr(it->second.first, it->second.second);
582 dep->addedServices.erase(it);
583 dep->template
waitForExpired(removedSvc, svcId,
"service pointer");
584 dep->template
waitForExpired(removedProps, svcId,
"service properties");
593 std::memset(&opts, 0,
sizeof(opts));
600 template<
class T,
class I>
607 template<
class T,
class I>