Apache Celix  2.3.0
An implementation of the OSGi specification adapted to C and C++
Trackers.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 <memory>
23 #include <mutex>
24 #include <atomic>
25 #include <cassert>
26 #include <set>
27 #include <unordered_map>
28 #include <functional>
29 #include <thread>
30 
31 #include "celix_utils.h"
32 #include "celix/Properties.h"
33 #include "celix/Utils.h"
34 #include "celix/Bundle.h"
35 #include "celix/Constants.h"
36 #include "celix/Filter.h"
37 #include "celix_bundle_context.h"
38 #include "celix_framework.h"
39 
40 
41 namespace celix {
42 
43 
47  enum class TrackerState {
48  OPENING,
49  OPEN,
50  CLOSING,
51  CLOSED
52  };
53 
73  public:
74  explicit AbstractTracker(std::shared_ptr<celix_bundle_context_t> _cCtx) :
75  cCtx{std::move(_cCtx)} {}
76 
77  virtual ~AbstractTracker() noexcept = default;
78 
82  bool isOpen() const {
83  std::lock_guard<std::mutex> lck{mutex};
84  return state == TrackerState::OPEN;
85  }
86 
91  std::lock_guard<std::mutex> lck{mutex};
92  return state;
93  }
94 
101  void close() {
102  long localTrkId = -1;
103  {
104  std::lock_guard<std::mutex> lck{mutex};
106  //not yet closed
108  localTrkId = trkId;
109  trkId = -1;
110  }
111  }
112  if (localTrkId >= 0) {
113  celix_bundleContext_stopTracker(cCtx.get(), localTrkId);
114  {
115  std::lock_guard<std::mutex> lck{mutex};
117  }
118  }
119  }
120 
129  virtual void open() = 0;
130 
136  void wait() const {
137  bool needWaitOpening = false;
138  bool needWaitClosing = false;
139  long localId;
140  {
141  std::lock_guard<std::mutex> lck{mutex};
142  localId = trkId;
143  if (state == TrackerState::OPENING) {
144  needWaitOpening = true;
145  } else if (state == TrackerState::CLOSING) {
146  needWaitClosing = true;
147  }
148  }
149  if (needWaitOpening) {
151  }
152  if (needWaitClosing) {
154  }
155  }
156  protected:
160  void waitIfAble() const {
161  auto* fw = celix_bundleContext_getFramework(cCtx.get());
163  wait();
164  }
165  }
166 
167  template<typename T>
168  static std::function<void(T*)> delCallback() {
169  return [](T *tracker) {
170  if (tracker->getState() == TrackerState::CLOSED) {
171  delete tracker;
172  } else {
173  /*
174  * if open/opening -> close() -> new event on the Celix event thread
175  * if closing -> nop close() -> there is already a event on the Celix event thread to close
176  */
177  tracker->close();
178 
179  /*
180  * Creating event on the Event loop, this will be after the close is done
181  */
182  auto *fw = celix_bundleContext_getFramework(tracker->cCtx.get());
183  auto *bnd = celix_bundleContext_getBundle(tracker->cCtx.get());
184  long bndId = celix_bundle_getId(bnd);
186  fw,
187  -1,
188  bndId,
189  "celix::AbstractTracker delete callback",
190  tracker,
191  [](void *data) {
192  auto *t = static_cast<AbstractTracker *>(data);
193  delete t;
194  },
195  nullptr,
196  nullptr);
197  }
198  };
199  }
200 
201  const std::shared_ptr<celix_bundle_context_t> cCtx;
202 
203  mutable std::mutex mutex{}; //protects below
204  long trkId{-1L};
206  };
207 
218  public:
219  GenericServiceTracker(std::shared_ptr<celix_bundle_context_t> _cCtx, std::string_view _svcName,
220  std::string_view _svcVersionRange, celix::Filter _filter) : AbstractTracker{std::move(_cCtx)}, svcName{_svcName},
221  svcVersionRange{_svcVersionRange}, filter{std::move(_filter)} {
222  opts.trackerCreatedCallbackData = this;
223  opts.trackerCreatedCallback = [](void *data) {
224  auto* trk = static_cast<GenericServiceTracker*>(data);
225  {
226  std::lock_guard<std::mutex> callbackLock{trk->mutex};
227  trk->state = TrackerState::OPEN;
228  }
229  };
230  }
231 
232  ~GenericServiceTracker() override = default;
233 
237  void open() override {
238  std::lock_guard<std::mutex> lck{mutex};
241 
242  //NOTE assuming the opts already configured the callbacks
244  if (trkId < 0) {
245  throw celix::Exception{"Cannot open service tracker"};
246  }
247  }
248  }
249 
253  const std::string& getServiceName() const { return svcName; }
254 
258  const std::string& getServiceRange() const { return svcVersionRange; }
259 
266  const celix::Filter& getFilter() const { return filter; }
267 
271  std::size_t getServiceCount() const {
272  return svcCount;
273  }
274  protected:
275  const std::string svcName;
276  const std::string svcVersionRange;
277  const celix::Filter filter;
278  celix_service_tracking_options opts{}; //note only set in the ctor
279  std::atomic<size_t> svcCount{0};
280  };
281 
294  template<typename I>
296  public:
309  static std::shared_ptr<ServiceTracker<I>> create(
310  std::shared_ptr<celix_bundle_context_t> cCtx,
311  std::string_view svcName,
312  std::string_view svcVersionRange,
313  celix::Filter filter,
314  std::vector<std::function<void(const std::shared_ptr<I>&, const std::shared_ptr<const celix::Properties>&, const std::shared_ptr<const celix::Bundle>&)>> setCallbacks,
315  std::vector<std::function<void(const std::shared_ptr<I>&, const std::shared_ptr<const celix::Properties>&, const std::shared_ptr<const celix::Bundle>&)>> addCallbacks,
316  std::vector<std::function<void(const std::shared_ptr<I>&, const std::shared_ptr<const celix::Properties>&, const std::shared_ptr<const celix::Bundle>&)>> remCallbacks) {
317 
318  auto tracker = std::shared_ptr<ServiceTracker<I>>{
319  new ServiceTracker<I>{
320  std::move(cCtx),
321  svcName,
323  std::move(filter),
324  std::move(setCallbacks),
325  std::move(addCallbacks),
326  std::move(remCallbacks)},
327  AbstractTracker::delCallback<ServiceTracker<I>>()};
328  tracker->open();
329  return tracker;
330  }
331 
340  std::shared_ptr<I> getHighestRankingService() {
341  waitIfAble();
342  std::shared_ptr<I> result{};
343  std::lock_guard<std::mutex> lck{mutex};
344  auto it = entries.begin();
345  if (it != entries.end()) {
346  result = (*it)->svc;
347  }
348  return result;
349  }
350 
359  std::vector<std::shared_ptr<I>> getServices() {
360  waitIfAble();
361  std::vector<std::shared_ptr<I>> result{};
362  std::lock_guard<std::mutex> lck{mutex};
363  result.reserve(entries.size());
364  for (auto& e : entries) {
365  result.push_back(e->svc);
366  }
367  return result;
368  }
369  protected:
370  struct SvcEntry {
371  SvcEntry(long _svcId, long _svcRanking, std::shared_ptr<I> _svc,
372  std::shared_ptr<const celix::Properties> _properties,
373  std::shared_ptr<const celix::Bundle> _owner) : svcId(_svcId), svcRanking(_svcRanking),
374  svc(std::move(_svc)),
375  properties(std::move(_properties)),
376  owner(std::move(_owner)) {}
377  long svcId;
379  std::shared_ptr<I> svc;
380  std::shared_ptr<const celix::Properties> properties;
381  std::shared_ptr<const celix::Bundle> owner;
382  };
383 
384  ServiceTracker(std::shared_ptr<celix_bundle_context_t> _cCtx, std::string_view _svcName,
385  std::string_view _svcVersionRange, celix::Filter _filter,
386  std::vector<std::function<void(const std::shared_ptr<I>&, const std::shared_ptr<const celix::Properties>&, const std::shared_ptr<const celix::Bundle>&)>> _setCallbacks,
387  std::vector<std::function<void(const std::shared_ptr<I>&, const std::shared_ptr<const celix::Properties>&, const std::shared_ptr<const celix::Bundle>&)>> _addCallbacks,
388  std::vector<std::function<void(const std::shared_ptr<I>&, const std::shared_ptr<const celix::Properties>&, const std::shared_ptr<const celix::Bundle>&)>> _remCallbacks) :
389  GenericServiceTracker{std::move(_cCtx), _svcName, _svcVersionRange, std::move(_filter)},
390  setCallbacks{std::move(_setCallbacks)},
391  addCallbacks{std::move(_addCallbacks)},
392  remCallbacks{std::move(_remCallbacks)} {
393  opts.filter.serviceName = svcName.empty() ? nullptr : svcName.c_str();
394  opts.filter.versionRange = svcVersionRange.empty() ? nullptr : svcVersionRange.c_str();
395  opts.filter.filter = filter.empty() ? nullptr : filter.getFilterCString();
396  opts.callbackHandle = this;
397  opts.addWithOwner = [](void *handle, void *voidSvc, const celix_properties_t* cProps, const celix_bundle_t* cBnd) {
398  auto tracker = static_cast<ServiceTracker<I>*>(handle);
399  auto entry = createEntry(voidSvc, cProps, cBnd);
400  {
401  std::lock_guard<std::mutex> lck{tracker->mutex};
402  tracker->entries.insert(entry);
403  tracker->cachedEntries[entry->svcId] = entry;
404  }
405  tracker->svcCount.fetch_add(1, std::memory_order_relaxed);
406  for (const auto& cb : tracker->addCallbacks) {
407  cb(entry->svc, entry->properties, entry->owner);
408  }
409  tracker->invokeUpdateCallbacks();
410  };
411  opts.removeWithOwner = [](void *handle, void*, const celix_properties_t* cProps, const celix_bundle_t*) {
412  auto tracker = static_cast<ServiceTracker<I>*>(handle);
413  long svcId = celix_properties_getAsLong(cProps, OSGI_FRAMEWORK_SERVICE_ID, -1L);
414  std::shared_ptr<SvcEntry> entry{};
415  {
416  std::lock_guard<std::mutex> lck{tracker->mutex};
417  auto it = tracker->cachedEntries.find(svcId);
418  assert(it != tracker->cachedEntries.end()); //should not happen, added during add callback
419  entry = it->second;
420  tracker->cachedEntries.erase(it);
421  tracker->entries.erase(entry);
422  }
423  for (const auto& cb : tracker->remCallbacks) {
424  cb(entry->svc, entry->properties, entry->owner);
425  }
426  tracker->invokeUpdateCallbacks();
427  tracker->svcCount.fetch_sub(1, std::memory_order_relaxed);
428  tracker->waitForExpiredSvcEntry(entry);
429  };
430  opts.setWithOwner = [](void *handle, void *voidSvc, const celix_properties_t *cProps, const celix_bundle_t *cBnd) {
431  auto tracker = static_cast<ServiceTracker<I>*>(handle);
432  std::lock_guard<std::mutex> lck{tracker->mutex};
433  auto prevEntry = tracker->highestRankingServiceEntry;
434  if (voidSvc) {
435  tracker->highestRankingServiceEntry = createEntry(voidSvc, cProps, cBnd);
436  } else {
437  tracker->highestRankingServiceEntry = nullptr;
438  }
439  for (const auto& cb : tracker->setCallbacks) {
440  if (tracker->highestRankingServiceEntry) {
441  auto& e = tracker->highestRankingServiceEntry;
442  cb(e->svc, e->properties, e->owner);
443  } else /*"unset"*/ {
444  cb(nullptr, nullptr, nullptr);
445  }
446  }
447  tracker->waitForExpiredSvcEntry(prevEntry);
448  };
449  }
450 
451  static std::shared_ptr<SvcEntry> createEntry(void* voidSvc, const celix_properties_t* cProps, const celix_bundle_t* cBnd) {
452  long svcId = celix_properties_getAsLong(cProps, OSGI_FRAMEWORK_SERVICE_ID, -1L);
453  long svcRanking = celix_properties_getAsLong(cProps, OSGI_FRAMEWORK_SERVICE_RANKING, 0);
454  auto svc = std::shared_ptr<I>{static_cast<I*>(voidSvc), [](I*){/*nop*/}};
455  auto props = celix::Properties::wrap(cProps);
456  auto owner = std::make_shared<celix::Bundle>(const_cast<celix_bundle_t*>(cBnd));
457  return std::make_shared<SvcEntry>(svcId, svcRanking, svc, props, owner);
458  }
459 
460  void waitForExpiredSvcEntry(std::shared_ptr<SvcEntry>& entry) {
461  if (entry) {
462  std::weak_ptr<void> svcObserve = entry->svc;
463  std::weak_ptr<const celix::Properties> propsObserve = entry->properties;
464  std::weak_ptr<const celix::Bundle> ownerObserve = entry->owner;
465  entry->svc = nullptr;
466  entry->properties = nullptr;
467  entry->owner = nullptr;
468  waitForExpired(svcObserve, entry->svcId, "service");
469  waitForExpired(propsObserve, entry->svcId, "service properties");
470  waitForExpired(ownerObserve, entry->svcId, "service bundle (owner)");
471  }
472  }
473 
474  template<typename U>
475  void waitForExpired(std::weak_ptr<U> observe, long svcId, const char* objName) {
476  auto start = std::chrono::system_clock::now();
477  while (!observe.expired()) {
478  auto now = std::chrono::system_clock::now();
479  auto durationInMilli = std::chrono::duration_cast<std::chrono::milliseconds>(now - start);
480  if (durationInMilli > warningTimoutForNonExpiredSvcObject) {
481  celix_bundleContext_log(cCtx.get(), CELIX_LOG_LEVEL_WARNING, "Cannot remove %s associated with service.id %li, because it is still in use. Current shared_ptr use count is %i\n", objName, svcId, (int)observe.use_count());
482  start = now;
483  }
484  std::this_thread::sleep_for(std::chrono::milliseconds{50});
485  }
486  }
487 
489  if (!updateCallbacks.empty()) {
490  std::vector<std::shared_ptr<I>> updateVector{};
491  {
492  std::lock_guard<std::mutex> lck{mutex};
493  updateVector.reserve(entries.size());
494  for (const auto &entry : entries) {
495  updateVector.push_back(entry->svc);
496  }
497  }
498  for (const auto& cb : updateCallbacks) {
499  cb(updateVector);
500  }
501  }
502  if (!updateWithPropertiesCallbacks.empty()) {
503  std::vector<std::pair<std::shared_ptr<I>, std::shared_ptr<const celix::Properties>>> updateVector{};
504  updateVector.reserve(entries.size());
505  {
506  std::lock_guard<std::mutex> lck{mutex};
507  for (const auto &entry : entries) {
508  updateVector.emplace_back(entry->svc, entry->properties);
509  }
510  }
511  for (const auto& cb : updateWithPropertiesCallbacks) {
512  cb(updateVector);
513  }
514  }
515  if (!updateWithOwnerCallbacks.empty()) {
516  std::vector<std::tuple<std::shared_ptr<I>, std::shared_ptr<const celix::Properties>, std::shared_ptr<const celix::Bundle>>> updateVector{};
517  updateVector.reserve(entries.size());
518  {
519  std::lock_guard<std::mutex> lck{mutex};
520  for (const auto &entry : entries) {
521  updateVector.emplace_back(entry->svc, entry->properties, entry->owner);
522  }
523  }
524  for (const auto& cb : updateWithOwnerCallbacks) {
525  cb(updateVector);
526  }
527  }
528  }
529 
530  const std::chrono::milliseconds warningTimoutForNonExpiredSvcObject{1000};
531 
532  const std::vector<std::function<void(const std::shared_ptr<I>&, const std::shared_ptr<const celix::Properties>&, const std::shared_ptr<const celix::Bundle>&)>> setCallbacks;
533  const std::vector<std::function<void(const std::shared_ptr<I>&, const std::shared_ptr<const celix::Properties>&, const std::shared_ptr<const celix::Bundle>&)>> addCallbacks;
534  const std::vector<std::function<void(const std::shared_ptr<I>&, const std::shared_ptr<const celix::Properties>&, const std::shared_ptr<const celix::Bundle>&)>> remCallbacks;
535 
536  //NOTE update callbacks cannot yet be configured
537  const std::vector<std::function<void(const std::vector<std::shared_ptr<I>>)>> updateCallbacks{};
538  const std::vector<std::function<void(const std::vector<std::pair<std::shared_ptr<I>, std::shared_ptr<const celix::Properties>>>)>> updateWithPropertiesCallbacks{};
539  const std::vector<std::function<void(const std::vector<std::tuple<std::shared_ptr<I>, std::shared_ptr<const celix::Properties>, std::shared_ptr<const celix::Bundle>>>)>> updateWithOwnerCallbacks{};
540 
542  bool operator() (const std::shared_ptr<SvcEntry>& a, const std::shared_ptr<SvcEntry>& b) const {
543  int cmp = celix_utils_compareServiceIdsAndRanking(a->svcId, a->svcRanking, b->svcId, b->svcRanking);
544  return cmp < 0;
545  }
546  };
547 
548  mutable std::mutex mutex{}; //protect below
549  std::set<std::shared_ptr<SvcEntry>, SvcEntryCompare> entries{};
550  std::unordered_map<long, std::shared_ptr<SvcEntry>> cachedEntries{};
551  std::shared_ptr<SvcEntry> highestRankingServiceEntry{};
552  };
553 
559  public:
571  static std::shared_ptr<BundleTracker> create(
572  std::shared_ptr<celix_bundle_context_t> cCtx,
573  bool includeFrameworkBundle,
574  std::vector<std::function<void(const celix::Bundle&)>> onInstallCallbacks,
575  std::vector<std::function<void(const celix::Bundle&)>> onStartCallbacks,
576  std::vector<std::function<void(const celix::Bundle&)>> onStopCallbacks) {
577 
578  auto tracker = std::shared_ptr<BundleTracker>{
579  new BundleTracker{
580  std::move(cCtx),
581  includeFrameworkBundle,
582  std::move(onInstallCallbacks),
583  std::move(onStartCallbacks),
584  std::move(onStopCallbacks)},
585  AbstractTracker::delCallback<BundleTracker>()};
586  tracker->open();
587  return tracker;
588  }
589 
593  void open() override {
594  std::lock_guard<std::mutex> lck{mutex};
597  //NOTE the opts already configured the callbacks
599  if (trkId < 0) {
600  throw celix::Exception{"Cannot open bundle tracker"};
601  }
602  }
603  }
604  private:
606  std::shared_ptr<celix_bundle_context_t> _cCtx,
607  bool _includeFrameworkBundle,
608  std::vector<std::function<void(const celix::Bundle&)>> _onInstallCallbacks,
609  std::vector<std::function<void(const celix::Bundle&)>> _onStartCallbacks,
610  std::vector<std::function<void(const celix::Bundle&)>> _onStopCallbacks) :
611  AbstractTracker{std::move(_cCtx)},
612  includeFrameworkBundle{_includeFrameworkBundle},
613  onInstallCallbacks{std::move(_onInstallCallbacks)},
614  onStartCallbacks{std::move(_onStartCallbacks)},
615  onStopCallbacks{std::move(_onStopCallbacks)} {
616 
617 
618  opts.includeFrameworkBundle = includeFrameworkBundle;
619  opts.callbackHandle = this;
620  opts.onInstalled = [](void *handle, const celix_bundle_t *cBnd) {
621  auto tracker = static_cast<BundleTracker *>(handle);
622  celix::Bundle bnd{const_cast<celix_bundle_t *>(cBnd)};
623  for (const auto& cb : tracker->onInstallCallbacks) {
624  cb(bnd);
625  }
626  };
627  opts.onStarted = [](void *handle, const celix_bundle_t *cBnd) {
628  auto tracker = static_cast<BundleTracker *>(handle);
629  celix::Bundle bnd{const_cast<celix_bundle_t *>(cBnd)};
630  for (const auto& cb : tracker->onStartCallbacks) {
631  cb(bnd);
632  }
633  };
634  opts.onStopped = [](void *handle, const celix_bundle_t *cBnd) {
635  auto tracker = static_cast<BundleTracker *>(handle);
636  celix::Bundle bnd{const_cast<celix_bundle_t *>(cBnd)};
637  for (const auto& cb : tracker->onStopCallbacks) {
638  cb(bnd);
639  }
640  };
641  opts.trackerCreatedCallbackData = this;
642  opts.trackerCreatedCallback = [](void *data) {
643  auto* trk = static_cast<BundleTracker*>(data);
644  std::lock_guard<std::mutex> callbackLock{trk->mutex};
645  trk->state = TrackerState::OPEN;
646  };
647  }
648 
649  const bool includeFrameworkBundle;
650  const std::vector<std::function<void(const celix::Bundle&)>> onInstallCallbacks;
651  const std::vector<std::function<void(const celix::Bundle&)>> onStartCallbacks;
652  const std::vector<std::function<void(const celix::Bundle&)>> onStopCallbacks;
653  celix_bundle_tracking_options_t opts{}; //note only set in the ctor
654  };
655 
656 
666  const std::string serviceName;
667 
671  const celix::Filter filter;
672 
677  };
678 
684  class MetaTracker : public AbstractTracker {
685  public:
686 
697  static std::shared_ptr<MetaTracker> create(
698  std::shared_ptr<celix_bundle_context_t> cCtx,
699  std::string_view serviceName,
700  std::vector<std::function<void(const ServiceTrackerInfo&)>> onTrackerCreated,
701  std::vector<std::function<void(const ServiceTrackerInfo&)>> onTrackerDestroyed) {
702 
703  auto tracker = std::shared_ptr<MetaTracker>{
704  new MetaTracker{
705  std::move(cCtx),
706  serviceName,
707  std::move(onTrackerCreated),
708  std::move(onTrackerDestroyed)},
709  AbstractTracker::delCallback<MetaTracker>()};
710  tracker->open();
711  return tracker;
712  }
713 
717  void open() override {
718  std::lock_guard<std::mutex> lck{mutex};
721 
722  //NOTE the opts already configured the callbacks
724  cCtx.get(),
725  serviceName.empty() ? nullptr : serviceName.c_str(),
726  static_cast<void*>(this),
727  [](void *handle, const celix_service_tracker_info_t *cInfo) {
728  auto *trk = static_cast<MetaTracker *>(handle);
729  std::string svcName = cInfo->serviceName == nullptr ? "" : cInfo->serviceName;
730  ServiceTrackerInfo info{svcName, celix::Filter::wrap(cInfo->filter), cInfo->bundleId};
731  for (const auto& cb : trk->onTrackerCreated) {
732  cb(info);
733  }
734  },
735  [](void *handle, const celix_service_tracker_info_t *cInfo) {
736  auto *trk = static_cast<MetaTracker *>(handle);
737  std::string svcName = cInfo->serviceName == nullptr ? "" : cInfo->serviceName;
738  ServiceTrackerInfo info{svcName, celix::Filter::wrap(cInfo->filter), cInfo->bundleId};
739  for (const auto& cb : trk->onTrackerDestroyed) {
740  cb(info);
741  }
742  },
743  static_cast<void*>(this),
744  [](void *data) {
745  auto *trk = static_cast<MetaTracker *>(data);
746  std::lock_guard<std::mutex> callbackLock{trk->mutex};
747  trk->state = TrackerState::OPEN;
748  });
749  if (trkId < 0) {
750  throw celix::Exception{"Cannot open meta tracker"};
751  }
752  }
753  }
754 
755  private:
756  MetaTracker(
757  std::shared_ptr<celix_bundle_context_t> _cCtx,
758  std::string_view _serviceName,
759  std::vector<std::function<void(const ServiceTrackerInfo&)>> _onTrackerCreated,
760  std::vector<std::function<void(const ServiceTrackerInfo&)>> _onTrackerDestroyed) :
761  AbstractTracker{std::move(_cCtx)},
762  serviceName{_serviceName},
763  onTrackerCreated{std::move(_onTrackerCreated)},
764  onTrackerDestroyed{std::move(_onTrackerDestroyed)} {}
765 
766  const std::string serviceName;
767  const std::vector<std::function<void(const ServiceTrackerInfo&)>> onTrackerCreated;
768  const std::vector<std::function<void(const ServiceTrackerInfo&)>> onTrackerDestroyed;
769  };
770 
771 }
celix::ServiceTracker::warningTimoutForNonExpiredSvcObject
const std::chrono::milliseconds warningTimoutForNonExpiredSvcObject
Definition: Trackers.h:530
Bundle.h
celix::ServiceTracker::entries
std::set< std::shared_ptr< SvcEntry >, SvcEntryCompare > entries
Definition: Trackers.h:549
celix::ServiceTrackerInfo::serviceName
const std::string serviceName
The service name the service tracker is tracking.
Definition: Trackers.h:666
celix_framework_fireGenericEvent
long celix_framework_fireGenericEvent(celix_framework_t *fw, long eventId, long bndId, const char *eventName, void *processData, void(*processCallback)(void *data), void *doneData, void(*doneCallback)(void *doneData))
Fire a generic event. The event will be added to the event loop and handled on the event loop thread.
celix::GenericServiceTracker::~GenericServiceTracker
~GenericServiceTracker() override=default
celix_service_tracking_options::addWithOwner
void(* addWithOwner)(void *handle, void *svc, const celix_properties_t *props, const celix_bundle_t *svcOwner) CELIX_OPTS_INIT
The optional addWithOwner callback is handled as the add callback, but with the addition that the ser...
Definition: celix_bundle_context.h:526
celix::GenericServiceTracker::open
void open() override
Definition: Trackers.h:237
celix::ServiceTracker::updateWithPropertiesCallbacks
const std::vector< std::function< void(const std::vector< std::pair< std::shared_ptr< I >, std::shared_ptr< const celix::Properties >>>)> > updateWithPropertiesCallbacks
Definition: Trackers.h:538
celix::ServiceTracker::SvcEntry
Definition: Trackers.h:370
celix::ServiceTrackerInfo
A trivial struct containing information about a service tracker.
Definition: Trackers.h:660
celix::GenericServiceTracker::filter
const celix::Filter filter
Definition: Trackers.h:277
celix::ServiceTracker::remCallbacks
const std::vector< std::function< void(const std::shared_ptr< I > &, const std::shared_ptr< const celix::Properties > &, const std::shared_ptr< const celix::Bundle > &)> > remCallbacks
Definition: Trackers.h:534
celix::GenericServiceTracker::opts
celix_service_tracking_options opts
Definition: Trackers.h:278
celix
Definition: Bundle.h:26
celix::ServiceTracker::SvcEntryCompare::operator()
bool operator()(const std::shared_ptr< SvcEntry > &a, const std::shared_ptr< SvcEntry > &b) const
Definition: Trackers.h:542
celix::ServiceTracker::setCallbacks
const std::vector< std::function< void(const std::shared_ptr< I > &, const std::shared_ptr< const celix::Properties > &, const std::shared_ptr< const celix::Bundle > &)> > setCallbacks
Definition: Trackers.h:532
celix::AbstractTracker::delCallback
static std::function< void(T *)> delCallback()
Definition: Trackers.h:168
celix::ServiceTracker::createEntry
static std::shared_ptr< SvcEntry > createEntry(void *voidSvc, const celix_properties_t *cProps, const celix_bundle_t *cBnd)
Definition: Trackers.h:451
celix::MetaTracker::create
static std::shared_ptr< MetaTracker > create(std::shared_ptr< celix_bundle_context_t > cCtx, std::string_view serviceName, std::vector< std::function< void(const ServiceTrackerInfo &)>> onTrackerCreated, std::vector< std::function< void(const ServiceTrackerInfo &)>> onTrackerDestroyed)
Creates a new meta tracker and opens the tracker.
Definition: Trackers.h:697
celix::GenericServiceTracker::GenericServiceTracker
GenericServiceTracker(std::shared_ptr< celix_bundle_context_t > _cCtx, std::string_view _svcName, std::string_view _svcVersionRange, celix::Filter _filter)
Definition: Trackers.h:219
celix_bundle_tracker_options::trackerCreatedCallback
void(* trackerCreatedCallback)(void *trackerCreatedCallbackData) CELIX_OPTS_INIT
The callback called when the tracker has ben created (and is active) when using the track bundles asc...
Definition: celix_bundle_context.h:1054
celix_bundle_tracker_options
The Service Bundle Tracking options can be used to fine tune the requested bundle tracker options.
Definition: celix_bundle_context.h:998
Constants.h
celix_bundleContext_trackServicesWithOptionsAsync
long celix_bundleContext_trackServicesWithOptionsAsync(celix_bundle_context_t *ctx, const celix_service_tracking_options_t *opts)
Tracks services using the provided tracker options.
celix::ServiceTracker::waitForExpired
void waitForExpired(std::weak_ptr< U > observe, long svcId, const char *objName)
Definition: Trackers.h:475
celix_bundleContext_trackBundlesWithOptionsAsync
long celix_bundleContext_trackBundlesWithOptionsAsync(celix_bundle_context_t *ctx, const celix_bundle_tracking_options_t *opts)
Tracks bundles using the provided bundle tracker options.
celix::BundleTracker::open
void open() override
Definition: Trackers.h:593
celix::GenericServiceTracker::getServiceRange
const std::string & getServiceRange() const
The service version range tracked by this service tracker.
Definition: Trackers.h:258
celix::ServiceTracker::waitForExpiredSvcEntry
void waitForExpiredSvcEntry(std::shared_ptr< SvcEntry > &entry)
Definition: Trackers.h:460
celix::AbstractTracker::state
TrackerState state
Definition: Trackers.h:205
celix::GenericServiceTracker::getFilter
const celix::Filter & getFilter() const
The additional filter for services tracked by this service tracker.
Definition: Trackers.h:266
celix::TrackerState
TrackerState
The tracker state.
Definition: Trackers.h:47
celix::AbstractTracker::open
virtual void open()=0
Open the tracker (if the state is not OPEN or OPENING).
celix::ServiceTracker::getHighestRankingService
std::shared_ptr< I > getHighestRankingService()
Get the current highest ranking service tracked by this tracker.
Definition: Trackers.h:340
celix::ServiceTrackerInfo::trackerOwnerBundleId
const long trackerOwnerBundleId
The bundle id of the owner of the service tracker.
Definition: Trackers.h:676
celix::ServiceTracker::SvcEntry::owner
std::shared_ptr< const celix::Bundle > owner
Definition: Trackers.h:381
celix::TrackerState::OPENING
@ OPENING
celix::GenericServiceTracker
he GenericServiceTracker class is a specialization of the AbstractTracker for managing a service trac...
Definition: Trackers.h:217
celix::ServiceTracker::ServiceTracker
ServiceTracker(std::shared_ptr< celix_bundle_context_t > _cCtx, std::string_view _svcName, std::string_view _svcVersionRange, celix::Filter _filter, std::vector< std::function< void(const std::shared_ptr< I > &, const std::shared_ptr< const celix::Properties > &, const std::shared_ptr< const celix::Bundle > &)>> _setCallbacks, std::vector< std::function< void(const std::shared_ptr< I > &, const std::shared_ptr< const celix::Properties > &, const std::shared_ptr< const celix::Bundle > &)>> _addCallbacks, std::vector< std::function< void(const std::shared_ptr< I > &, const std::shared_ptr< const celix::Properties > &, const std::shared_ptr< const celix::Bundle > &)>> _remCallbacks)
Definition: Trackers.h:384
celix::GenericServiceTracker::getServiceCount
std::size_t getServiceCount() const
The nr of services currently tracked by this tracker.
Definition: Trackers.h:271
celix::ServiceTracker::SvcEntry::properties
std::shared_ptr< const celix::Properties > properties
Definition: Trackers.h:380
celix::ServiceTracker
The ServiceTracker class tracks services.
Definition: Trackers.h:295
celix::GenericServiceTracker::svcCount
std::atomic< size_t > svcCount
Definition: Trackers.h:279
celix_service_tracking_options::trackerCreatedCallback
void(* trackerCreatedCallback)(void *trackerCreatedCallbackData) CELIX_OPTS_INIT
The callback called when the tracker has ben created (and is active) when using a async call.
Definition: celix_bundle_context.h:564
celix::BundleTracker
The BundleTracker class tracks bundles.
Definition: Trackers.h:558
celix_framework.h
celix_service_tracking_options::removeWithOwner
void(* removeWithOwner)(void *handle, void *svc, const celix_properties_t *props, const celix_bundle_t *svcOwner) CELIX_OPTS_INIT
The optional removeWithOwner callback is handled as the remove callback, but with the addition that t...
Definition: celix_bundle_context.h:549
celix::ServiceTracker::cachedEntries
std::unordered_map< long, std::shared_ptr< SvcEntry > > cachedEntries
Definition: Trackers.h:550
celix::MetaTracker
The MetaTracker track service trackers.
Definition: Trackers.h:684
celix::AbstractTracker::waitIfAble
void waitIfAble() const
Wait (if not on the Celix event thread) for the tracker to be OPEN or CLOSED.
Definition: Trackers.h:160
celix_bundleContext_getFramework
celix_framework_t * celix_bundleContext_getFramework(const celix_bundle_context_t *ctx)
celix::ServiceTracker::SvcEntryCompare
Definition: Trackers.h:541
celix_service_tracking_options
Service Tracker Options used to fine tune which services to track and the callback to be used for the...
Definition: celix_bundle_context.h:477
celix::Bundle
An installed bundle in the Celix framework.
Definition: Bundle.h:47
celix::TrackerState::CLOSED
@ CLOSED
celix::ServiceTracker::mutex
std::mutex mutex
Definition: Trackers.h:548
celix::AbstractTracker::mutex
std::mutex mutex
Definition: Trackers.h:203
celix::AbstractTracker::getState
TrackerState getState() const
Get the current state of the tracker.
Definition: Trackers.h:90
celix::ServiceTracker::create
static std::shared_ptr< ServiceTracker< I > > create(std::shared_ptr< celix_bundle_context_t > cCtx, std::string_view svcName, std::string_view svcVersionRange, celix::Filter filter, std::vector< std::function< void(const std::shared_ptr< I > &, const std::shared_ptr< const celix::Properties > &, const std::shared_ptr< const celix::Bundle > &)>> setCallbacks, std::vector< std::function< void(const std::shared_ptr< I > &, const std::shared_ptr< const celix::Properties > &, const std::shared_ptr< const celix::Bundle > &)>> addCallbacks, std::vector< std::function< void(const std::shared_ptr< I > &, const std::shared_ptr< const celix::Properties > &, const std::shared_ptr< const celix::Bundle > &)>> remCallbacks)
Creates a new service tracker and opens the tracker.
Definition: Trackers.h:309
celix::ServiceTracker::updateWithOwnerCallbacks
const std::vector< std::function< void(const std::vector< std::tuple< std::shared_ptr< I >, std::shared_ptr< const celix::Properties >, std::shared_ptr< const celix::Bundle >>>)> > updateWithOwnerCallbacks
Definition: Trackers.h:539
celix::BundleTracker::create
static std::shared_ptr< BundleTracker > create(std::shared_ptr< celix_bundle_context_t > cCtx, bool includeFrameworkBundle, std::vector< std::function< void(const celix::Bundle &)>> onInstallCallbacks, std::vector< std::function< void(const celix::Bundle &)>> onStartCallbacks, std::vector< std::function< void(const celix::Bundle &)>> onStopCallbacks)
Creates a new bundle tracker and opens the tracker.
Definition: Trackers.h:571
celix_bundleContext_stopTracker
void celix_bundleContext_stopTracker(celix_bundle_context_t *ctx, long trackerId)
Stop the tracker with the provided track id.
celix::AbstractTracker::wait
void wait() const
Wait until a service tracker is completely OPEN or CLOSED.
Definition: Trackers.h:136
celix_bundle_tracker_options::onStarted
void(* onStarted)(void *handle, const celix_bundle_t *bundle) CELIX_OPTS_INIT
Tracker callback when a bundle is started.
Definition: celix_bundle_context.h:1018
celix::GenericServiceTracker::svcName
const std::string svcName
Definition: Trackers.h:275
celix_bundle_tracker_options::onInstalled
void(* onInstalled)(void *handle, const celix_bundle_t *bundle) CELIX_OPTS_INIT
Tracker callback when a bundle is installed.
Definition: celix_bundle_context.h:1010
celix::ServiceTracker::SvcEntry::svc
std::shared_ptr< I > svc
Definition: Trackers.h:379
celix::TrackerState::CLOSING
@ CLOSING
celix::ServiceTracker::SvcEntry::svcId
long svcId
Definition: Trackers.h:377
celix::ServiceTracker::invokeUpdateCallbacks
void invokeUpdateCallbacks()
Definition: Trackers.h:488
celix_framework_isCurrentThreadTheEventLoop
bool celix_framework_isCurrentThreadTheEventLoop(celix_framework_t *fw)
Returns whether the current thread is the Celix framework event loop thread.
celix::ServiceTracker::SvcEntry::svcRanking
long svcRanking
Definition: Trackers.h:378
celix::AbstractTracker::AbstractTracker
AbstractTracker(std::shared_ptr< celix_bundle_context_t > _cCtx)
Definition: Trackers.h:74
celix::AbstractTracker::isOpen
bool isOpen() const
Check if the tracker is open (state == OPEN)
Definition: Trackers.h:82
celix_bundleContext_log
void celix_bundleContext_log(const celix_bundle_context_t *ctx, celix_log_level_e level, const char *format,...)
Logs a message to Celix framework logger with the provided log level.
celix::AbstractTracker::trkId
long trkId
Definition: Trackers.h:204
celix_bundleContext_waitForAsyncTracker
void celix_bundleContext_waitForAsyncTracker(celix_bundle_context_t *ctx, long trackerId)
Wait for (async) creation of tracker.
celix::AbstractTracker::cCtx
const std::shared_ptr< celix_bundle_context_t > cCtx
Definition: Trackers.h:201
celix::GenericServiceTracker::getServiceName
const std::string & getServiceName() const
The service name tracked by this service tracker.
Definition: Trackers.h:253
celix_service_tracker_info
Service Tracker Info provided to the service tracker tracker callbacks.
Definition: celix_bundle_context.h:1137
celix_service_tracking_options::setWithOwner
void(* setWithOwner)(void *handle, void *svc, const celix_properties_t *props, const celix_bundle_t *svcOwner) CELIX_OPTS_INIT
The optional setWithOwner callback is handled as the set callback, but with the addition that the ser...
Definition: celix_bundle_context.h:506
celix::AbstractTracker::~AbstractTracker
virtual ~AbstractTracker() noexcept=default
celix_bundle_tracker_options::onStopped
void(* onStopped)(void *handle, const celix_bundle_t *bundle) CELIX_OPTS_INIT
Tracker callback when a bundle is stopped.
Definition: celix_bundle_context.h:1026
celix::TrackerState::OPEN
@ OPEN
celix_bundle_getId
long celix_bundle_getId(const celix_bundle_t *bnd)
Returns the bundle id.
celix::ServiceTracker::addCallbacks
const std::vector< std::function< void(const std::shared_ptr< I > &, const std::shared_ptr< const celix::Properties > &, const std::shared_ptr< const celix::Bundle > &)> > addCallbacks
Definition: Trackers.h:533
celix::AbstractTracker::close
void close()
Close the tracker (of the state is not CLOSED or CLOSING).
Definition: Trackers.h:101
celix_bundleContext_trackServiceTrackersAsync
long celix_bundleContext_trackServiceTrackersAsync(celix_bundle_context_t *ctx, const char *serviceName, void *callbackHandle, void(*trackerAdd)(void *handle, const celix_service_tracker_info_t *info), void(*trackerRemove)(void *handle, const celix_service_tracker_info_t *info), void *doneCallbackData, void(*doneCallback)(void *doneCallbackData))
Track the service tracker targeting the provided service name.
celix::GenericServiceTracker::svcVersionRange
const std::string svcVersionRange
Definition: Trackers.h:276
celix::Exception
Celix runtime Exception.
Definition: Exception.h:28
celix::AbstractTracker
The AbstractTracker class is the base of all C++ Celix trackers.
Definition: Trackers.h:72
celix::MetaTracker::open
void open() override
Definition: Trackers.h:717
celix_bundleContext_waitForAsyncStopTracker
void celix_bundleContext_waitForAsyncStopTracker(celix_bundle_context_t *ctx, long trackerId)
Wait for (async) stopping of tracking.
celix::ServiceTracker::getServices
std::vector< std::shared_ptr< I > > getServices()
Get a vector of all the currently found services for this tracker.
Definition: Trackers.h:359
celix::ServiceTrackerInfo::filter
const celix::Filter filter
The service filter the service tracker is using for tracking.
Definition: Trackers.h:671
celix::ServiceTracker::highestRankingServiceEntry
std::shared_ptr< SvcEntry > highestRankingServiceEntry
Definition: Trackers.h:551
celix_bundle_context.h
celix::ServiceTracker::updateCallbacks
const std::vector< std::function< void(const std::vector< std::shared_ptr< I >>)> > updateCallbacks
Definition: Trackers.h:537
celix_bundleContext_getBundle
celix_bundle_t * celix_bundleContext_getBundle(const celix_bundle_context_t *ctx)
Returns the bundle for this bundle context.
celix::ServiceTracker::SvcEntry::SvcEntry
SvcEntry(long _svcId, long _svcRanking, std::shared_ptr< I > _svc, std::shared_ptr< const celix::Properties > _properties, std::shared_ptr< const celix::Bundle > _owner)
Definition: Trackers.h:371