Repository: celix Updated Branches: refs/heads/feature/CELIX-272_synchronization_service_registry df56860df -> 07d0dfe65
CELIX-272: Fix some bc_ungetServiceRefernce issues. Project: http://git-wip-us.apache.org/repos/asf/celix/repo Commit: http://git-wip-us.apache.org/repos/asf/celix/commit/07d0dfe6 Tree: http://git-wip-us.apache.org/repos/asf/celix/tree/07d0dfe6 Diff: http://git-wip-us.apache.org/repos/asf/celix/diff/07d0dfe6 Branch: refs/heads/feature/CELIX-272_synchronization_service_registry Commit: 07d0dfe65fcba3df5355d0a64c8c1a2fc1228ca7 Parents: df56860 Author: Pepijn Noltes <[email protected]> Authored: Wed Nov 11 17:17:18 2015 +0100 Committer: Pepijn Noltes <[email protected]> Committed: Wed Nov 11 17:17:18 2015 +0100 ---------------------------------------------------------------------- .../private/src/dm_shell_list_command.c | 2 +- .../private/include/service_reference_private.h | 10 ++- .../include/service_registration_private.h | 4 +- framework/private/src/service_reference.c | 53 ++++++++++- framework/private/src/service_registration.c | 94 ++++++++++++-------- framework/private/src/service_registry.c | 29 ++++-- .../private/src/calculator_endpoint_activator.c | 2 +- .../private/src/calculator_activator.c | 12 +-- .../rsa/private/src/export_registration_dfi.c | 3 + .../rsa/private/src/remote_service_admin_dfi.c | 10 ++- .../rsa_tst/rsa_tests.cpp | 6 ++ 11 files changed, 162 insertions(+), 63 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/celix/blob/07d0dfe6/dependency_manager/private/src/dm_shell_list_command.c ---------------------------------------------------------------------- diff --git a/dependency_manager/private/src/dm_shell_list_command.c b/dependency_manager/private/src/dm_shell_list_command.c index fd7c5d9..ed2c5f0 100644 --- a/dependency_manager/private/src/dm_shell_list_command.c +++ b/dependency_manager/private/src/dm_shell_list_command.c @@ -43,7 +43,7 @@ void dmListCommand_execute(bundle_context_pt context, char * line, FILE *out, FI array_list_pt servRefs = NULL; int i; bundleContext_getServiceReferences(context, DM_INFO_SERVICE_NAME ,NULL, &servRefs); - char *term = getenv("TERM"); + char *term = secure_getenv("TERM"); bool colors = false; if (strcmp("xterm-256color", term) == 0) { colors = true; http://git-wip-us.apache.org/repos/asf/celix/blob/07d0dfe6/framework/private/include/service_reference_private.h ---------------------------------------------------------------------- diff --git a/framework/private/include/service_reference_private.h b/framework/private/include/service_reference_private.h index 2ac4ee5..7eea45e 100644 --- a/framework/private/include/service_reference_private.h +++ b/framework/private/include/service_reference_private.h @@ -34,6 +34,7 @@ struct serviceReference { bundle_pt referenceOwner; struct serviceRegistration * registration; bundle_pt registrationBundle; + void *service; size_t refCount; size_t usageCount; @@ -46,8 +47,8 @@ celix_status_t serviceReference_create(bundle_pt referenceOwner, service_registr celix_status_t serviceReference_retain(service_reference_pt ref); celix_status_t serviceReference_release(service_reference_pt ref, bool *destroyed); -celix_status_t serviceReference_increaseUsage(service_reference_pt ref); -celix_status_t serviceReference_decreaseUsage(service_reference_pt ref); +celix_status_t serviceReference_increaseUsage(service_reference_pt ref, size_t *updatedCount); +celix_status_t serviceReference_decreaseUsage(service_reference_pt ref, size_t *updatedCount); celix_status_t serviceReference_invalidate(service_reference_pt reference); celix_status_t serviceReference_isValid(service_reference_pt reference, bool *result); @@ -55,4 +56,9 @@ celix_status_t serviceReference_isValid(service_reference_pt reference, bool *re celix_status_t serviceReference_getUsageCount(service_reference_pt reference, size_t *count); celix_status_t serviceReference_getReferenceCount(service_reference_pt reference, size_t *count); +celix_status_t serviceReference_setService(service_reference_pt ref, void *service); +celix_status_t serviceReference_getService(service_reference_pt reference, void **service); + + + #endif /* SERVICE_REFERENCE_PRIVATE_H_ */ http://git-wip-us.apache.org/repos/asf/celix/blob/07d0dfe6/framework/private/include/service_registration_private.h ---------------------------------------------------------------------- diff --git a/framework/private/include/service_registration_private.h b/framework/private/include/service_registration_private.h index 081f996..1b48887 100644 --- a/framework/private/include/service_registration_private.h +++ b/framework/private/include/service_registration_private.h @@ -43,7 +43,6 @@ struct serviceRegistration { void * svcObj; long serviceId; - celix_thread_mutex_t mutex; bool isUnregistering; bool isServiceFactory; @@ -53,6 +52,8 @@ struct serviceRegistration { int nrOfServices; size_t refCount; //protected by mutex + + celix_thread_rwlock_t lock; }; service_registration_pt serviceRegistration_create(service_registry_pt registry, bundle_pt bundle, char * serviceName, long serviceId, void * serviceObject, properties_pt dictionary); @@ -67,7 +68,6 @@ void serviceRegistration_invalidate(service_registration_pt registration); celix_status_t serviceRegistration_getService(service_registration_pt registration, bundle_pt bundle, void **service); celix_status_t serviceRegistration_ungetService(service_registration_pt registration, bundle_pt bundle, void **service); -celix_status_t serviceRegistration_getRegistry(service_registration_pt registration, service_registry_pt *registry); celix_status_t serviceRegistration_getBundle(service_registration_pt registration, bundle_pt *bundle); celix_status_t serviceRegistration_getServiceName(service_registration_pt registration, char **serviceName); http://git-wip-us.apache.org/repos/asf/celix/blob/07d0dfe6/framework/private/src/service_reference.c ---------------------------------------------------------------------- diff --git a/framework/private/src/service_reference.c b/framework/private/src/service_reference.c index 73e9778..333339e 100644 --- a/framework/private/src/service_reference.c +++ b/framework/private/src/service_reference.c @@ -43,7 +43,7 @@ static void serviceReference_destroy(service_reference_pt); static void serviceReference_logWarningUsageCountBelowZero(service_reference_pt ref); -celix_status_t serviceReference_create(bundle_pt referenceOwner, service_registration_pt registration, service_reference_pt *out) { +celix_status_t serviceReference_create(bundle_pt referenceOwner, service_registration_pt registration, service_reference_pt *out) { celix_status_t status = CELIX_SUCCESS; service_reference_pt ref = calloc(1, sizeof(*ref)); @@ -53,6 +53,7 @@ celix_status_t serviceReference_create(bundle_pt referenceOwner, service_registr serviceRegistration_retain(registration); ref->referenceOwner = referenceOwner; ref->registration = registration; + ref->service = NULL; serviceRegistration_getBundle(registration, &ref->registrationBundle); celixThreadRwlock_create(&ref->lock, NULL); ref->refCount = 1; @@ -76,6 +77,23 @@ celix_status_t serviceReference_retain(service_reference_pt ref) { } celix_status_t serviceReference_release(service_reference_pt ref, bool *out) { + celixThreadRwlock_writeLock(&ref->lock); + if (ref->refCount > 0) { + ref->refCount -= 1; + } else { + fw_log(logger, OSGI_FRAMEWORK_LOG_ERROR, "serviceReference_release error serv reference count already at 0\n"); + } + + if (out) { + *out = ref->refCount == 0; + } + + celixThreadRwlock_unlock(&ref->lock); + return CELIX_SUCCESS; +} + +/* TODO enable, for now use a leak version to prevent to much errors +celix_status_t serviceReference_release(service_reference_pt ref, bool *out) { bool destroyed = false; celixThreadRwlock_writeLock(&ref->lock); assert(ref->refCount > 0); @@ -91,17 +109,23 @@ celix_status_t serviceReference_release(service_reference_pt ref, bool *out) { *out = destroyed; } return CELIX_SUCCESS; -} +}*/ -celix_status_t serviceReference_increaseUsage(service_reference_pt ref) { +celix_status_t serviceReference_increaseUsage(service_reference_pt ref, size_t *out) { + size_t local = 0; celixThreadRwlock_writeLock(&ref->lock); ref->usageCount += 1; + local = ref->usageCount; celixThreadRwlock_unlock(&ref->lock); + if (out) { + *out = local; + } return CELIX_SUCCESS; } -celix_status_t serviceReference_decreaseUsage(service_reference_pt ref) { +celix_status_t serviceReference_decreaseUsage(service_reference_pt ref, size_t *out) { celix_status_t status = CELIX_SUCCESS; + size_t localCount = 0; celixThreadRwlock_writeLock(&ref->lock); if (ref->usageCount == 0) { serviceReference_logWarningUsageCountBelowZero(ref); @@ -109,7 +133,12 @@ celix_status_t serviceReference_decreaseUsage(service_reference_pt ref) { } else { ref->usageCount -= 1; } + localCount = ref->usageCount; celixThreadRwlock_unlock(&ref->lock); + + if (out) { + *out = localCount; + } return status; } @@ -134,6 +163,22 @@ celix_status_t serviceReference_getReferenceCount(service_reference_pt ref, size return status; } +celix_status_t serviceReference_getService(service_reference_pt ref, void **service) { + celix_status_t status = CELIX_SUCCESS; + celixThreadRwlock_readLock(&ref->lock); + *service = ref->service; + celixThreadRwlock_unlock(&ref->lock); + return status; +} + +celix_status_t serviceReference_setService(service_reference_pt ref, void *service) { + celix_status_t status = CELIX_SUCCESS; + celixThreadRwlock_writeLock(&ref->lock); + ref->service = service; + celixThreadRwlock_unlock(&ref->lock); + return status; +} + static void serviceReference_destroy(service_reference_pt ref) { assert(ref->refCount == 0); celixThreadRwlock_destroy(&ref->lock); http://git-wip-us.apache.org/repos/asf/celix/blob/07d0dfe6/framework/private/src/service_registration.c ---------------------------------------------------------------------- diff --git a/framework/private/src/service_registration.c b/framework/private/src/service_registration.c index 3bd9ddd..f9c2ec2 100644 --- a/framework/private/src/service_registration.c +++ b/framework/private/src/service_registration.c @@ -75,7 +75,7 @@ static celix_status_t serviceRegistration_createInternal(service_registry_pt reg } reg->isUnregistering = false; - celixThreadMutex_create(®->mutex, NULL); + celixThreadRwlock_create(®->lock, NULL); serviceRegistration_initializeProperties(reg, dictionary); } else { @@ -90,19 +90,19 @@ static celix_status_t serviceRegistration_createInternal(service_registry_pt reg } void serviceRegistration_retain(service_registration_pt registration) { - celixThreadMutex_lock(®istration->mutex); + celixThreadRwlock_writeLock(®istration->lock); registration->refCount += 1; - celixThreadMutex_unlock(®istration->mutex); + celixThreadRwlock_unlock(®istration->lock); } void serviceRegistration_release(service_registration_pt registration) { - celixThreadMutex_lock(®istration->mutex); - assert(registration->refCount > 0); + celixThreadRwlock_writeLock(®istration->lock); + assert(registration->refCount > 0); registration->refCount -= 1; if (registration->refCount == 0) { serviceRegistration_destroy(registration); } else { - celixThreadMutex_unlock(®istration->mutex); + celixThreadRwlock_unlock(®istration->lock); } } @@ -112,7 +112,7 @@ static celix_status_t serviceRegistration_destroy(service_registration_pt regist registration->registry = NULL; properties_destroy(registration->properties); - celixThreadMutex_destroy(®istration->mutex); + celixThreadRwlock_destroy(®istration->lock); free(registration); return CELIX_SUCCESS; @@ -125,7 +125,6 @@ static celix_status_t serviceRegistration_initializeProperties(service_registrat dictionary = properties_create(); } - registration->properties = dictionary; snprintf(sId, 32, "%ld", registration->serviceId); properties_set(dictionary, (char *) OSGI_FRAMEWORK_SERVICE_ID, sId); @@ -134,29 +133,46 @@ static celix_status_t serviceRegistration_initializeProperties(service_registrat properties_set(dictionary, (char *) OSGI_FRAMEWORK_OBJECTCLASS, registration->className); } - return CELIX_SUCCESS; + + celixThreadRwlock_writeLock(®istration->lock); + registration->properties = dictionary; + celixThreadRwlock_unlock(®istration->lock); + + + return CELIX_SUCCESS; } bool serviceRegistration_isValid(service_registration_pt registration) { - return registration == NULL ? false : registration->svcObj != NULL; + bool result; + celixThreadRwlock_readLock(®istration->lock); + result = registration == NULL ? false : registration->svcObj != NULL; + celixThreadRwlock_unlock(®istration->lock); + return result; } void serviceRegistration_invalidate(service_registration_pt registration) { - celixThreadMutex_lock(®istration->mutex); + celixThreadRwlock_writeLock(®istration->lock); registration->svcObj = NULL; - celixThreadMutex_unlock(®istration->mutex); + celixThreadRwlock_unlock(®istration->lock); } celix_status_t serviceRegistration_unregister(service_registration_pt registration) { celix_status_t status = CELIX_SUCCESS; - celixThreadMutex_lock(®istration->mutex); - if (!serviceRegistration_isValid(registration) || registration->isUnregistering) { + + bool notValidOrUnregistering; + celixThreadRwlock_readLock(®istration->lock); + notValidOrUnregistering = !serviceRegistration_isValid(registration) || registration->isUnregistering; + celixThreadRwlock_unlock(®istration->lock); + + + if (notValidOrUnregistering) { printf("Service is already unregistered\n"); status = CELIX_ILLEGAL_STATE; } else { - registration->isUnregistering = true; - } - celixThreadMutex_unlock(®istration->mutex); + celixThreadRwlock_writeLock(®istration->lock); + registration->isUnregistering = true; + celixThreadRwlock_unlock(®istration->lock); + } if (status == CELIX_SUCCESS) { serviceRegistry_unregisterService(registration->registry, registration->bundle, registration); @@ -169,71 +185,71 @@ celix_status_t serviceRegistration_unregister(service_registration_pt registrati celix_status_t serviceRegistration_getService(service_registration_pt registration, bundle_pt bundle, void **service) { int status = CELIX_SUCCESS; + celixThreadRwlock_readLock(®istration->lock); if (registration->isServiceFactory) { service_factory_pt factory = registration->serviceFactory; status = factory->getService(factory->factory, bundle, registration, service); } else { (*service) = registration->svcObj; } + celixThreadRwlock_unlock(®istration->lock); return status; } celix_status_t serviceRegistration_ungetService(service_registration_pt registration, bundle_pt bundle, void **service) { + celixThreadRwlock_readLock(®istration->lock); if (registration->isServiceFactory) { service_factory_pt factory = registration->serviceFactory; factory->ungetService(factory->factory, bundle, registration, service); } + celixThreadRwlock_unlock(®istration->lock); return CELIX_SUCCESS; } celix_status_t serviceRegistration_getProperties(service_registration_pt registration, properties_pt *properties) { celix_status_t status = CELIX_SUCCESS; - if (registration != NULL && *properties == NULL) { + celixThreadRwlock_readLock(®istration->lock); + if (registration != NULL && *properties == NULL) { *properties = registration->properties; } else { status = CELIX_ILLEGAL_ARGUMENT; } + celixThreadRwlock_unlock(®istration->lock); + - framework_logIfError(logger, status, NULL, "Cannot get registration properties"); + framework_logIfError(logger, status, NULL, "Cannot get registration properties"); return status; } celix_status_t serviceRegistration_setProperties(service_registration_pt registration, properties_pt properties) { - properties_pt oldProps = registration->properties; - serviceRegistration_initializeProperties(registration, properties); + + celixThreadRwlock_writeLock(®istration->lock); + properties_pt oldProps = registration->properties; + serviceRegistration_initializeProperties(registration, properties); + celixThreadRwlock_unlock(®istration->lock); serviceRegistry_servicePropertiesModified(registration->registry, registration, oldProps); return CELIX_SUCCESS; } -celix_status_t serviceRegistration_getRegistry(service_registration_pt registration, service_registry_pt *registry) { - celix_status_t status = CELIX_SUCCESS; - - if (registration != NULL && *registry == NULL) { - *registry = registration->registry; - } else { - status = CELIX_ILLEGAL_ARGUMENT; - } - - framework_logIfError(logger, status, NULL, "Cannot get registry"); - - return status; -} celix_status_t serviceRegistration_getBundle(service_registration_pt registration, bundle_pt *bundle) { celix_status_t status = CELIX_SUCCESS; - if (registration != NULL && *bundle == NULL) { + celixThreadRwlock_readLock(®istration->lock); + if (registration != NULL && *bundle == NULL) { *bundle = registration->bundle; } else { status = CELIX_ILLEGAL_ARGUMENT; } + celixThreadRwlock_unlock(®istration->lock); + - framework_logIfError(logger, status, NULL, "Cannot get bundle"); + framework_logIfError(logger, status, NULL, "Cannot get bundle"); return status; } @@ -241,13 +257,15 @@ celix_status_t serviceRegistration_getBundle(service_registration_pt registratio celix_status_t serviceRegistration_getServiceName(service_registration_pt registration, char **serviceName) { celix_status_t status = CELIX_SUCCESS; - if (registration != NULL && *serviceName == NULL) { + celixThreadRwlock_readLock(®istration->lock); + if (registration != NULL && *serviceName == NULL) { *serviceName = registration->className; } else { status = CELIX_ILLEGAL_ARGUMENT; } + celixThreadRwlock_unlock(®istration->lock); - framework_logIfError(logger, status, NULL, "Cannot get service name"); + framework_logIfError(logger, status, NULL, "Cannot get service name"); return status; } http://git-wip-us.apache.org/repos/asf/celix/blob/07d0dfe6/framework/private/src/service_registry.c ---------------------------------------------------------------------- diff --git a/framework/private/src/service_registry.c b/framework/private/src/service_registry.c index 9f84ded..6abd0cc 100644 --- a/framework/private/src/service_registry.c +++ b/framework/private/src/service_registry.c @@ -201,7 +201,6 @@ celix_status_t serviceRegistry_clearServiceRegistrations(service_registry_pt reg celix_status_t status = CELIX_SUCCESS; array_list_pt registrations = NULL; - celixThreadMutex_lock(®istry->mutex); registrations = hashMap_get(registry->serviceRegistrations, bundle); @@ -386,8 +385,7 @@ celix_status_t serviceRegistry_clearReferencesFor(service_registry_pt registry, serviceRegistry_logWarningServiceReferenceUsageCount(registry, usageCount, refCount); while (usageCount > 0) { - serviceReference_decreaseUsage(ref); - serviceReference_getUsageCount(ref, &usageCount); + serviceReference_decreaseUsage(ref, &usageCount); } bool destroyed = false; @@ -431,14 +429,21 @@ celix_status_t serviceRegistry_getServicesInUse(service_registry_pt registry, bu celix_status_t serviceRegistry_getService(service_registry_pt registry, bundle_pt bundle, service_reference_pt reference, void **out) { celix_status_t status = CELIX_SUCCESS; service_registration_pt registration = NULL; + size_t count = 0; + void *service = NULL; serviceReference_getServiceRegistration(reference, ®istration); - celixThreadMutex_lock(®istry->mutex); + if (serviceRegistration_isValid(registration)) { - serviceReference_increaseUsage(reference); - serviceRegistration_getService(registration, bundle, out); + serviceReference_increaseUsage(reference, &count); + if (count == 1) { + serviceRegistration_getService(registration, bundle, &service); + serviceReference_setService(reference, service); + } + + serviceReference_getService(reference, out); } else { *out = NULL; //invalid service registration } @@ -451,8 +456,18 @@ celix_status_t serviceRegistry_getService(service_registry_pt registry, bundle_p celix_status_t serviceRegistry_ungetService(service_registry_pt registry, bundle_pt bundle, service_reference_pt reference, bool *result) { celix_status_t status = CELIX_SUCCESS; + service_registration_pt reg = NULL; + void *service = NULL; + size_t count = 0; + + celix_status_t subStatus = serviceReference_decreaseUsage(reference, &count); + + if (count == 0) { + serviceReference_getService(reference, &service); + serviceReference_getServiceRegistration(reference, ®); + serviceRegistration_ungetService(reg, bundle, &service); + } - celix_status_t subStatus = serviceReference_decreaseUsage(reference); if (result) { *result = (subStatus == CELIX_SUCCESS); } http://git-wip-us.apache.org/repos/asf/celix/blob/07d0dfe6/remote_services/examples/calculator_endpoint/private/src/calculator_endpoint_activator.c ---------------------------------------------------------------------- diff --git a/remote_services/examples/calculator_endpoint/private/src/calculator_endpoint_activator.c b/remote_services/examples/calculator_endpoint/private/src/calculator_endpoint_activator.c index e76ebfa..04130f8 100644 --- a/remote_services/examples/calculator_endpoint/private/src/calculator_endpoint_activator.c +++ b/remote_services/examples/calculator_endpoint/private/src/calculator_endpoint_activator.c @@ -81,7 +81,7 @@ celix_status_t bundleActivator_stop(void * userData, bundle_context_pt context) serviceRegistration_unregister(activator->endpointServiceRegistration); - free(activator->endpointService->endpoint); + //calculatorEndpoint_destroy(activator->endpointService->endpoint); free(activator->endpointService); return status; http://git-wip-us.apache.org/repos/asf/celix/blob/07d0dfe6/remote_services/examples/calculator_service/private/src/calculator_activator.c ---------------------------------------------------------------------- diff --git a/remote_services/examples/calculator_service/private/src/calculator_activator.c b/remote_services/examples/calculator_service/private/src/calculator_activator.c index 13ea995..688a7b0 100644 --- a/remote_services/examples/calculator_service/private/src/calculator_activator.c +++ b/remote_services/examples/calculator_service/private/src/calculator_activator.c @@ -76,13 +76,13 @@ celix_status_t bundleActivator_start(void * userData, bundle_context_pt context) properties = properties_create(); properties_set(properties, (char *) OSGI_RSA_SERVICE_EXPORTED_INTERFACES, (char *) CALCULATOR_SERVICE); - bundleContext_registerService(context, (char *) CALCULATOR_SERVICE, activator->service, properties, &activator->calculatorReg); + bundleContext_registerService(context, (char *) CALCULATOR_SERVICE, activator->service, properties, &activator->calculatorReg); - properties_pt properties2 = properties_create(); - properties_set(properties2, (char *) OSGI_RSA_SERVICE_EXPORTED_INTERFACES, (char *) CALCULATOR2_SERVICE); - bundleContext_registerService(context, CALCULATOR2_SERVICE, activator->service, properties2, &activator->calculatorReg2); - } - } + properties_pt properties2 = properties_create(); + properties_set(properties2, (char *) OSGI_RSA_SERVICE_EXPORTED_INTERFACES, (char *) CALCULATOR2_SERVICE); + bundleContext_registerService(context, CALCULATOR2_SERVICE, activator->service, properties2, &activator->calculatorReg2); + } + } return status; } http://git-wip-us.apache.org/repos/asf/celix/blob/07d0dfe6/remote_services/remote_service_admin_dfi/rsa/private/src/export_registration_dfi.c ---------------------------------------------------------------------- diff --git a/remote_services/remote_service_admin_dfi/rsa/private/src/export_registration_dfi.c b/remote_services/remote_service_admin_dfi/rsa/private/src/export_registration_dfi.c index 4182a4c..0567870 100644 --- a/remote_services/remote_service_admin_dfi/rsa/private/src/export_registration_dfi.c +++ b/remote_services/remote_service_admin_dfi/rsa/private/src/export_registration_dfi.c @@ -191,6 +191,9 @@ static void exportRegistration_removeServ(export_registration_pt reg, service_re celix_status_t exportRegistration_stop(export_registration_pt reg) { celix_status_t status = CELIX_SUCCESS; status = bundleContext_ungetService(reg->context, reg->exportReference.reference, NULL); + if (status == CELIX_SUCCESS) { + bundleContext_ungetServiceReference(reg->context, reg->exportReference.reference); + } return status; } http://git-wip-us.apache.org/repos/asf/celix/blob/07d0dfe6/remote_services/remote_service_admin_dfi/rsa/private/src/remote_service_admin_dfi.c ---------------------------------------------------------------------- diff --git a/remote_services/remote_service_admin_dfi/rsa/private/src/remote_service_admin_dfi.c b/remote_services/remote_service_admin_dfi/rsa/private/src/remote_service_admin_dfi.c index 066c3da..fc0303b 100644 --- a/remote_services/remote_service_admin_dfi/rsa/private/src/remote_service_admin_dfi.c +++ b/remote_services/remote_service_admin_dfi/rsa/private/src/remote_service_admin_dfi.c @@ -379,8 +379,14 @@ celix_status_t remoteServiceAdmin_exportService(remote_service_admin_pt admin, c logHelper_log(admin->loghelper, OSGI_LOGSERVICE_ERROR, "RSA: exportService called for serviceId %s", serviceId); - if (status == CELIX_SUCCESS && arrayList_size(references) >= 1) { - reference = arrayList_get(references, 0); + int i; + int size = arrayList_size(references); + for (i = 0; i < size; i += 1) { + if (i == 0) { + reference = arrayList_get(references, i); + } else { + bundleContext_ungetServiceReference(admin->context, arrayList_get(references, i)); + } } if(references != NULL){ http://git-wip-us.apache.org/repos/asf/celix/blob/07d0dfe6/remote_services/remote_service_admin_dfi/rsa_tst/rsa_tests.cpp ---------------------------------------------------------------------- diff --git a/remote_services/remote_service_admin_dfi/rsa_tst/rsa_tests.cpp b/remote_services/remote_service_admin_dfi/rsa_tst/rsa_tests.cpp index 5784730..fd764d2 100644 --- a/remote_services/remote_service_admin_dfi/rsa_tst/rsa_tests.cpp +++ b/remote_services/remote_service_admin_dfi/rsa_tst/rsa_tests.cpp @@ -79,9 +79,15 @@ extern "C" { rc = bundleContext_ungetService(context, rsaRef, NULL); CHECK_EQUAL(CELIX_SUCCESS, rc); + rc = bundleContext_ungetServiceReference(context, rsaRef); + CHECK_EQUAL(CELIX_SUCCESS, rc); + rc = bundleContext_ungetService(context, calcRef, NULL); CHECK_EQUAL(CELIX_SUCCESS, rc); + rc = bundleContext_ungetServiceReference(context, calcRef); + CHECK_EQUAL(CELIX_SUCCESS, rc); + celixLauncher_stop(framework); celixLauncher_waitForShutdown(framework); celixLauncher_destroy(framework);
