(celix) branch feature/87-create-service-tracker-inside-useTrackedService-call updated (e665364e -> 3c3227af)

2024-03-03 Thread pengzheng
This is an automated email from the ASF dual-hosted git repository.

pengzheng pushed a change to branch 
feature/87-create-service-tracker-inside-useTrackedService-call
in repository https://gitbox.apache.org/repos/asf/celix.git


from e665364e gh-87: Support creating service tracker inside a 
useTrackedService call
 add 3c3227af gh-87: Address review issues in gh-734.

No new revisions were added by this update.

Summary of changes:
 libs/framework/src/bundle_context.c | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)



(celix) 02/02: gh-87: Support creating service tracker inside a useTrackedService call

2024-03-03 Thread pnoltes
This is an automated email from the ASF dual-hosted git repository.

pnoltes pushed a commit to branch 
feature/87-create-service-tracker-inside-useTrackedService-call
in repository https://gitbox.apache.org/repos/asf/celix.git

commit e665364e8dfa02db26b130d1f17bd87acc63e2dc
Author: Pepijn Noltes 
AuthorDate: Sun Mar 3 11:24:47 2024 +0100

gh-87: Support creating service tracker inside a useTrackedService call
---
 .../src/CelixBundleContextServicesTestSuite.cc |  23 +
 libs/framework/src/bundle_context.c| 111 ++---
 libs/framework/src/bundle_context_private.h|   3 +
 3 files changed, 99 insertions(+), 38 deletions(-)

diff --git a/libs/framework/gtest/src/CelixBundleContextServicesTestSuite.cc 
b/libs/framework/gtest/src/CelixBundleContextServicesTestSuite.cc
index 607cb208..12ffcd94 100644
--- a/libs/framework/gtest/src/CelixBundleContextServicesTestSuite.cc
+++ b/libs/framework/gtest/src/CelixBundleContextServicesTestSuite.cc
@@ -2045,3 +2045,26 @@ TEST_F(CelixBundleContextServicesTestSuite, 
UseTrackedServiceOnTheCelixEventThre
 nullptr);
 celix_framework_waitForGenericEvent(fw, eventId);
 }
+
+TEST_F(CelixBundleContextServicesTestSuite, 
CreateServiceTrackedOnUseServiceTrackerCall) {
+//Given a registered service with a service registration guard
+long svcId = celix_bundleContext_registerService(ctx, (void*)0x42, "test", 
nullptr);
+celix_auto(celix_service_registration_guard_t) svcGuard = 
celix_serviceRegistrationGuard_init(ctx, svcId);
+
+//And a  service tracker for the "test" service with a service tracker 
guard
+long trkId = celix_bundleContext_trackServices(ctx, "test");
+celix_auto(celix_tracker_guard_t) trkGuard = celix_trackerGuard_init(ctx, 
trkId);
+
+//When all events are processed
+celix_bundleContext_waitForEvents(ctx);
+
+//Then I can create and destroy an additional service tracker on the 
callback of the useTrackedService function
+auto useCallback = [](void *data, void* /*svc*/) {
+auto c = static_cast(data);
+long additionalTrkId = celix_bundleContext_trackServices(c, "foo");
+EXPECT_GT(additionalTrkId, 0);
+celix_bundleContext_stopTracker(c, additionalTrkId);
+};
+bool called = celix_bundleContext_useTrackedService(ctx, trkId, ctx, 
useCallback);
+EXPECT_TRUE(called);
+}
diff --git a/libs/framework/src/bundle_context.c 
b/libs/framework/src/bundle_context.c
index ee890648..99624cae 100644
--- a/libs/framework/src/bundle_context.c
+++ b/libs/framework/src/bundle_context.c
@@ -43,6 +43,8 @@
 #include "celix_array_list.h"
 #include "celix_convert_utils.h"
 
+#define TRACKER_WARN_THRESHOLD_SEC 5
+
 static celix_status_t bundleContext_bundleChanged(void* listenerSvc, 
bundle_event_t* event);
 static void bundleContext_cleanupBundleTrackers(bundle_context_t *ct);
 static void bundleContext_cleanupServiceTrackers(bundle_context_t *ctx);
@@ -839,7 +841,28 @@ static void 
celix_bundleContext_removeServiceTrackerTracker(void *data) {
 free(tracker);
 }
 
