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 hash_map_iterator_t iter = hashMapIterator_construct((hash_map_pt)props);
246 while(hashMapIterator_hasNext(&iter)) {
247 key = (
const char*) hashMapIterator_nextKey(&iter);
248 value = celix_properties_get(props, key,
"");
250 properties[key] = value;
254 const I* srv = (
const I*) service;
256 fp(srv, std::move(properties));
261 template<
class T,
class I>
268 template<
class T,
class I>
274 template<
class T,
class I>
279 this->setupService();
283 template<
class T,
class I>
285 std::string n = name;
287 n = celix::typeName<I>();
290 const char* v = versionRange.empty() ? nullptr : versionRange.c_str();
294 template<
class T,
class I>
301 template<
class T,
class I>
308 template<
class T,
class I>
310 versionRange = _versionRange;
316 template<
class T,
class I>
318 this->addCxxLanguageFilter = addLang;
324 template<
class T,
class I>
326 this->setCallbacks([
this, set](I* srv, [[gnu::unused]]
Properties&& props) {
327 T *cmp = this->componentInstance;
333 template<
class T,
class I>
335 this->setCallbacks([
this, set](I* srv,
Properties&& props) {
336 T *cmp = this->componentInstance;
337 (cmp->*set)(srv, std::move(props));
342 template<
class T,
class I>
345 this->setupCallbacks();
349 template<
class T,
class I>
351 this->setCallbacks([
this, set](
const std::shared_ptr<I>& service,
const std::shared_ptr<const celix::Properties>& properties) {
352 T *cmp = this->componentInstance;
353 (cmp->*set)(std::move(service), properties);
358 template<
class T,
class I>
360 this->setFpUsingSharedPtr = std::move(set);
361 this->setupCallbacks();
365 template<
class T,
class I>
367 this->setCallbacks([
this, set](
const std::shared_ptr<I>& service) {
368 T *cmp = this->componentInstance;
369 (cmp->*set)(service);
374 template<
class T,
class I>
376 this->setCallbacks([set](
const std::shared_ptr<I>& service,
const std::shared_ptr<const celix::Properties>& ) {
384 template<
class T,
class I>
386 void (T::*add)(I* service),
387 void (T::*remove)(I* service)) {
389 [
this, add](I* srv, [[gnu::unused]]
Properties&& props) {
390 T *cmp = this->componentInstance;
393 [
this, remove](I* srv, [[gnu::unused]]
Properties&& props) {
394 T *cmp = this->componentInstance;
401 template<
class T,
class I>
403 void (T::*add)(I* service,
Properties&& properties),
404 void (T::*remove)(I* service,
Properties&& properties)
408 T *cmp = this->componentInstance;
409 (cmp->*add)(srv, std::move(props));
412 T *cmp = this->componentInstance;
413 (cmp->*remove)(srv, std::move(props));
420 template<
class T,
class I>
422 std::function<
void(I* service,
Properties&& properties)> add,
423 std::function<
void(I* service,
Properties&& properties)> remove) {
425 this->removeFp = remove;
426 this->setupCallbacks();
430 template<
class T,
class I>
432 void (T::*add)(
const std::shared_ptr<I>& service,
const std::shared_ptr<const celix::Properties>& properties),
433 void (T::*remove)(
const std::shared_ptr<I>& service,
const std::shared_ptr<const celix::Properties>& properties)
436 [
this, add](
const std::shared_ptr<I>& service,
const std::shared_ptr<const celix::Properties>& properties) {
437 T *cmp = this->componentInstance;
438 (cmp->*add)(service, properties);
440 [
this, remove](
const std::shared_ptr<I>& service,
const std::shared_ptr<const celix::Properties>& properties) {
441 T *cmp = this->componentInstance;
442 (cmp->*remove)(service, properties);
449 template<
class T,
class I>
451 std::function<
void(
const std::shared_ptr<I>& service,
const std::shared_ptr<const celix::Properties>& properties)> add,
452 std::function<
void(
const std::shared_ptr<I>& service,
const std::shared_ptr<const celix::Properties>& properties)> remove) {
453 this->addFpUsingSharedPtr = std::move(add);
454 this->removeFpUsingSharedPtr = std::move(remove);
455 this->setupCallbacks();
459 template<
class T,
class I>
461 void (T::*add)(
const std::shared_ptr<I>& service),
462 void (T::*remove)(
const std::shared_ptr<I>& service)
465 [
this, add](
const std::shared_ptr<I>& service,
const std::shared_ptr<const celix::Properties>& ) {
466 T *cmp = this->componentInstance;
467 (cmp->*add)(service);
469 [
this, remove](
const std::shared_ptr<I>& service,
const std::shared_ptr<const celix::Properties>& ) {
470 T *cmp = this->componentInstance;
471 (cmp->*remove)(service);
478 template<
class T,
class I>
480 std::function<
void(
const std::shared_ptr<I>& service)> add,
481 std::function<
void(
const std::shared_ptr<I>& service)> remove) {
483 [add](
const std::shared_ptr<I>& service,
const std::shared_ptr<const celix::Properties>& ) {
486 [remove](
const std::shared_ptr<I>& service,
const std::shared_ptr<const celix::Properties>& ) {
494 template<
class T,
class I>
500 template<
class T,
class I>
502 this->setDepStrategy(strategy);
506 template<
class T,
class I>
508 I *svc = (I*)service;
511 const char* key {
nullptr};
512 const char* value {
nullptr};
514 if (props !=
nullptr) {
515 hash_map_iterator_t iter = hashMapIterator_construct((hash_map_pt)props);
516 while(hashMapIterator_hasNext(&iter)) {
517 key = (
const char*) hashMapIterator_nextKey(&iter);
518 value = celix_properties_get(props, key,
"");
520 properties[key] = value;
524 fp(svc, std::move(properties));
528 template<
class T,
class I>
530 int(*cset)(
void*,
void *,
const celix_properties_t*) {
nullptr};
531 int(*cadd)(
void*,
void *,
const celix_properties_t*) {
nullptr};
532 int(*crem)(
void*,
void *,
const celix_properties_t*) {
nullptr};
534 if (setFp || setFpUsingSharedPtr) {
535 cset = [](
void* handle,
void* rawSvc,
const celix_properties_t* rawProps) ->
int {
539 rc = dep->invokeCallback(dep->setFp, rawProps, rawSvc);
541 if (dep->setFpUsingSharedPtr) {
542 auto svcId = dep->setService.second ? dep->setService.second->getAsLong(
celix::SERVICE_ID, -1) : -1;
543 std::weak_ptr<I> replacedSvc = dep->setService.first;
544 std::weak_ptr<const celix::Properties> replacedProps = dep->setService.second;
545 auto svc = std::shared_ptr<I>{
static_cast<I*
>(rawSvc), [](I*){}};
546 auto props = rawProps ? celix::Properties::wrap(rawProps) : nullptr;
547 dep->setService = std::make_pair(std::move(svc), std::move(props));
548 dep->setFpUsingSharedPtr(dep->setService.first, dep->setService.second);
549 dep->waitForExpired(replacedSvc, svcId,
"service pointer");
550 dep->waitForExpired(replacedProps, svcId,
"service properties");
555 if (addFp || addFpUsingSharedPtr) {
556 cadd = [](
void* handle,
void *rawSvc,
const celix_properties_t* rawProps) ->
int {
560 rc = dep->invokeCallback(dep->addFp, rawProps, rawSvc);
562 if (dep->addFpUsingSharedPtr) {
563 auto props = celix::Properties::wrap(rawProps);
564 auto svc = std::shared_ptr<I>{
static_cast<I*
>(rawSvc), [](I*){}};
566 dep->addFpUsingSharedPtr(svc, props);
567 dep->addedServices.template emplace(svcId, std::make_pair(std::move(svc), std::move(props)));
572 if (removeFp || removeFpUsingSharedPtr) {
573 crem = [](
void* handle,
void *rawSvc,
const celix_properties_t* rawProps) ->
int {
577 rc = dep->invokeCallback(dep->removeFp, rawProps, rawSvc);
579 if (dep->removeFpUsingSharedPtr) {
581 auto it = dep->addedServices.find(svcId);
582 if (it != dep->addedServices.end()) {
583 std::weak_ptr<I> removedSvc = it->second.first;
584 std::weak_ptr<const celix::Properties> removedProps = it->second.second;
585 dep->removeFpUsingSharedPtr(it->second.first, it->second.second);
586 dep->addedServices.erase(it);
587 dep->template waitForExpired(removedSvc, svcId,
"service pointer");
588 dep->template waitForExpired(removedProps, svcId,
"service properties");
597 std::memset(&opts, 0,
sizeof(opts));
604 template<
class T,
class I>
611 template<
class T,
class I>