26 #include "celix_constants.h"
27 #include "celix_properties.h"
38 auto start = std::chrono::steady_clock::now();
39 while (!observe.expired()) {
40 auto now = std::chrono::steady_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>
121 template<
class T,
typename I>
123 this->setDepStrategy(strategy);
128 template<
class T,
typename I>
130 this->setCallbacks([
this, set](
const I* service, [[gnu::unused]]
Properties&& properties) {
131 T *cmp = this->componentInstance;
132 (cmp->*set)(service);
137 template<
class T,
typename I>
139 this->setCallbacks([
this, set](
const I* service,
Properties&& properties) {
140 T *cmp = this->componentInstance;
141 (cmp->*set)(service, std::move(properties));
146 template<
class T,
typename I>
149 this->setupCallbacks();
154 template<
class T,
typename I>
156 void (T::*add)(
const I* service),
157 void (T::*remove)(
const I* service)) {
159 [
this, add](
const I* service, [[gnu::unused]]
Properties&& properties) {
160 T *cmp = this->componentInstance;
161 (cmp->*add)(service);
163 [
this, remove](
const I* service, [[gnu::unused]]
Properties&& properties) {
164 T *cmp = this->componentInstance;
165 (cmp->*remove)(service);
171 template<
class T,
typename I>
173 void (T::*add)(
const I* service,
Properties&& properties),
174 void (T::*remove)(
const I* service,
Properties&& properties)
177 [
this, add](
const I* service,
Properties&& properties) {
178 T *cmp = this->componentInstance;
179 (cmp->*add)(service, std::move(properties));
181 [
this, remove](
const I* service,
Properties&& properties) {
182 T *cmp = this->componentInstance;
183 (cmp->*remove)(service, std::move(properties));
189 template<
class T,
typename I>
192 this->removeFp = remove;
193 this->setupCallbacks();
198 template<
class T,
typename I>
200 int(*cset)(
void*,
void *,
const celix_properties_t*) {
nullptr};
201 int(*cadd)(
void*,
void *,
const celix_properties_t*) {
nullptr};
202 int(*crem)(
void*,
void *,
const celix_properties_t*) {
nullptr};
205 cset = [](
void* handle,
void *service,
const celix_properties_t *props) ->
int {
207 return dep->invokeCallback(dep->setFp, props, service);
211 cadd = [](
void* handle,
void *service,
const celix_properties_t *props) ->
int {
213 return dep->invokeCallback(dep->addFp, props, service);
217 crem= [](
void* handle,
void *service,
const celix_properties_t *props) ->
int {
219 return dep->invokeCallback(dep->removeFp, props, service);
224 std::memset(&opts, 0,
sizeof(opts));
231 template<
class T,
typename I>
233 auto properties = Properties::copy(props);
234 const I* srv = (
const I*) service;
235 fp(srv, std::move(properties));
240 template<
class T,
class I>
247 template<
class T,
class I>
253 template<
class T,
class I>
258 this->setupService();
262 template<
class T,
class I>
264 std::string n = name;
266 n = celix::typeName<I>();
269 const char* v = versionRange.empty() ? nullptr : versionRange.c_str();
273 template<
class T,
class I>
280 template<
class T,
class I>
287 template<
class T,
class I>
289 versionRange = _versionRange;
295 template<
class T,
class I>
298 T *cmp = this->componentInstance;
304 template<
class T,
class I>
306 this->setCallbacks([
this, set](I* srv,
Properties&& props) {
307 T *cmp = this->componentInstance;
308 (cmp->*set)(srv, std::move(props));
313 template<
class T,
class I>
316 this->setupCallbacks();
320 template<
class T,
class I>
322 this->setCallbacks([
this, set](
const std::shared_ptr<I>& service,
const std::shared_ptr<const celix::Properties>& properties) {
323 T *cmp = this->componentInstance;
324 (cmp->*set)(std::move(service), properties);
329 template<
class T,
class I>
331 this->setFpUsingSharedPtr = std::move(set);
332 this->setupCallbacks();
336 template<
class T,
class I>
338 this->setCallbacks([
this, set](
const std::shared_ptr<I>& service) {
339 T *cmp = this->componentInstance;
340 (cmp->*set)(service);
345 template<
class T,
class I>
347 this->setCallbacks([set](
const std::shared_ptr<I>& service,
const std::shared_ptr<const celix::Properties>& ) {
355 template<
class T,
class I>
357 void (T::*add)(I* service),
358 void (T::*remove)(I* service)) {
360 [
this, add](I* srv, [[gnu::unused]]
Properties&& props) {
361 T *cmp = this->componentInstance;
364 [
this, remove](I* srv, [[gnu::unused]]
Properties&& props) {
365 T *cmp = this->componentInstance;
372 template<
class T,
class I>
374 void (T::*add)(I* service,
Properties&& properties),
375 void (T::*remove)(I* service,
Properties&& properties)
379 T *cmp = this->componentInstance;
380 (cmp->*add)(srv, std::move(props));
383 T *cmp = this->componentInstance;
384 (cmp->*remove)(srv, std::move(props));
391 template<
class T,
class I>
393 std::function<
void(I* service,
Properties&& properties)> add,
394 std::function<
void(I* service,
Properties&& properties)> remove) {
396 this->removeFp = remove;
397 this->setupCallbacks();
401 template<
class T,
class I>
403 void (T::*add)(
const std::shared_ptr<I>& service,
const std::shared_ptr<const celix::Properties>& properties),
404 void (T::*remove)(
const std::shared_ptr<I>& service,
const std::shared_ptr<const celix::Properties>& properties)
407 [
this, add](
const std::shared_ptr<I>& service,
const std::shared_ptr<const celix::Properties>& properties) {
408 T *cmp = this->componentInstance;
409 (cmp->*add)(service, properties);
411 [
this, remove](
const std::shared_ptr<I>& service,
const std::shared_ptr<const celix::Properties>& properties) {
412 T *cmp = this->componentInstance;
413 (cmp->*remove)(service, properties);
420 template<
class T,
class I>
422 std::function<
void(
const std::shared_ptr<I>& service,
const std::shared_ptr<const celix::Properties>& properties)> add,
423 std::function<
void(
const std::shared_ptr<I>& service,
const std::shared_ptr<const celix::Properties>& properties)> remove) {
424 this->addFpUsingSharedPtr = std::move(add);
425 this->removeFpUsingSharedPtr = std::move(remove);
426 this->setupCallbacks();
430 template<
class T,
class I>
432 void (T::*add)(
const std::shared_ptr<I>& service),
433 void (T::*remove)(
const std::shared_ptr<I>& service)
436 [
this, add](
const std::shared_ptr<I>& service,
const std::shared_ptr<const celix::Properties>& ) {
437 T *cmp = this->componentInstance;
438 (cmp->*add)(service);
440 [
this, remove](
const std::shared_ptr<I>& service,
const std::shared_ptr<const celix::Properties>& ) {
441 T *cmp = this->componentInstance;
442 (cmp->*remove)(service);
449 template<
class T,
class I>
451 std::function<
void(
const std::shared_ptr<I>& service)> add,
452 std::function<
void(
const std::shared_ptr<I>& service)> remove) {
454 [add](
const std::shared_ptr<I>& service,
const std::shared_ptr<const celix::Properties>& ) {
457 [remove](
const std::shared_ptr<I>& service,
const std::shared_ptr<const celix::Properties>& ) {
465 template<
class T,
class I>
471 template<
class T,
class I>
473 this->setDepStrategy(strategy);
477 template<
class T,
class I>
479 I *svc = (I*)service;
480 auto properties = celix::Properties::wrap(props);
481 fp(svc, std::move(properties));
485 template<
class T,
class I>
487 int(*cset)(
void*,
void *,
const celix_properties_t*) {
nullptr};
488 int(*cadd)(
void*,
void *,
const celix_properties_t*) {
nullptr};
489 int(*crem)(
void*,
void *,
const celix_properties_t*) {
nullptr};
491 if (setFp || setFpUsingSharedPtr) {
492 cset = [](
void* handle,
void* rawSvc,
const celix_properties_t* rawProps) ->
int {
496 rc = dep->invokeCallback(dep->setFp, rawProps, rawSvc);
498 if (dep->setFpUsingSharedPtr) {
499 auto svcId = dep->setService.second ? dep->setService.second->getAsLong(
celix::SERVICE_ID, -1) : -1;
500 std::weak_ptr<I> replacedSvc = dep->setService.first;
501 std::weak_ptr<const celix::Properties> replacedProps = dep->setService.second;
502 auto svc = std::shared_ptr<I>{
static_cast<I*
>(rawSvc), [](I*){}};
503 auto props = rawProps ? std::make_shared<const celix::Properties>(celix::Properties::wrap(rawProps)) : nullptr;
504 dep->setService = std::make_pair(std::move(svc), std::move(props));
505 dep->setFpUsingSharedPtr(dep->setService.first, dep->setService.second);
506 dep->waitForExpired(replacedSvc, svcId,
"service pointer");
507 dep->waitForExpired(replacedProps, svcId,
"service properties");
512 if (addFp || addFpUsingSharedPtr) {
513 cadd = [](
void* handle,
void *rawSvc,
const celix_properties_t* rawProps) ->
int {
517 rc = dep->invokeCallback(dep->addFp, rawProps, rawSvc);
519 if (dep->addFpUsingSharedPtr) {
520 auto props = std::make_shared<const celix::Properties>(celix::Properties::wrap(rawProps));
521 auto svc = std::shared_ptr<I>{
static_cast<I*
>(rawSvc), [](I*){}};
523 dep->addFpUsingSharedPtr(svc, props);
524 dep->addedServices.template emplace(svcId, std::make_pair(std::move(svc), std::move(props)));
529 if (removeFp || removeFpUsingSharedPtr) {
530 crem = [](
void* handle,
void *rawSvc,
const celix_properties_t* rawProps) ->
int {
534 rc = dep->invokeCallback(dep->removeFp, rawProps, rawSvc);
536 if (dep->removeFpUsingSharedPtr) {
538 auto it = dep->addedServices.find(svcId);
539 if (it != dep->addedServices.end()) {
540 std::weak_ptr<I> removedSvc = it->second.first;
541 std::weak_ptr<const celix::Properties> removedProps = it->second.second;
542 dep->removeFpUsingSharedPtr(it->second.first, it->second.second);
543 dep->addedServices.erase(it);
544 dep->template
waitForExpired(removedSvc, svcId,
"service pointer");
545 dep->template
waitForExpired(removedProps, svcId,
"service properties");
554 std::memset(&opts, 0,
sizeof(opts));
561 template<
class T,
class I>
568 template<
class T,
class I>