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



##########
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:
       That is an interesting scenario and would IMO  indeed make it possible 
to make better performance use service calls without breaking api or putting 
extra stress on the service registry.
   
   I also agree with making parts of the service tracker more accessible.  
   
   The idea of returning "service tracker ids" instead of pointers to a service 
tracker has to do with ownership and difficulties in C to arrange or share 
ownership. IMO is was too easy to forward service tracker (or service 
registration) pointers without providing control of the service tracker 
lifecycle or checks if the service tracker is still valid. 
   But indeed the downside is that the service tracker api is now hidden and we 
could provide the api  through the bundle context adds additional overhead. 
   
   Another note: The service tracker was designed for multi threading and has 
not yet been updated for the fact that is should only be created, destroyed and 
get services update from a single Celix event thread. I have not look into this 
yet, but this could also mean that service trackers should be able to operate 
without mutexes, but with atomics or even lock-free constructs instead. 




-- 
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