Repository: celix
Updated Branches:
  refs/heads/feature/CELIX-272_synchronization_service_registry [created] 
e0231e51e


http://git-wip-us.apache.org/repos/asf/celix/blob/e0231e51/framework/private/src/service_registration.c
----------------------------------------------------------------------
diff --git a/framework/private/src/service_registration.c 
b/framework/private/src/service_registration.c
index 1817784..718a633 100644
--- a/framework/private/src/service_registration.c
+++ b/framework/private/src/service_registration.c
@@ -26,6 +26,7 @@
 #include <stdlib.h>
 #include <stdio.h>
 #include <string.h>
+#include <assert.h>
 
 #include "service_registration_private.h"
 #include "constants.h"
@@ -35,9 +36,9 @@
 #include "celix_threads.h"
 
 static celix_status_t 
serviceRegistration_initializeProperties(service_registration_pt registration, 
properties_pt properties);
-
-celix_status_t serviceRegistration_createInternal(service_registry_pt 
registry, bundle_pt bundle, char * serviceName, long serviceId,
+static celix_status_t serviceRegistration_createInternal(service_registry_pt 
registry, bundle_pt bundle, char * serviceName, long serviceId,
         void * serviceObject, properties_pt dictionary, bool isFactory, 
service_registration_pt *registration);
+static celix_status_t serviceRegistration_destroy(service_registration_pt 
registration);
 
 service_registration_pt serviceRegistration_create(service_registry_pt 
registry, bundle_pt bundle, char * serviceName, long serviceId, void * 
serviceObject, properties_pt dictionary) {
     service_registration_pt registration = NULL;
@@ -51,39 +52,61 @@ service_registration_pt 
serviceRegistration_createServiceFactory(service_registr
     return registration;
 }
 
-celix_status_t serviceRegistration_createInternal(service_registry_pt 
registry, bundle_pt bundle, char * serviceName, long serviceId,
-        void * serviceObject, properties_pt dictionary, bool isFactory, 
service_registration_pt *registration) {
+static celix_status_t serviceRegistration_createInternal(service_registry_pt 
registry, bundle_pt bundle, char * serviceName, long serviceId,
+        void * serviceObject, properties_pt dictionary, bool isFactory, 
service_registration_pt *out) {
     celix_status_t status = CELIX_SUCCESS;
 
-    *registration = malloc(sizeof(**registration));
-    if (*registration) {
-        (*registration)->services = NULL;
-        (*registration)->nrOfServices = 0;
-               (*registration)->isServiceFactory = isFactory;
-               (*registration)->registry = registry;
-               (*registration)->className = strdup(serviceName);
-               (*registration)->bundle = bundle;
-
-               (*registration)->serviceId = serviceId;
-               (*registration)->svcObj = serviceObject;
+       service_registration_pt  reg = calloc(1, sizeof(*reg));
+    if (reg) {
+        reg->services = NULL;
+        reg->nrOfServices = 0;
+               reg->isServiceFactory = isFactory;
+               reg->registry = registry;
+               reg->className = strdup(serviceName);
+               reg->bundle = bundle;
+               reg->refCount = 1;
+
+               reg->serviceId = serviceId;
+               reg->svcObj = serviceObject;
                if (isFactory) {
-                       (*registration)->serviceFactory = (service_factory_pt) 
(*registration)->svcObj;
+                       reg->serviceFactory = (service_factory_pt) reg->svcObj;
                } else {
-                       (*registration)->serviceFactory = NULL;
+                       reg->serviceFactory = NULL;
                }
 
-               (*registration)->isUnregistering = false;
-               celixThreadMutex_create(&(*registration)->mutex, NULL);
+               reg->isUnregistering = false;
+               celixThreadMutex_create(&reg->mutex, NULL);
 
-               serviceRegistration_initializeProperties(*registration, 
dictionary);
+               serviceRegistration_initializeProperties(reg, dictionary);
     } else {
        status = CELIX_ENOMEM;
     }
 
+       if (status == CELIX_SUCCESS) {
+               *out = reg;
+       }
+
        return status;
 }
 
-celix_status_t serviceRegistration_destroy(service_registration_pt 
registration) {
+void serviceRegistration_retain(service_registration_pt registration) {
+       celixThreadMutex_lock(&registration->mutex);
+       registration->refCount += 1;
+       celixThreadMutex_unlock(&registration->mutex);
+}
+
+void serviceRegistration_release(service_registration_pt registration) {
+       celixThreadMutex_lock(&registration->mutex);
+       assert(registration->refCount > 0);
+       registration->refCount -= 1;
+       if (registration->refCount == 0) {
+               serviceRegistration_destroy(registration);
+       } else {
+               celixThreadMutex_unlock(&registration->mutex);
+       }
+}
+
+static celix_status_t serviceRegistration_destroy(service_registration_pt 
registration) {
     free(registration->className);
        registration->className = NULL;
        registration->registry = NULL;
@@ -99,7 +122,7 @@ celix_status_t 
serviceRegistration_destroy(service_registration_pt registration)
 }
 
 static celix_status_t 
serviceRegistration_initializeProperties(service_registration_pt registration, 
properties_pt dictionary) {
-       char * sId = (char *)malloc(sizeof(registration->serviceId) + 1);
+    char sId[32];
 
        if (dictionary == NULL) {
                dictionary = properties_create();
@@ -107,15 +130,13 @@ static celix_status_t 
serviceRegistration_initializeProperties(service_registrat
 
        registration->properties = dictionary;
 
-       sprintf(sId, "%ld", registration->serviceId);
+       snprintf(sId, 32, "%ld", registration->serviceId);
        properties_set(dictionary, (char *) OSGI_FRAMEWORK_SERVICE_ID, sId);
 
        if (properties_get(dictionary, (char *) OSGI_FRAMEWORK_OBJECTCLASS) == 
NULL) {
                properties_set(dictionary, (char *) OSGI_FRAMEWORK_OBJECTCLASS, 
registration->className);
        }
 
-       free(sId);
-
        return CELIX_SUCCESS;
 }
 

http://git-wip-us.apache.org/repos/asf/celix/blob/e0231e51/framework/private/src/service_registry.c
----------------------------------------------------------------------
diff --git a/framework/private/src/service_registry.c 
b/framework/private/src/service_registry.c
index f9cea4e..ec72f6d 100644
--- a/framework/private/src/service_registry.c
+++ b/framework/private/src/service_registry.c
@@ -38,7 +38,9 @@
 #include "celix_log.h"
 
 static celix_status_t serviceRegistry_getUsageCount(service_registry_pt 
registry, bundle_pt bundle, service_reference_pt reference, usage_count_pt 
*usageCount);
-static celix_status_t serviceRegistry_addUsageCount(service_registry_pt 
registry, bundle_pt bundle, service_reference_pt reference, usage_count_pt 
*usageCount);
+static celix_status_t serviceRegistry_addUsageCount(service_registry_pt 
registry, bundle_pt bundle,
+                                                   service_reference_pt 
reference,
+                                                   service_registration_pt 
registration, usage_count_pt *usageCount);
 static celix_status_t serviceRegistry_flushUsageCount(service_registry_pt 
registry, bundle_pt bundle, service_reference_pt reference);
 
 celix_status_t serviceRegistry_registerServiceInternal(service_registry_pt 
registry, bundle_pt bundle, char * serviceName, void * serviceObject, 
properties_pt dictionary, bool isFactory, service_registration_pt 
*registration);
@@ -108,12 +110,17 @@ static celix_status_t 
serviceRegistry_getUsageCount(service_registry_pt registry
        return CELIX_SUCCESS;
 }
 
-static celix_status_t serviceRegistry_addUsageCount(service_registry_pt 
registry, bundle_pt bundle, service_reference_pt reference, usage_count_pt 
*usageCount) {
+static celix_status_t serviceRegistry_addUsageCount(service_registry_pt 
registry, bundle_pt bundle,
+                                                   service_reference_pt 
reference,
+                                                   service_registration_pt 
registration, usage_count_pt *usageCount) {
        array_list_pt usages = hashMap_get(registry->inUseMap, bundle);
        usage_count_pt usage = malloc(sizeof(*usage));
        usage->reference = reference;
        usage->count = 0;
        usage->service = NULL;
+    usage->registration = registration;
+
+    serviceRegistration_retain(registration);
 
        if (usages == NULL) {
                arrayList_create(&usages);
@@ -134,6 +141,7 @@ static celix_status_t 
serviceRegistry_flushUsageCount(service_registry_pt regist
                        serviceReference_equals(usage->reference, reference, 
&equals);
                        if (equals) {
                                arrayListIterator_remove(iter);
+                serviceRegistration_release(usage->registration);
                                free(usage);
                        }
                }
@@ -262,10 +270,8 @@ celix_status_t 
serviceRegistry_unregisterService(service_registry_pt registry, b
        }
        arrayList_destroy(references);
 
-       //TODO not needed, the registration is destroyed, any reference to the 
registration is invalid and will result in a segfault
-       serviceRegistration_invalidate(registration);
-
-       // serviceRegistration_destroy(registration);
+    serviceRegistration_invalidate(registration);
+    serviceRegistration_release(registration);
 
        celixThreadMutex_unlock(&registry->mutex);
 
@@ -345,7 +351,7 @@ celix_status_t 
serviceRegistry_getServiceReferencesForRegistration(service_regis
             service_registration_pt reg = NULL;
             service_reference_pt reference = (service_reference_pt) 
arrayList_get(refs, refIdx);
             bool valid = false;
-            serviceRefernce_isValid(reference, &valid);
+                       serviceReference_isValid(reference, &valid);
             if (valid) {
                 serviceReference_getServiceRegistration(reference, &reg);
                 if (reg == registration) {
@@ -421,7 +427,7 @@ celix_status_t 
serviceRegistry_ungetServiceReference(service_registry_pt registr
     celix_status_t status = CELIX_SUCCESS;
 
     bool valid = false;
-    serviceRefernce_isValid(reference, &valid);
+       serviceReference_isValid(reference, &valid);
     if (valid) {
         bool ungetResult = true;
         while (ungetResult) {
@@ -433,7 +439,7 @@ celix_status_t 
serviceRegistry_ungetServiceReference(service_registry_pt registr
     array_list_pt references = hashMap_get(registry->serviceReferences, owner);
     if (references != NULL) {
         arrayList_removeElement(references, reference);
-        serviceReference_destroy(&reference);
+        serviceReference_release(reference);
         if (arrayList_size(references) > 0) {
             hashMap_put(registry->serviceReferences, owner, references);
         } else {
@@ -494,7 +500,7 @@ celix_status_t 
serviceRegistry_getService(service_registry_pt registry, bundle_p
        if (serviceRegistration_isValid(registration)) {
                status = serviceRegistry_getUsageCount(registry, bundle, 
reference, &usage);
                if (usage == NULL) {
-                       status = serviceRegistry_addUsageCount(registry, 
bundle, reference, &usage);
+                       status = serviceRegistry_addUsageCount(registry, 
bundle, reference, registration, &usage);
                }
                usage->count++;
                *service = usage->service;

http://git-wip-us.apache.org/repos/asf/celix/blob/e0231e51/framework/public/include/properties.h
----------------------------------------------------------------------
diff --git a/framework/public/include/properties.h 
b/framework/public/include/properties.h
index c4803cb..9fa5f68 100644
--- a/framework/public/include/properties.h
+++ b/framework/public/include/properties.h
@@ -31,6 +31,7 @@
 
 #include "hash_map.h"
 #include "framework_exports.h"
+#include "celix_errno.h"
 
 typedef hash_map_pt properties_pt;
 
@@ -44,4 +45,6 @@ FRAMEWORK_EXPORT char * properties_get(properties_pt 
properties, char * key);
 FRAMEWORK_EXPORT char * properties_getWithDefault(properties_pt properties, 
char * key, char * defaultValue);
 FRAMEWORK_EXPORT char * properties_set(properties_pt properties, char * key, 
char * value);
 
+FRAMEWORK_EXPORT celix_status_t properties_copy(properties_pt properties, 
properties_pt *copy);
+
 #endif /* PROPERTIES_H_ */

Reply via email to