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(®->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(®istration->mutex); + registration->refCount += 1; + celixThreadMutex_unlock(®istration->mutex); +} + +void serviceRegistration_release(service_registration_pt registration) { + celixThreadMutex_lock(®istration->mutex); + assert(registration->refCount > 0); + registration->refCount -= 1; + if (registration->refCount == 0) { + serviceRegistration_destroy(registration); + } else { + celixThreadMutex_unlock(®istration->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(®istry->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, ®); 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_ */
