27 #if __cplusplus >= 201703L //C++17 or higher
32 struct BundleActivatorData {
34 std::shared_ptr<celix::BundleContext> ctx;
39 typename std::enable_if<std::is_constructible<I, std::shared_ptr<celix::BundleContext>>::value, celix_status_t>::type
41 auto ctx = std::make_shared<celix::BundleContext>(cCtx);
42 auto act = std::make_unique<I>(ctx);
43 auto *data =
new BundleActivatorData<I>{ctx->getBundleId(), std::move(ctx), std::move(act)};
49 typename std::enable_if<std::is_constructible<I, std::shared_ptr<celix::dm::DependencyManager>>::value, celix_status_t>::type
51 auto ctx = std::make_shared<celix::BundleContext>(cCtx);
52 auto dm = ctx->getDependencyManager();
53 auto act = std::make_unique<I>(dm);
55 auto *data =
new BundleActivatorData<I>{ctx->getBundleId(), std::move(ctx), std::move(act)};
61 void waitForExpired(
long bndId, std::weak_ptr<celix::BundleContext> &weakCtx,
const char *name,
62 std::weak_ptr<T> &observe) {
63 auto start = std::chrono::system_clock::now();
64 while (!observe.expired()) {
65 auto now = std::chrono::system_clock::now();
66 auto durationInSec = std::chrono::duration_cast<std::chrono::seconds>(now - start);
67 if (durationInSec > std::chrono::seconds{5}) {
68 auto msg = std::string{
"Cannot destroy bundle "} + std::to_string(bndId) +
". " + name +
69 " is still in use. std::shared_ptr use count is " + std::to_string(observe.use_count()) +
71 auto ctx = weakCtx.lock();
73 ctx->logWarn(msg.c_str());
79 std::this_thread::sleep_for(std::chrono::milliseconds{50});
85 auto *data =
static_cast<BundleActivatorData<I> *
>(userData);
86 data->bundleActivator.reset();
87 data->ctx->getDependencyManager()->clear();
89 auto bndId = data->bndId;
90 std::weak_ptr<celix::BundleContext> ctx = data->ctx;
91 std::weak_ptr<celix::dm::DependencyManager> dm = data->ctx->getDependencyManager();
93 waitForExpired(bndId, ctx,
"celix::BundleContext", ctx);
94 waitForExpired(bndId, ctx,
"celix::dm::DependencyManager", dm);
103 std::shared_ptr<celix::dm::DependencyManager>
dm;
108 typename std::enable_if<std::is_constructible<I, std::shared_ptr<celix::dm::DependencyManager>>::value, celix_status_t>::type
110 auto dm = std::make_shared<celix::dm::DependencyManager>(cCtx);
111 auto act = std::unique_ptr<I>(
new I{dm});
114 *out = (
void *) data;
115 return CELIX_SUCCESS;
124 return CELIX_SUCCESS;
149 #define CELIX_GEN_CXX_BUNDLE_ACTIVATOR(actType) \
150 extern "C" celix_status_t bundleActivator_create(celix_bundle_context_t *context, void** userData) { \
151 return celix::impl::createActivator<actType>(context, userData); \
154 extern "C" celix_status_t bundleActivator_start(void *, celix_bundle_context_t *) { \
156 return CELIX_SUCCESS; \
159 extern "C" celix_status_t bundleActivator_stop(void *userData, celix_bundle_context_t*) { \
160 return celix::impl::destroyActivator<actType>(userData); \
163 extern "C" celix_status_t bundleActivator_destroy(void *, celix_bundle_context_t*) { \
165 return CELIX_SUCCESS; \