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