-static void celix_bundleContext_stopTrackerInternal(bundle_context_t *ctx, 
long trackerId, bool async, void *doneData, void (*doneCallback)(void* 
doneData)) {
+static void 
celix_bundleContext_waitForUnusedServiceTracker(celix_bundle_context_t* ctx,
+
celix_bundle_context_service_tracker_entry_t* trkEntry) {
+// busy wait till the tracker is not used anymore
+// note that the use count cannot be increased anymore, because the 
tracker is removed from the map
+struct timespec start = celix_gettime(CLOCK_MONOTONIC);
+int logCount = 0;
+while (__atomic_load_n(>useCount, __ATOMIC_RELAXED) > 0) {
+if (celix_elapsedtime(CLOCK_MONOTONIC, start) > 
TRACKER_WARN_THRESHOLD_SEC) {
+fw_log(ctx->framework->logger,
+   CELIX_LOG_LEVEL_WARNING,
+   "Service tracker with trk id %li is still in use after %i 
seconds. "
+   "This might indicate a programming error.",
+   trkEntry->trackerId,
+   logCount * TRACKER_WARN_THRESHOLD_SEC);
+start = celix_gettime(CLOCK_MONOTONIC);
+logCount++;
+}
+usleep(1);
+}
+}
+
+static void celix_bundleContext_stopTrackerInternal(celix_bundle_context_t* 
ctx, long trackerId, bool async, void *doneData, void (*doneCallback)(void* 
doneData)) {
 if (ctx == NULL || trackerId <= 0) {
 return;
 }
@@ -888,6 +911,7 @@ static void 
celix_bundleContext_stopTrackerInternal(bundle_context_t *ctx, long
 fw_removeBundleListener(ctx->framework, ctx->bundle, 
>listener);
 free(bundleTracker);
 } else if (serviceTracker != NULL) {
+celix_bundleContext_waitForUnusedServiceTracker(ctx, 
serviceTracker);
 celix_serviceTracker_destroy(serviceTracker->tracker);
 if 

(celix) branch feature/87-create-service-tracker-inside-useTrackedService-call created (now e665364e)

2024-03-03 Thread pnoltes
This is an automated email from the ASF dual-hosted git repository.

pnoltes pushed a change to branch 
feature/87-create-service-tracker-inside-useTrackedService-call
in repository https://gitbox.apache.org/repos/asf/celix.git


  at e665364e gh-87: Support creating service tracker inside a 
useTrackedService call

This branch includes the following new commits:

 new dbadfebc gh-87: Add test to call useTrackedService on the event thread.
 new e665364e gh-87: Support creating service tracker inside a 
useTrackedService call

The 2 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.




(celix) 01/02: gh-87: Add test to call useTrackedService on the event thread.

2024-03-03 Thread pnoltes
This is an automated email from the ASF dual-hosted git repository.

pnoltes pushed a commit to branch 
feature/87-create-service-tracker-inside-useTrackedService-call
in repository https://gitbox.apache.org/repos/asf/celix.git

commit dbadfebcc4401b7f51a02c2f504d23863ca114e9
Author: Pepijn Noltes 
AuthorDate: Sat Mar 2 13:28:09 2024 +0100

gh-87: Add test to call useTrackedService on the event thread.
---
 .../src/CelixBundleContextServicesTestSuite.cc | 36 ++
 1 file changed, 36 insertions(+)

diff --git a/libs/framework/gtest/src/CelixBundleContextServicesTestSuite.cc 
b/libs/framework/gtest/src/CelixBundleContextServicesTestSuite.cc
index 8218ecf0..607cb208 100644
--- a/libs/framework/gtest/src/CelixBundleContextServicesTestSuite.cc
+++ b/libs/framework/gtest/src/CelixBundleContextServicesTestSuite.cc
@@ -2009,3 +2009,39 @@ TEST_F(CelixBundleContextServicesTestSuite, 
UseTrackedServiceDuringTrackerCreati
 serviceFound = celix_bundleContext_useTrackedService(ctx, trkId, nullptr, 
nullptr);
 EXPECT_TRUE(serviceFound);
 }
+
+TEST_F(CelixBundleContextServicesTestSuite, 
UseTrackedServiceOnTheCelixEventThread) {
+//Given a registered service with a service registration guard
+long svcId = celix_bundleContext_registerService(ctx, (void*)0x42, "test", 
nullptr);
+celix_auto(celix_service_registration_guard_t) svcGuard = 
celix_serviceRegistrationGuard_init(ctx, svcId);
+
+//And a  service tracker for the "test" service with a service tracker 
guard
+long trkId = celix_bundleContext_trackServices(ctx, "test");
+celix_auto(celix_tracker_guard_t) trkGuard = celix_trackerGuard_init(ctx, 
trkId);
+
+//When all events are processed
+celix_bundleContext_waitForEvents(ctx);
+
+//Then I can use the tracked service on the Celix event thread
+struct callback_data {
+celix_bundle_context_t* ctx;
+long trkId;
+};
+callback_data cbData{ctx, trkId};
+auto eventCallback = [](void *data) {
+auto d = static_cast(data);
+bool called = celix_bundleContext_useTrackedService(d->ctx, d->trkId, 
nullptr, nullptr);
+EXPECT_TRUE(called);
+};
+
+long eventId = celix_framework_fireGenericEvent(
+fw,
+-1,
+celix_bundle_getId(celix_framework_getFrameworkBundle(fw)),
+"use tracked service",
+(void*),
+eventCallback,
+nullptr,
+nullptr);
+celix_framework_waitForGenericEvent(fw, eventId);
+}