This is an automated email from the ASF dual-hosted git repository. pnoltes pushed a commit to branch hotfix/crashing_cxx_meta_tracker in repository https://gitbox.apache.org/repos/asf/celix.git
commit fdfb1dd44173b6962f0452cd3bdb5604a1b8f8d0 Author: Pepijn Noltes <[email protected]> AuthorDate: Wed Feb 2 23:32:31 2022 +0100 Fixes an issue where the C++ meta tracker crashes when combined with the rsa topology manager bundle. --- .../topology_manager/src/activator.c | 2 +- .../gtest/src/CxxBundleContextTestSuite.cc | 23 +++++++++++++++++++++- libs/framework/include/celix/Trackers.h | 6 ++++-- 3 files changed, 27 insertions(+), 4 deletions(-) diff --git a/bundles/remote_services/topology_manager/src/activator.c b/bundles/remote_services/topology_manager/src/activator.c index e074c68..a639dc9 100644 --- a/bundles/remote_services/topology_manager/src/activator.c +++ b/bundles/remote_services/topology_manager/src/activator.c @@ -150,7 +150,7 @@ static celix_status_t bundleActivator_createExportedServicesTracker(struct activ service_tracker_customizer_t *customizer = NULL; status = serviceTrackerCustomizer_create(activator->manager, NULL, topologyManager_addExportedService, NULL, topologyManager_removeExportedService, &customizer); if (status == CELIX_SUCCESS) { - status = serviceTracker_createWithFilter(activator->context, "(service.exported.interfaces=*)", customizer, tracker); + status = serviceTracker_createWithFilter(activator->context, "(&(objectClass=*)(service.exported.interfaces=*))", customizer, tracker); } return status; } diff --git a/libs/framework/gtest/src/CxxBundleContextTestSuite.cc b/libs/framework/gtest/src/CxxBundleContextTestSuite.cc index f02114f..2c05964 100644 --- a/libs/framework/gtest/src/CxxBundleContextTestSuite.cc +++ b/libs/framework/gtest/src/CxxBundleContextTestSuite.cc @@ -21,10 +21,11 @@ #include <atomic> +#include "service_tracker.h" #include "celix/BundleContext.h" - #include "celix_framework_factory.h" #include "celix_framework.h" +#include "service_tracker_customizer.h" class CxxBundleContextTestSuite : public ::testing::Test { public: @@ -719,3 +720,23 @@ TEST_F(CxxBundleContextTestSuite, RegisterServiceWithNameAndVersionInfo) { EXPECT_EQ(reg->getServiceName(), "TestName"); EXPECT_EQ(reg->getServiceVersion(), "1.2.3"); } + +TEST_F(CxxBundleContextTestSuite, TestOldCStyleTrackerWithCxxMetaTracker) { + //rule: A old C style service tracker without an (objectClass=*) filter part, should not crash when combined with a C++ MetaTracker. + + service_tracker_customizer_t *customizer = nullptr; + auto status = serviceTrackerCustomizer_create(this, nullptr, nullptr, nullptr, nullptr, &customizer); + ASSERT_EQ(status, CELIX_SUCCESS); + celix_service_tracker_t* tracker = nullptr; + status = serviceTracker_createWithFilter(ctx->getCBundleContext(), "(service.exported.interfaces=*)", customizer, &tracker); + ASSERT_EQ(status, CELIX_SUCCESS); + status = serviceTracker_open(tracker); + ASSERT_EQ(status, CELIX_SUCCESS); + + auto metaTracker = ctx->trackAnyServiceTrackers().build(); + ctx->waitForEvents(); + EXPECT_EQ(metaTracker->getState(), celix::TrackerState::OPEN); + + serviceTracker_close(tracker); + serviceTracker_destroy(tracker); +} diff --git a/libs/framework/include/celix/Trackers.h b/libs/framework/include/celix/Trackers.h index 7d42c13..64011fc 100644 --- a/libs/framework/include/celix/Trackers.h +++ b/libs/framework/include/celix/Trackers.h @@ -726,14 +726,16 @@ namespace celix { static_cast<void*>(this), [](void *handle, const celix_service_tracker_info_t *cInfo) { auto *trk = static_cast<MetaTracker *>(handle); - ServiceTrackerInfo info{cInfo->serviceName, celix::Filter::wrap(cInfo->filter), cInfo->bundleId}; + std::string svcName = cInfo->serviceName == nullptr ? "" : cInfo->serviceName; + ServiceTrackerInfo info{svcName, celix::Filter::wrap(cInfo->filter), cInfo->bundleId}; for (const auto& cb : trk->onTrackerCreated) { cb(info); } }, [](void *handle, const celix_service_tracker_info_t *cInfo) { auto *trk = static_cast<MetaTracker *>(handle); - ServiceTrackerInfo info{cInfo->serviceName, celix::Filter::wrap(cInfo->filter), cInfo->bundleId}; + std::string svcName = cInfo->serviceName == nullptr ? "" : cInfo->serviceName; + ServiceTrackerInfo info{svcName, celix::Filter::wrap(cInfo->filter), cInfo->bundleId}; for (const auto& cb : trk->onTrackerDestroyed) { cb(info); }
