This is an automated email from the ASF dual-hosted git repository. pnoltes pushed a commit to branch hotfix/use_new_tracker_in_rsa_dfi in repository https://gitbox.apache.org/repos/asf/celix.git
commit c35735ea290b96a9f8324e96164f4aed3eb8ee88 Author: Pepijn Noltes <[email protected]> AuthorDate: Mon Sep 7 21:14:21 2020 +0200 Refactors the rsa dfi export registration to use the tracker from the bundle context (which should be thread safe) --- .../src/export_registration_dfi.c | 68 +++++++++++++++------- 1 file changed, 47 insertions(+), 21 deletions(-) diff --git a/bundles/remote_services/remote_service_admin_dfi/src/export_registration_dfi.c b/bundles/remote_services/remote_service_admin_dfi/src/export_registration_dfi.c index edc1078..39b43b3 100644 --- a/bundles/remote_services/remote_service_admin_dfi/src/export_registration_dfi.c +++ b/bundles/remote_services/remote_service_admin_dfi/src/export_registration_dfi.c @@ -36,14 +36,16 @@ struct export_reference { }; struct export_registration { + celix_log_helper_t* helper; celix_bundle_context_t * context; struct export_reference exportReference; char *servId; dyn_interface_type *intf; //owner - service_tracker_t *tracker; + celix_thread_mutex_t mutex; void *service; //protected by mutex + long trackerId; //protected by mutex //TODO add tracker and lock bool closed; @@ -54,8 +56,8 @@ struct export_registration { }; static celix_status_t exportRegistration_findAndParseInterfaceDescriptor(celix_log_helper_t *helper, celix_bundle_context_t * const context, celix_bundle_t * const bundle, char const * const name, dyn_interface_type **out); -static void exportRegistration_addServ(export_registration_t *reg, service_reference_pt ref, void *service); -static void exportRegistration_removeServ(export_registration_t *reg, service_reference_pt ref, void *service); +static void exportRegistration_addServ(void *data, void *service); +static void exportRegistration_removeServ(void *data, void *service); celix_status_t exportRegistration_create(celix_log_helper_t *helper, service_reference_pt reference, endpoint_description_t *endpoint, celix_bundle_context_t *context, FILE *logFile, export_registration_t **out) { celix_status_t status = CELIX_SUCCESS; @@ -76,12 +78,14 @@ celix_status_t exportRegistration_create(celix_log_helper_t *helper, service_ref if (status == CELIX_SUCCESS) { + reg->helper = helper; reg->context = context; reg->exportReference.endpoint = endpoint; reg->exportReference.reference = reference; reg->closed = false; reg->logFile = logFile; reg->servId = strndup(servId, 1024); + reg->trackerId = -1L; remoteInterceptorsHandler_create(context, ®->interceptorsHandler); @@ -114,17 +118,6 @@ celix_status_t exportRegistration_create(celix_log_helper_t *helper, service_ref } if (status == CELIX_SUCCESS) { - service_tracker_customizer_t *cust = NULL; - status = serviceTrackerCustomizer_create(reg, NULL, (void *) exportRegistration_addServ, NULL, - (void *) exportRegistration_removeServ, &cust); - if (status == CELIX_SUCCESS) { - char filter[32]; - snprintf(filter, 32, "(service.id=%s)", servId); - status = serviceTracker_createWithFilter(reg->context, filter, cust, ®->tracker); - } - } - - if (status == CELIX_SUCCESS) { *out = reg; } else { celix_logHelper_log(helper, CELIX_LOG_LEVEL_ERROR, "Error creating export registration"); @@ -146,7 +139,12 @@ celix_status_t exportRegistration_call(export_registration_t *export, char *data bool cont = remoteInterceptorHandler_invokePreExportCall(export->interceptorsHandler, export->exportReference.endpoint->properties, sig, &metadata); if (cont) { celixThreadMutex_lock(&export->mutex); - status = jsonRpc_call(export->intf, export->service, data, responseOut); + if (export->service != NULL) { + status = jsonRpc_call(export->intf, export->service, data, responseOut); + } else { + status = CELIX_ILLEGAL_STATE; + celix_logHelper_error(export->helper, "export service pointer is NULL"); + } celixThreadMutex_unlock(&export->mutex); remoteInterceptorHandler_invokePostExportCall(export->interceptorsHandler, export->exportReference.endpoint->properties, sig, metadata); @@ -212,8 +210,8 @@ void exportRegistration_destroy(export_registration_t *reg) { reg->exportReference.endpoint = NULL; endpointDescription_destroy(ep); } - if (reg->tracker != NULL) { - serviceTracker_destroy(reg->tracker); + if (reg->trackerId >= 0) { + celix_bundleContext_stopTracker(reg->context, reg->trackerId); } if (reg->servId != NULL) { free(reg->servId); @@ -230,7 +228,27 @@ void exportRegistration_destroy(export_registration_t *reg) { celix_status_t exportRegistration_start(export_registration_t *reg) { celix_status_t status = CELIX_SUCCESS; - serviceTracker_open(reg->tracker); + char filter[32]; + snprintf(filter, 32, "(service.id=%s)", reg->servId); + celix_service_tracking_options_t opts = CELIX_EMPTY_SERVICE_TRACKING_OPTIONS; + opts.filter.filter = filter; + opts.filter.serviceName = "*"; + opts.filter.ignoreServiceLanguage = true; + opts.callbackHandle = reg; + opts.add = exportRegistration_addServ; + opts.remove = exportRegistration_removeServ; + long newTrkId = celix_bundleContext_trackServicesWithOptions(reg->context, &opts); + + celixThreadMutex_lock(®->mutex); + long prevTrkId = reg->trackerId; + reg->trackerId = newTrkId; + celixThreadMutex_unlock(®->mutex); + + if (prevTrkId >= 0) { + celix_logHelper_error(reg->helper, "Error staring export registration. The export registration already has an active service tracker"); + celix_bundleContext_stopTracker(reg->context, prevTrkId); + } + return status; } @@ -239,18 +257,26 @@ celix_status_t exportRegistration_stop(export_registration_t *reg) { celix_status_t status = CELIX_SUCCESS; if (status == CELIX_SUCCESS) { status = bundleContext_ungetServiceReference(reg->context, reg->exportReference.reference); - serviceTracker_close(reg->tracker); + + celixThreadMutex_lock(®->mutex); + long trkId = reg->trackerId; + reg->trackerId = -1L; + celixThreadMutex_unlock(®->mutex); + celix_bundleContext_stopTracker(reg->context, trkId); + } return status; } -static void exportRegistration_addServ(export_registration_t *reg, service_reference_pt ref, void *service) { +static void exportRegistration_addServ(void *data, void *service) { + export_registration_t *reg = data; celixThreadMutex_lock(®->mutex); reg->service = service; celixThreadMutex_unlock(®->mutex); } -static void exportRegistration_removeServ(export_registration_t *reg, service_reference_pt ref, void *service) { +static void exportRegistration_removeServ(void *data, void *service) { + export_registration_t *reg = data; celixThreadMutex_lock(®->mutex); if (reg->service == service) { reg->service = NULL;
