Apache Celix  latest
Apache Celix is a framework for C, C++14 and C++17 to develop dynamic modular software applications using component and in-process service-oriented programming.
ServiceDependency.h
Go to the documentation of this file.
1 /*
2  * Licensed to the Apache Software Foundation (ASF) under one
3  * or more contributor license agreements. See the NOTICE file
4  * distributed with this work for additional information
5  * regarding copyright ownership. The ASF licenses this file
6  * to you under the Apache License, Version 2.0 (the
7  * "License"); you may not use this file except in compliance
8  * with the License. You may obtain a copy of the License at
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing,
13  * software distributed under the License is distributed on an
14  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15  * KIND, either express or implied. See the License for the
16  * specific language governing permissions and limitations
17  * under the License.
18  */
19 
20 #pragma once
21 
22 #include <map>
23 #include <string>
24 #include <list>
25 #include <tuple>
26 #include <memory>
27 #include <iostream>
28 #include <functional>
29 #include <atomic>
30 #include <vector>
31 #include <cstring>
32 #include <chrono>
33 
35 #include "celix_constants.h"
36 #include "celix_properties.h"
37 #include "celix/Utils.h"
38 #include "celix/dm/Properties.h"
39 
40 namespace celix { namespace dm {
41 
43  suspend,
44  locking
45  };
46 
48  private:
49  const std::chrono::milliseconds warningTimoutForNonExpiredSvcObject{5000};
50  std::atomic<bool> depAddedToCmp{false};
51  celix_dm_component_t* cCmp;
52  protected:
53  celix_dm_service_dependency_t *cServiceDep {nullptr};
54 
56  if (strategy == DependencyUpdateStrategy::locking) {
58  } else { /*suspend*/
60  }
61  }
62 
63  template<typename U>
64  void waitForExpired(std::weak_ptr<U> observe, long svcId, const char* observeType);
65  public:
66  BaseServiceDependency(celix_dm_component_t* c) : cCmp{c} {
68  //NOTE using suspend as default strategy
70  }
71 
72  virtual ~BaseServiceDependency() noexcept;
73 
75  BaseServiceDependency& operator=(const BaseServiceDependency&) = delete;
76  BaseServiceDependency(BaseServiceDependency&&) noexcept = delete;
77  BaseServiceDependency& operator=(BaseServiceDependency&&) noexcept = delete;
78 
84  bool isValid() const __attribute__((deprecated)) { return true; }
85 
89  celix_dm_service_dependency_t *cServiceDependency() const { return cServiceDep; }
90 
97  void wait() const;
98 
104  void runBuild();
105  };
106 
107  template<class T>
109  using cmpType = T;
110  protected:
111  T* componentInstance {nullptr};
112  public:
113  TypedServiceDependency(celix_dm_component_t* cCmp) : BaseServiceDependency(cCmp) {}
114  ~TypedServiceDependency() override = default;
115 
118  TypedServiceDependency(TypedServiceDependency&&) noexcept = delete;
119  TypedServiceDependency& operator=(TypedServiceDependency&&) noexcept = delete;
120 
125  };
126 
133  template<class T, typename I>
135  using type = I;
136  public:
137  CServiceDependency(celix_dm_component_t* cCmp, const std::string &name);
138  ~CServiceDependency() override = default;
139 
140  CServiceDependency(const CServiceDependency&) = delete;
142  CServiceDependency(CServiceDependency&&) noexcept = delete;
143  CServiceDependency& operator=(CServiceDependency&&) noexcept = delete;
144 
151  CServiceDependency<T,I>& setVersionRange(const std::string &serviceVersionRange);
152 
159  CServiceDependency<T,I>& setFilter(const std::string &filter);
160 
167 
174 
180  CServiceDependency<T,I>& setCallbacks(void (T::*set)(const I* service));
181 
187  CServiceDependency<T,I>& setCallbacks(void (T::*set)(const I* service, Properties&& properties));
188 
194  CServiceDependency<T,I>& setCallbacks(std::function<void(const I* service, Properties&& properties)> set);
195 
201  CServiceDependency<T,I>& setCallbacks(void (T::*add)(const I* service), void (T::*remove)(const I* service));
202 
209  void (T::*add)(const I* service, Properties&& properties),
210  void (T::*remove)(const I* service, Properties&& properties)
211  );
212 
219  std::function<void(const I* service, Properties&& properties)> add,
220  std::function<void(const I* service, Properties&& properties)> remove
221  );
222 
230 
236 
237 
238 
239  private:
240  std::string name {};
241  std::string filter {};
242  std::string versionRange {};
243 
244  std::function<void(const I* service, Properties&& properties)> setFp{nullptr};
245  std::function<void(const I* service, Properties&& properties)> addFp{nullptr};
246  std::function<void(const I* service, Properties&& properties)> removeFp{nullptr};
247 
248  void setupCallbacks();
249  int invokeCallback(std::function<void(const I*, Properties&&)> fp, const celix_properties_t *props, const void* service);
250 
251  void setupService();
252  };
253 
259  template<class T, class I>
261  using type = I;
262  public:
263  ServiceDependency(celix_dm_component_t* cCmp, const std::string &name);
264  ~ServiceDependency() override = default;
265 
266  ServiceDependency(const ServiceDependency&) = delete;
268  ServiceDependency(ServiceDependency&&) noexcept = delete;
269  ServiceDependency& operator=(ServiceDependency&&) noexcept = delete;
270 
276  ServiceDependency<T,I>& setName(const std::string &_name);
277 
283  ServiceDependency<T,I>& setFilter(const std::string &filter);
284 
290  ServiceDependency<T,I>& setVersionRange(const std::string &versionRange);
291 
297  ServiceDependency<T,I>& setCallbacks(void (T::*set)(I* service));
298 
304  ServiceDependency<T,I>& setCallbacks(void (T::*set)(I* service, Properties&& properties));
305 
311  ServiceDependency<T,I>& setCallbacks(std::function<void(I* service, Properties&& properties)> set);
312 
318  ServiceDependency<T,I>& setCallbacks(void (T::*set)(const std::shared_ptr<I>& service, const std::shared_ptr<const celix::Properties>& properties));
319 
325  ServiceDependency<T,I>& setCallbacks(std::function<void(const std::shared_ptr<I>& service, const std::shared_ptr<const celix::Properties>& properties)> set);
326 
332  ServiceDependency<T,I>& setCallbacks(void (T::*set)(const std::shared_ptr<I>& service));
333 
339  ServiceDependency<T,I>& setCallbacks(std::function<void(const std::shared_ptr<I>& service)> set);
340 
346  ServiceDependency<T,I>& setCallbacks(void (T::*add)(I* service), void (T::*remove)(I* service));
347 
354  void (T::*add)(I* service, Properties&& properties),
355  void (T::*remove)(I* service, Properties&& properties)
356  );
357 
364  std::function<void(I* service, Properties&& properties)> add,
365  std::function<void(I* service, Properties&& properties)> remove
366  );
367 
374  void (T::*add)(const std::shared_ptr<I>& service, const std::shared_ptr<const celix::Properties>& properties),
375  void (T::*remove)(const std::shared_ptr<I>& service, const std::shared_ptr<const celix::Properties>& properties));
376 
383  std::function<void(const std::shared_ptr<I>& service, const std::shared_ptr<const celix::Properties>& properties)> add,
384  std::function<void(const std::shared_ptr<I>& service, const std::shared_ptr<const celix::Properties>& properties)> remove);
385 
386 
393  void (T::*add)(const std::shared_ptr<I>& service),
394  void (T::*remove)(const std::shared_ptr<I>& service));
395 
402  std::function<void(const std::shared_ptr<I>& service)> add,
403  std::function<void(const std::shared_ptr<I>& service)> remove);
404 
411 
418 
428 
436  private:
437  void setupService();
438  void setupCallbacks();
439  int invokeCallback(std::function<void(I*, Properties&&)> fp, const celix_properties_t *props, const void* service);
440 
441  std::string name {};
442  std::string filter {};
443  std::string versionRange {};
444 
445  std::function<void(I* service, Properties&& properties)> setFp{};
446  std::function<void(I* service, Properties&& properties)> addFp{};
447  std::function<void(I* service, Properties&& properties)> removeFp{};
448 
449  std::function<void(const std::shared_ptr<I>& service, const std::shared_ptr<const celix::Properties>& properties)> setFpUsingSharedPtr{};
450  std::function<void(const std::shared_ptr<I>& service, const std::shared_ptr<const celix::Properties>& properties)> addFpUsingSharedPtr{};
451  std::function<void(const std::shared_ptr<I>& service, const std::shared_ptr<const celix::Properties>& properties)> removeFpUsingSharedPtr{};
452 
453  //note below is only updated in the Celix event thread.
454  std::unordered_map<long, std::pair<std::shared_ptr<I>, std::shared_ptr<const celix::Properties>>> addedServices{};
455  std::pair<std::shared_ptr<I>, std::shared_ptr<const celix::Properties>> setService{};
456  };
457 }}
458 
celix::dm::ServiceDependency::setStrategy
ServiceDependency< T, I > & setStrategy(DependencyUpdateStrategy strategy)
Definition: ServiceDependency_Impl.h:472
celix::dm::ServiceDependency::setCallbacks
ServiceDependency< T, I > & setCallbacks(void(T::*set)(I *service))
Definition: ServiceDependency_Impl.h:296
celix::dm::CServiceDependency::setVersionRange
CServiceDependency< T, I > & setVersionRange(const std::string &serviceVersionRange)
Definition: ServiceDependency_Impl.h:95
celix::dm::TypedServiceDependency::operator=
TypedServiceDependency & operator=(const TypedServiceDependency &)=delete
celix::dm::CServiceDependency
A service dependency for a component.
Definition: ServiceDependency.h:134
celix::dm::ServiceDependency::setVersionRange
ServiceDependency< T, I > & setVersionRange(const std::string &versionRange)
Definition: ServiceDependency_Impl.h:288
celix::dm::BaseServiceDependency
Definition: ServiceDependency.h:47
celix::dm::BaseServiceDependency::~BaseServiceDependency
virtual ~BaseServiceDependency() noexcept
Definition: ServiceDependency_Impl.h:82
celix::dm::TypedServiceDependency::~TypedServiceDependency
~TypedServiceDependency() override=default
celix::dm::BaseServiceDependency::isValid
bool isValid() const __attribute__((deprecated))
Definition: ServiceDependency.h:84
celix
Definition: Bundle.h:28
celix_dmServiceDependency_setStrategy
CELIX_FRAMEWORK_EXPORT celix_status_t celix_dmServiceDependency_setStrategy(celix_dm_service_dependency_t *dependency, celix_dm_service_dependency_strategy_t strategy)
Properties.h
celix::dm::DependencyUpdateStrategy::suspend
@ suspend
celix::dm::DependencyUpdateStrategy::locking
@ locking
celix::dm::CServiceDependency::CServiceDependency
CServiceDependency(celix_dm_component_t *cCmp, const std::string &name)
Definition: ServiceDependency_Impl.h:89
celix::dm::BaseServiceDependency::wait
void wait() const
Definition: ServiceDependency_Impl.h:68
celix::dm::CServiceDependency::setStrategy
CServiceDependency< T, I > & setStrategy(DependencyUpdateStrategy strategy)
Definition: ServiceDependency_Impl.h:122
celix::dm::TypedServiceDependency::TypedServiceDependency
TypedServiceDependency(celix_dm_component_t *cCmp)
Definition: ServiceDependency.h:113
celix::dm::CServiceDependency::build
CServiceDependency< T, I > & build()
Definition: ServiceDependency_Impl.h:241
celix::dm::ServiceDependency::operator=
ServiceDependency & operator=(const ServiceDependency &)=delete
celix::dm::TypedServiceDependency::componentInstance
T * componentInstance
Definition: ServiceDependency.h:111
celix::dm::CServiceDependency::buildAsync
CServiceDependency< T, I > & buildAsync()
Definition: ServiceDependency_Impl.h:248
celix::dm::BaseServiceDependency::cServiceDep
celix_dm_service_dependency_t * cServiceDep
Definition: ServiceDependency.h:53
celix::dm::ServiceDependency::buildAsync
ServiceDependency< T, I > & buildAsync()
Definition: ServiceDependency_Impl.h:569
celix_dm_service_dependency.h
celix::dm::BaseServiceDependency::runBuild
void runBuild()
Definition: ServiceDependency_Impl.h:61
celix::dm::DependencyUpdateStrategy
DependencyUpdateStrategy
Definition: ServiceDependency.h:42
celix::dm::TypedServiceDependency::setComponentInstance
void setComponentInstance(T *cmp)
Definition: ServiceDependency.h:124
celix::dm::BaseServiceDependency::cServiceDependency
celix_dm_service_dependency_t * cServiceDependency() const
Definition: ServiceDependency.h:89
DM_SERVICE_DEPENDENCY_STRATEGY_LOCKING
@ DM_SERVICE_DEPENDENCY_STRATEGY_LOCKING
Definition: celix_dm_service_dependency.h:36
celix::dm::ServiceDependency::setName
ServiceDependency< T, I > & setName(const std::string &_name)
Definition: ServiceDependency_Impl.h:274
celix::dm::CServiceDependency::operator=
CServiceDependency & operator=(const CServiceDependency &)=delete
celix::dm::CServiceDependency::setCallbacks
CServiceDependency< T, I > & setCallbacks(void(T::*set)(const I *service))
Definition: ServiceDependency_Impl.h:129
celix::dm::ServiceDependency::ServiceDependency
ServiceDependency(celix_dm_component_t *cCmp, const std::string &name)
Definition: ServiceDependency_Impl.h:254
celix::dm::BaseServiceDependency::setDepStrategy
void setDepStrategy(DependencyUpdateStrategy strategy)
Definition: ServiceDependency.h:55
celix::dm::TypedServiceDependency
Definition: ServiceDependency.h:108
celix::dm::ServiceDependency::setRequired
ServiceDependency< T, I > & setRequired(bool req)
Definition: ServiceDependency_Impl.h:466
celix::dm::BaseServiceDependency::BaseServiceDependency
BaseServiceDependency(celix_dm_component_t *c)
Definition: ServiceDependency.h:66
celix::dm::ServiceDependency::~ServiceDependency
~ServiceDependency() override=default
ServiceDependency_Impl.h
celix::dm::ServiceDependency::setFilter
ServiceDependency< T, I > & setFilter(const std::string &filter)
Definition: ServiceDependency_Impl.h:281
celix::dm::CServiceDependency::setFilter
CServiceDependency< T, I > & setFilter(const std::string &filter)
Definition: ServiceDependency_Impl.h:102
celix_dmServiceDependency_create
CELIX_FRAMEWORK_EXPORT celix_dm_service_dependency_t * celix_dmServiceDependency_create(void)
DM_SERVICE_DEPENDENCY_STRATEGY_SUSPEND
@ DM_SERVICE_DEPENDENCY_STRATEGY_SUSPEND
Definition: celix_dm_service_dependency.h:37
celix::dm::Properties
celix::Properties Properties
Definition: Properties.h:25
celix::dm::BaseServiceDependency::waitForExpired
void waitForExpired(std::weak_ptr< U > observe, long svcId, const char *observeType)
Definition: ServiceDependency_Impl.h:37
celix::dm::ServiceDependency::build
ServiceDependency< T, I > & build()
Definition: ServiceDependency_Impl.h:562
celix::dm::ServiceDependency
A service dependency for a component.
Definition: ServiceDependency.h:260
celix::dm::CServiceDependency::~CServiceDependency
~CServiceDependency() override=default
celix::dm::CServiceDependency::setRequired
CServiceDependency< T, I > & setRequired(bool req)
Definition: ServiceDependency_Impl.h:116