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(&reg->mutex, NULL);
+        celixThreadRwlock_create(&reg->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(&registration->mutex);
+       celixThreadRwlock_writeLock(&registration->lock);
        registration->refCount += 1;
-       celixThreadMutex_unlock(&registration->mutex);
+    celixThreadRwlock_unlock(&registration->lock);
 }
 
 void serviceRegistration_release(service_registration_pt registration) {
-       celixThreadMutex_lock(&registration->mutex);
-       assert(registration->refCount > 0);
+    celixThreadRwlock_writeLock(&registration->lock);
+    assert(registration->refCount > 0);
        registration->refCount -= 1;
        if (registration->refCount == 0) {
                serviceRegistration_destroy(registration);
        } else {
-               celixThreadMutex_unlock(&registration->mutex);
+        celixThreadRwlock_unlock(&registration->lock);
        }
 }
 
@@ -112,7 +112,7 @@ static celix_status_t 
serviceRegistration_destroy(service_registration_pt regist
        registration->registry = NULL;
 
        properties_destroy(registration->properties);
-       celixThreadMutex_destroy(&registration->mutex);
+    celixThreadRwlock_destroy(&registration->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(&registration->lock);
+    registration->properties = dictionary;
+    celixThreadRwlock_unlock(&registration->lock);
+
+
+    return CELIX_SUCCESS;
 }
 
 bool serviceRegistration_isValid(service_registration_pt registration) {
-       return registration == NULL ? false : registration->svcObj != NULL;
+    bool result;
+    celixThreadRwlock_readLock(&registration->lock);
+    result = registration == NULL ? false : registration->svcObj != NULL;
+    celixThreadRwlock_unlock(&registration->lock);
+    return result;
 }
 
 void serviceRegistration_invalidate(service_registration_pt registration) {
-       celixThreadMutex_lock(&registration->mutex);
+    celixThreadRwlock_writeLock(&registration->lock);
        registration->svcObj = NULL;
-       celixThreadMutex_unlock(&registration->mutex);
+    celixThreadRwlock_unlock(&registration->lock);
 }
 
 celix_status_t serviceRegistration_unregister(service_registration_pt 
registration) {
        celix_status_t status = CELIX_SUCCESS;
-       celixThreadMutex_lock(&registration->mutex);
-       if (!serviceRegistration_isValid(registration) || 
registration->isUnregistering) {
+
+    bool notValidOrUnregistering;
+    celixThreadRwlock_readLock(&registration->lock);
+    notValidOrUnregistering = !serviceRegistration_isValid(registration) || 
registration->isUnregistering;
+    celixThreadRwlock_unlock(&registration->lock);
+
+
+    if (notValidOrUnregistering) {
                printf("Service is already unregistered\n");
                status = CELIX_ILLEGAL_STATE;
        } else {
-               registration->isUnregistering = true;
-       }
-       celixThreadMutex_unlock(&registration->mutex);
+        celixThreadRwlock_writeLock(&registration->lock);
+        registration->isUnregistering = true;
+        celixThreadRwlock_unlock(&registration->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(&registration->lock);
     if (registration->isServiceFactory) {
         service_factory_pt factory = registration->serviceFactory;
         status = factory->getService(factory->factory, bundle, registration, 
service);
     } else {
         (*service) = registration->svcObj;
     }
+    celixThreadRwlock_unlock(&registration->lock);
     return status;
 }
 
 celix_status_t serviceRegistration_ungetService(service_registration_pt 
registration, bundle_pt bundle, void **service) {
+    celixThreadRwlock_readLock(&registration->lock);
     if (registration->isServiceFactory) {
         service_factory_pt factory = registration->serviceFactory;
         factory->ungetService(factory->factory, bundle, registration, service);
     }
+    celixThreadRwlock_unlock(&registration->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(&registration->lock);
+    if (registration != NULL && *properties == NULL) {
                *properties = registration->properties;
        } else {
                status = CELIX_ILLEGAL_ARGUMENT;
        }
+    celixThreadRwlock_unlock(&registration->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(&registration->lock);
+    properties_pt oldProps = registration->properties;
+    serviceRegistration_initializeProperties(registration, properties);
+    celixThreadRwlock_unlock(&registration->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(&registration->lock);
+    if (registration != NULL && *bundle == NULL) {
                *bundle = registration->bundle;
        } else {
                status = CELIX_ILLEGAL_ARGUMENT;
        }
+    celixThreadRwlock_unlock(&registration->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(&registration->lock);
+    if (registration != NULL && *serviceName == NULL) {
                *serviceName = registration->className;
        } else {
                status = CELIX_ILLEGAL_ARGUMENT;
        }
+    celixThreadRwlock_unlock(&registration->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(&registry->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, &registration);
-       
        celixThreadMutex_lock(&registry->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, &reg);
+        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);

Reply via email to