PengZheng commented on a change in pull request #399:
URL: https://github.com/apache/celix/pull/399#discussion_r818744855



##########
File path: libs/framework/src/bundle_context.c
##########
@@ -1181,78 +1182,70 @@ static void 
celix_bundleContext_useServiceWithOptions_2_UseServiceTracker(void *
     celix_bundle_context_use_service_data_t* d = data;
     assert(celix_framework_isCurrentThreadTheEventLoop(d->ctx->framework));
 
-    d->called = celix_serviceTracker_useHighestRankingService(d->svcTracker, 
d->opts->filter.serviceName, d->opts->callbackHandle, d->opts->use, 
d->opts->useWithProperties, d->opts->useWithOwner);
-}
-
-static void 
celix_bundleContext_useServiceWithOptions_3_CloseServiceTracker(void *data) {
-    celix_bundle_context_use_service_data_t* d = data;
-    assert(celix_framework_isCurrentThreadTheEventLoop(d->ctx->framework));
-
-    celix_service_tracker_t *tracker = d->svcTracker;
-    d->svcTracker = NULL;
-
-    celix_serviceTracker_destroy(tracker);
+    d->called = celix_serviceTracker_useHighestRankingService(d->svcTracker, 
d->opts->filter.serviceName, 0, d->opts->callbackHandle, d->opts->use, 
d->opts->useWithProperties, d->opts->useWithOwner);
 }
 
 bool celix_bundleContext_useServiceWithOptions(
         celix_bundle_context_t *ctx,
         const celix_service_use_options_t *opts) {
-    if (opts == NULL) {
+    if (opts == NULL || opts->filter.serviceName == NULL) {
         return false;
     }
 
     celix_bundle_context_use_service_data_t data = {0};
     data.ctx = ctx;
     data.opts = opts;
+    bool called = false;
 
     if (celix_framework_isCurrentThreadTheEventLoop(ctx->framework)) {
         // Ignore timeout: blocking the event loop prevents any progress to be 
made
         
celix_bundleContext_useServiceWithOptions_1_CreateServiceTracker(&data);
         celix_bundleContext_useServiceWithOptions_2_UseServiceTracker(&data);
-        celix_bundleContext_useServiceWithOptions_3_CloseServiceTracker(&data);
+        celix_serviceTracker_destroy(data.svcTracker);
         return data.called;
     }
 
     long eventId = celix_framework_fireGenericEvent(ctx->framework, -1, 
celix_bundle_getId(ctx->bundle), "create service tracker for 
celix_bundleContext_useServiceWithOptions", &data, 
celix_bundleContext_useServiceWithOptions_1_CreateServiceTracker, NULL, NULL);
     celix_framework_waitForGenericEvent(ctx->framework, eventId);
 
-    celix_framework_waitForEmptyEventQueue(ctx->framework); //ensure that a 
useService wait if a listener hooks concept, which triggers an async service 
registration
 
-    struct timespec startTime = celix_gettime(CLOCK_MONOTONIC);
-    bool useServiceIsDone = false;
-    bool called = false;
-    do {
-        eventId = celix_framework_fireGenericEvent(ctx->framework, -1, 
celix_bundle_getId(ctx->bundle), "use service tracker for 
celix_bundleContext_useServiceWithOptions", &data, 
celix_bundleContext_useServiceWithOptions_2_UseServiceTracker, NULL, NULL);
-        celix_framework_waitForGenericEvent(ctx->framework, eventId);
+    if(opts->flags & CELIX_SERVICE_USE_DIRECT) {
+        celix_framework_waitUntilNoPendingRegistration(ctx->framework); // 
TL;DR make "service on demand" pattern work. Try comment it out and run 
CelixBundleContextServicesTests.UseServiceOnDemandDirectlyWithAsyncRegisterTest

Review comment:
       Yes, I can see the rational behind ids. That's why I made 
`celix_serviceRegistry_unregisterService` MT-safe even when concurrently called 
with the same serviceId from multiple threads. The second point is almost true 
except that `celix_serviceRegistry_unregisterService` can also be called by 
`celix_bundleContext_cleanup`, which is in turn called by 
`celix_framework_stopBundleOnANonCelixEventThread`.  By the comments in 
`celix_bundleContext_cleanup`, it may be viewed as an assertion failure? 
Indeed, for this almost-one-writer-multiple-reader case, further optimization 
is possible.
   
   For the mentioned scenario, an additional 
`celix_bundleContext_getServiceTrackerFromId` might be enough. However, the 
semantics of `celix_serviceTracker_useServices` is not consistent with that of 
`celix_service_tracking_options_t`, especially the callbacks part.
   
   PS: let me have a try of my commit right ;p




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: dev-unsubscr...@celix.apache.org

For queries about this service, please contact Infrastructure at:
us...@infra.apache.org


Reply via email to