You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@celix.apache.org by GitBox <gi...@apache.org> on 2020/12/18 16:20:15 UTC

[GitHub] [celix] Oipo commented on a change in pull request #286: Feature/async svc registration

Oipo commented on a change in pull request #286:
URL: https://github.com/apache/celix/pull/286#discussion_r545940469



##########
File path: libs/framework/src/bundle_context.c
##########
@@ -836,20 +1316,111 @@ long celix_bundleContext_trackServices(
     opts.callbackHandle = callbackHandle;
     opts.add = add;
     opts.remove = remove;
-    return celix_bundleContext_trackServicesWithOptions(ctx, &opts);
+    return celix_bundleContext_trackServicesWithOptionsInternal(ctx, &opts, false);
 }
 
+long celix_bundleContext_trackServicesAsync(
+        celix_bundle_context_t* ctx,
+        const char* serviceName,
+        void* callbackHandle,
+        void (*add)(void* handle, void* svc),
+        void (*remove)(void* handle, void* svc)) {
+    celix_service_tracking_options_t opts = CELIX_EMPTY_SERVICE_TRACKING_OPTIONS;
+    opts.filter.serviceName = serviceName;
+    opts.callbackHandle = callbackHandle;
+    opts.add = add;
+    opts.remove = remove;
+    return celix_bundleContext_trackServicesWithOptionsInternal(ctx, &opts, true);
+}
 
-long celix_bundleContext_trackServicesWithOptions(bundle_context_t *ctx, const celix_service_tracking_options_t *opts) {
-    long trackerId = -1;
-    celix_service_tracker_t *tracker = celix_serviceTracker_createWithOptions(ctx, opts);
+
+static void celix_bundleContext_createTrackerOnEventLoop(void *data) {
+    celix_bundle_context_service_tracker_entry_t* entry = data;
+    assert(celix_framework_isCurrentThreadTheEventLoop(entry->ctx->framework));
+    celix_service_tracker_t *tracker = celix_serviceTracker_createWithOptions(entry->ctx, &entry->opts);
     if (tracker != NULL) {
+        celixThreadMutex_lock(&entry->ctx->mutex);
+        entry->tracker = tracker;
+        celixThreadMutex_unlock(&entry->ctx->mutex);
+    } else {
+        fw_log(entry->ctx->framework->logger, CELIX_LOG_LEVEL_ERROR, "Cannot create tracker for bnd %s (%li)", celix_bundle_getSymbolicName(entry->ctx->bundle), celix_bundle_getId(entry->ctx->bundle));
+    }
+}
+
+static void celix_bundleContext_doneCreatingTrackerOnEventLoop(void *data) {
+    celix_bundle_context_service_tracker_entry_t* entry = data;
+    if (entry->trackerCreatedCallback != NULL) {
+        entry->trackerCreatedCallback(entry->trackerCreatedCallbackData);
+    }
+}
+
+
+
+static long celix_bundleContext_trackServicesWithOptionsInternal(celix_bundle_context_t *ctx, const celix_service_tracking_options_t *opts, bool async) {
+    if (ctx == NULL) {
+        return -1L;
+    } else if (opts == NULL) {
+        fw_log(ctx->framework->logger, CELIX_LOG_LEVEL_ERROR, "Cannot track services with a NULL service tracking options argument");
+        return -1L;
+    }
+
+    if (opts->filter.serviceName == NULL) {
+        fw_log(ctx->framework->logger, CELIX_LOG_LEVEL_DEBUG, "Starting a tracker for any services");
+    }
+
+    if (!async && celix_framework_isCurrentThreadTheEventLoop(ctx->framework)) {
+        //already in event loop thread. To keep the old behavior just create the tracker traditionally (chained in the current thread).
+        celix_service_tracker_t *tracker = celix_serviceTracker_createWithOptions(ctx, opts);
+        long trackerId = -1L;
+        if (tracker != NULL) {
+            celix_bundle_context_service_tracker_entry_t* entry = calloc(1, sizeof(*entry));
+            entry->ctx = ctx;
+            entry->tracker = tracker;
+            entry->opts = *opts;
+            entry->createEventId = -1;
+            celixThreadMutex_lock(&ctx->mutex);
+            entry->trackerId = ctx->nextTrackerId++;
+            trackerId = entry->trackerId;
+            hashMap_put(ctx->serviceTrackers, (void *) trackerId, entry);
+            celixThreadMutex_unlock(&ctx->mutex);
+        }
+        return trackerId;
+    } else {
+        if (!async) {

Review comment:
       :do_not_litter: 




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

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