This is an automated email from the ASF dual-hosted git repository. pnoltes pushed a commit to branch hotfix/bundle_activator_issue in repository https://gitbox.apache.org/repos/asf/celix.git
commit f49b4c6fb798030e6d23cda5193ee1c959519649 Author: Pepijn Noltes <[email protected]> AuthorDate: Wed Apr 14 16:55:47 2021 +0200 Fixes an issue in the bundle activator where components where destroyed to soon. --- libs/framework/gtest/CMakeLists.txt | 20 ++++---- libs/framework/gtest/src/CmpTestBundleActivator.cc | 45 ++++++++++++++++++ .../gtest/src/CxxBundleActivatorTestSuite.cc | 55 ++++++++++++++++++++++ libs/framework/include/celix/BundleActivator.h | 1 + 4 files changed, 113 insertions(+), 8 deletions(-) diff --git a/libs/framework/gtest/CMakeLists.txt b/libs/framework/gtest/CMakeLists.txt index e1045b7..d898d72 100644 --- a/libs/framework/gtest/CMakeLists.txt +++ b/libs/framework/gtest/CMakeLists.txt @@ -20,6 +20,7 @@ add_celix_bundle(simple_test_bundle2 NO_ACTIVATOR VERSION 1.0.0) add_celix_bundle(simple_test_bundle3 NO_ACTIVATOR VERSION 1.0.0) add_celix_bundle(bundle_with_exception SOURCES src/nop_activator.c VERSION 1.0.0) add_celix_bundle(simple_cxx_bundle SOURCES src/HelloWorldCxxActivator.cc VERSION 1.0.0) +add_celix_bundle(cmp_test_bundle SOURCES src/CmpTestBundleActivator.cc) add_subdirectory(subdir) #simple_test_bundle4, simple_test_bundle5 and sublib add_celix_bundle(unresolveable_bundle SOURCES src/nop_activator.c VERSION 1.0.0) @@ -43,6 +44,7 @@ add_executable(test_framework src/HelloWorldCxxActivator.cc src/CxxFilterTestSuite.cc src/CxxFrameworkFactoryTestSuite.cc + src/CxxBundleActivatorTestSuite.cc ) target_link_libraries(test_framework Celix::framework CURL::libcurl GTest::gtest GTest::gtest_main) @@ -50,15 +52,17 @@ add_dependencies(test_framework simple_test_bundle1_bundle simple_test_bundle2_b target_include_directories(test_framework PRIVATE ../src) celix_get_bundle_file(simple_cxx_bundle SIMPLE_CXX_BUNDLE_LOC) +celix_get_bundle_file(cmp_test_bundle CMP_TEST_BUNDLE_LOC) target_compile_definitions(test_framework PRIVATE - -DSIMPLE_TEST_BUNDLE1_LOCATION="$<TARGET_PROPERTY:simple_test_bundle1,BUNDLE_FILE>" - -DSIMPLE_TEST_BUNDLE2_LOCATION="$<TARGET_PROPERTY:simple_test_bundle2,BUNDLE_FILE>" - -DSIMPLE_TEST_BUNDLE3_LOCATION="$<TARGET_PROPERTY:simple_test_bundle3,BUNDLE_FILE>" - -DSIMPLE_TEST_BUNDLE4_LOCATION="$<TARGET_PROPERTY:simple_test_bundle4,BUNDLE_FILENAME>" - -DSIMPLE_TEST_BUNDLE5_LOCATION="$<TARGET_PROPERTY:simple_test_bundle5,BUNDLE_FILENAME>" - -DTEST_BUNDLE_WITH_EXCEPTION_LOCATION="$<TARGET_PROPERTY:bundle_with_exception,BUNDLE_FILE>" - -DTEST_BUNDLE_UNRESOLVEABLE_LOCATION="$<TARGET_PROPERTY:unresolveable_bundle,BUNDLE_FILE>" - -DSIMPLE_CXX_BUNDLE_LOC="${SIMPLE_CXX_BUNDLE_LOC}" + SIMPLE_TEST_BUNDLE1_LOCATION="$<TARGET_PROPERTY:simple_test_bundle1,BUNDLE_FILE>" + SIMPLE_TEST_BUNDLE2_LOCATION="$<TARGET_PROPERTY:simple_test_bundle2,BUNDLE_FILE>" + SIMPLE_TEST_BUNDLE3_LOCATION="$<TARGET_PROPERTY:simple_test_bundle3,BUNDLE_FILE>" + SIMPLE_TEST_BUNDLE4_LOCATION="$<TARGET_PROPERTY:simple_test_bundle4,BUNDLE_FILENAME>" + SIMPLE_TEST_BUNDLE5_LOCATION="$<TARGET_PROPERTY:simple_test_bundle5,BUNDLE_FILENAME>" + TEST_BUNDLE_WITH_EXCEPTION_LOCATION="$<TARGET_PROPERTY:bundle_with_exception,BUNDLE_FILE>" + TEST_BUNDLE_UNRESOLVEABLE_LOCATION="$<TARGET_PROPERTY:unresolveable_bundle,BUNDLE_FILE>" + SIMPLE_CXX_BUNDLE_LOC="${SIMPLE_CXX_BUNDLE_LOC}" + CMP_TEST_BUNDLE_LOC="${CMP_TEST_BUNDLE_LOC}" ) configure_file(config.properties.in config.properties @ONLY) diff --git a/libs/framework/gtest/src/CmpTestBundleActivator.cc b/libs/framework/gtest/src/CmpTestBundleActivator.cc new file mode 100644 index 0000000..6e037e4 --- /dev/null +++ b/libs/framework/gtest/src/CmpTestBundleActivator.cc @@ -0,0 +1,45 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#include "celix/BundleActivator.h" + +class TestCmp { +public: + void setAnyService(const std::shared_ptr<void>& svc) { + std::lock_guard<std::mutex> lock{mutex}; + anyService = svc; + } +private: + std::mutex mutex{}; + std::shared_ptr<void> anyService{}; +}; + +class CmpTestBundleActivator { +public: + explicit CmpTestBundleActivator(const std::shared_ptr<celix::BundleContext>& ctx) { + auto& cmp = ctx->getDependencyManager()->createComponent<TestCmp>(); + tracker = ctx->trackAnyServices() + .addSetCallback(std::bind(&TestCmp::setAnyService, &cmp.getInstance(), std::placeholders::_1)) + .build(); + } +private: + std::shared_ptr<celix::ServiceTracker<void>> tracker{}; +}; + +CELIX_GEN_CXX_BUNDLE_ACTIVATOR(CmpTestBundleActivator) \ No newline at end of file diff --git a/libs/framework/gtest/src/CxxBundleActivatorTestSuite.cc b/libs/framework/gtest/src/CxxBundleActivatorTestSuite.cc new file mode 100644 index 0000000..c38049d --- /dev/null +++ b/libs/framework/gtest/src/CxxBundleActivatorTestSuite.cc @@ -0,0 +1,55 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#include <gtest/gtest.h> + +#include "celix/FrameworkFactory.h" + +class CxxBundleActivatorTestSuite : public ::testing::Test { +public: + CxxBundleActivatorTestSuite() { + fw = celix::createFramework(); + ctx = fw->getFrameworkBundleContext(); + } + + std::shared_ptr<celix::Framework> fw{}; + std::shared_ptr<celix::BundleContext> ctx{}; +}; + +class TestInterface { +public: + virtual ~TestInterface() noexcept = default; +}; + +class TestImpl : public TestInterface { +public: + ~TestImpl() noexcept override = default; +}; + +TEST_F(CxxBundleActivatorTestSuite, InstallUninstallBundleWithCmpAndTracker) { + //When I install and uninstall a bundle with a component and tracker combination without asan issues (use after free) + + auto reg = ctx->registerService<TestInterface>(std::make_shared<TestImpl>()).build(); + + auto bndId = ctx->installBundle(CMP_TEST_BUNDLE_LOC); + EXPECT_GE(bndId, 0); + ctx->uninstallBundle(bndId); + +} + diff --git a/libs/framework/include/celix/BundleActivator.h b/libs/framework/include/celix/BundleActivator.h index 687475b..22b8881 100644 --- a/libs/framework/include/celix/BundleActivator.h +++ b/libs/framework/include/celix/BundleActivator.h @@ -84,6 +84,7 @@ namespace celix { std::weak_ptr<celix::BundleContext> ctx = data->ctx; std::weak_ptr<celix::dm::DependencyManager> dm = data->ctx->getDependencyManager(); auto bndId = data->bndId; + data->bundleActivator.reset(); data->ctx->getDependencyManager()->clear(); delete data; waitForExpired(bndId, ctx, "celix::BundleContext", ctx);
