http://git-wip-us.apache.org/repos/asf/celix/blob/a1c30887/framework/private/src/service_reference.c ---------------------------------------------------------------------- diff --git a/framework/private/src/service_reference.c b/framework/private/src/service_reference.c deleted file mode 100644 index 545426d..0000000 --- a/framework/private/src/service_reference.c +++ /dev/null @@ -1,378 +0,0 @@ -/** - *Licensed to the Apache Software Foundation (ASF) under one - *or more contributor license agreements. See the NOTICE file - *distributed with this work for additional information - *regarding copyright ownership. The ASF licenses this file - *to you under the Apache License, Version 2.0 (the - *"License"); you may not use this file except in compliance - *with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - *Unless required by applicable law or agreed to in writing, - *software distributed under the License is distributed on an - *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - *specific language governing permissions and limitations - *under the License. - */ -/* - * service_reference.c - * - * \date Jul 20, 2010 - * \author <a href="mailto:[email protected]">Apache Celix Project Team</a> - * \copyright Apache License, Version 2.0 - */ -#include <stdio.h> -#include <stdlib.h> -#include <constants.h> -#include <stdint.h> -#include <utils.h> -#include <assert.h> - -#include "service_reference.h" - -#include "service_reference_private.h" -#include "service_registration_private.h" - -static void serviceReference_destroy(service_reference_pt); -static void serviceReference_logWarningUsageCountBelowZero(service_reference_pt ref); - -celix_status_t serviceReference_create(registry_callback_t callback, 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)); - if (!ref) { - status = CELIX_ENOMEM; - } else { - ref->callback = callback; - ref->referenceOwner = referenceOwner; - ref->registration = registration; - ref->service = NULL; - serviceRegistration_getBundle(registration, &ref->registrationBundle); - celixThreadRwlock_create(&ref->lock, NULL); - ref->refCount = 1; - ref->usageCount = 0; - - serviceRegistration_retain(ref->registration); - } - - if (status == CELIX_SUCCESS) { - *out = ref; - } - - framework_logIfError(logger, status, NULL, "Cannot create service reference"); - - return status; -} - -celix_status_t serviceReference_retain(service_reference_pt ref) { - celixThreadRwlock_writeLock(&ref->lock); - ref->refCount += 1; - celixThreadRwlock_unlock(&ref->lock); - return CELIX_SUCCESS; -} - -celix_status_t serviceReference_release(service_reference_pt ref, bool *out) { - bool destroyed = false; - celixThreadRwlock_writeLock(&ref->lock); - assert(ref->refCount > 0); - ref->refCount -= 1; - if (ref->refCount == 0) { - if (ref->registration != NULL) { - serviceRegistration_release(ref->registration); - } - celixThreadRwlock_unlock(&ref->lock); - serviceReference_destroy(ref); - destroyed = true; - } else { - celixThreadRwlock_unlock(&ref->lock); - } - - if (out) { - *out = destroyed; - } - return CELIX_SUCCESS; -} - -celix_status_t serviceReference_increaseUsage(service_reference_pt ref, size_t *out) { - //fw_log(logger, OSGI_FRAMEWORK_LOG_DEBUG, "Destroying service reference %p\n", ref); - 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, size_t *out) { - celix_status_t status = CELIX_SUCCESS; - size_t localCount = 0; - celixThreadRwlock_writeLock(&ref->lock); - if (ref->usageCount == 0) { - serviceReference_logWarningUsageCountBelowZero(ref); - status = CELIX_BUNDLE_EXCEPTION; - } else { - ref->usageCount -= 1; - } - localCount = ref->usageCount; - celixThreadRwlock_unlock(&ref->lock); - - if (out) { - *out = localCount; - } - return status; -} - -static void serviceReference_logWarningUsageCountBelowZero(service_reference_pt ref __attribute__((unused))) { - fw_log(logger, OSGI_FRAMEWORK_LOG_WARNING, "Cannot decrease service usage count below 0\n"); -} - - -celix_status_t serviceReference_getUsageCount(service_reference_pt ref, size_t *count) { - celix_status_t status = CELIX_SUCCESS; - celixThreadRwlock_readLock(&ref->lock); - *count = ref->usageCount; - celixThreadRwlock_unlock(&ref->lock); - return status; -} - -celix_status_t serviceReference_getReferenceCount(service_reference_pt ref, size_t *count) { - celix_status_t status = CELIX_SUCCESS; - celixThreadRwlock_readLock(&ref->lock); - *count = ref->refCount; - celixThreadRwlock_unlock(&ref->lock); - return status; -} - -celix_status_t serviceReference_getService(service_reference_pt ref, void **service) { - celix_status_t status = CELIX_SUCCESS; - celixThreadRwlock_readLock(&ref->lock); - /*NOTE the service argument should be 'const void**' - To ensure backwards compatability a cast is made instead. - */ - *service = (const void**) ref->service; - celixThreadRwlock_unlock(&ref->lock); - return status; -} - -celix_status_t serviceReference_setService(service_reference_pt ref, const 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); - ref->registration = NULL; - free(ref); -} - -celix_status_t serviceReference_getBundle(service_reference_pt ref, bundle_pt *bundle) { - celix_status_t status = CELIX_SUCCESS; - celixThreadRwlock_readLock(&ref->lock); - if (ref->registration != NULL) { - *bundle = ref->registrationBundle; - } - celixThreadRwlock_unlock(&ref->lock); - return status; -} - -celix_status_t serviceReference_getOwner(service_reference_pt ref, bundle_pt *owner) { - celix_status_t status = CELIX_SUCCESS; - celixThreadRwlock_readLock(&ref->lock); - *owner = ref->referenceOwner; - celixThreadRwlock_unlock(&ref->lock); - return status; -} - -celix_status_t serviceReference_getServiceRegistration(service_reference_pt ref, service_registration_pt *out) { - if (ref != NULL) { - celixThreadRwlock_readLock(&ref->lock); - *out = ref->registration; - celixThreadRwlock_unlock(&ref->lock); - return CELIX_SUCCESS; - } else { - return CELIX_ILLEGAL_ARGUMENT; - } -} - -celix_status_t serviceReference_getProperty(service_reference_pt ref, const char* key, const char** value) { - celix_status_t status = CELIX_SUCCESS; - properties_pt props = NULL; - celixThreadRwlock_readLock(&ref->lock); - if (ref->registration != NULL) { - status = serviceRegistration_getProperties(ref->registration, &props); - if (status == CELIX_SUCCESS) { - *value = (char*) properties_get(props, key); - } - } else { - *value = NULL; - } - celixThreadRwlock_unlock(&ref->lock); - return status; -} - -FRAMEWORK_EXPORT celix_status_t serviceReference_getPropertyKeys(service_reference_pt ref, char **keys[], unsigned int *size) { - celix_status_t status = CELIX_SUCCESS; - properties_pt props = NULL; - - celixThreadRwlock_readLock(&ref->lock); - serviceRegistration_getProperties(ref->registration, &props); - hash_map_iterator_pt it; - int i = 0; - int vsize = hashMap_size(props); - *size = (unsigned int)vsize; - *keys = malloc(vsize * sizeof(**keys)); - it = hashMapIterator_create(props); - while (hashMapIterator_hasNext(it)) { - (*keys)[i] = hashMapIterator_nextKey(it); - i++; - } - hashMapIterator_destroy(it); - celixThreadRwlock_unlock(&ref->lock); - return status; -} - -celix_status_t serviceReference_invalidate(service_reference_pt ref) { - assert(ref != NULL); - celix_status_t status = CELIX_SUCCESS; - service_registration_pt reg = NULL; - celixThreadRwlock_writeLock(&ref->lock); - reg = ref->registration; - ref->registration = NULL; - celixThreadRwlock_unlock(&ref->lock); - - if (reg != NULL) { - serviceRegistration_release(reg); - } - return status; -} - -celix_status_t serviceReference_isValid(service_reference_pt ref, bool *result) { - celixThreadRwlock_readLock(&ref->lock); - (*result) = ref->registration != NULL; - celixThreadRwlock_unlock(&ref->lock); - return CELIX_SUCCESS; -} - -bool serviceReference_isAssignableTo(service_reference_pt reference __attribute__((unused)), bundle_pt requester __attribute__((unused)), const char* serviceName __attribute__((unused))) { - bool allow = true; - - /*NOTE for now always true. It would be nice to be able to do somechecks if the services are really assignable. - */ - - return allow; -} - -celix_status_t serviceReference_equals(service_reference_pt reference, service_reference_pt compareTo, bool *equal) { - celix_status_t status = CELIX_SUCCESS; - if (reference != NULL && compareTo != NULL) { - service_registration_pt reg1; - service_registration_pt reg2; - serviceReference_getServiceRegistration(reference, ®1); - serviceReference_getServiceRegistration(compareTo, ®2); - *equal = (reg1 == reg2); - } else { - status = CELIX_ILLEGAL_ARGUMENT; - *equal = false; - } - return status; -} - -int serviceReference_equals2(const void* reference1, const void* reference2) { - bool equal; - serviceReference_equals((service_reference_pt)reference1, (service_reference_pt)reference2, &equal); - return equal; -} - -celix_status_t serviceReference_compareTo(service_reference_pt reference, service_reference_pt compareTo, int *compare) { - celix_status_t status = CELIX_SUCCESS; - - long id, other_id; - const char* id_str; - const char* other_id_str; - serviceReference_getProperty(reference, (char *) OSGI_FRAMEWORK_SERVICE_ID, &id_str); - serviceReference_getProperty(compareTo, (char *) OSGI_FRAMEWORK_SERVICE_ID, &other_id_str); - - id = atol(id_str); - other_id = atol(other_id_str); - - - long rank, other_rank; - const char *rank_str; - const char* other_rank_str; - serviceReference_getProperty(reference, OSGI_FRAMEWORK_SERVICE_RANKING, &rank_str); - serviceReference_getProperty(compareTo, OSGI_FRAMEWORK_SERVICE_RANKING, &other_rank_str); - - rank = rank_str == NULL ? 0 : atol(rank_str); - other_rank = other_rank_str == NULL ? 0 : atol(other_rank_str); - - *compare = utils_compareServiceIdsAndRanking(id, rank, other_id, other_rank); - - return status; -} - -unsigned int serviceReference_hashCode(const void *referenceP) { - service_reference_pt ref = (service_reference_pt)referenceP; - bundle_pt bundle = NULL; - service_registration_pt reg = NULL; - - if (ref != NULL) { - celixThreadRwlock_readLock(&ref->lock); - bundle = ref->registrationBundle; - reg = ref->registration; - celixThreadRwlock_unlock(&ref->lock); - } - - - int prime = 31; - int result = 1; - result = prime * result; - - if (bundle != NULL && reg != NULL) { - intptr_t bundleA = (intptr_t) bundle; - intptr_t registrationA = (intptr_t) reg; - - result += bundleA + registrationA; - } - return result; -} - - -celix_status_t serviceReference_getUsingBundles(service_reference_pt ref, array_list_pt *out) { - celix_status_t status = CELIX_SUCCESS; - service_registration_pt reg = NULL; - registry_callback_t callback; - - callback.getUsingBundles = NULL; - - - celixThreadRwlock_readLock(&ref->lock); - reg = ref->registration; - if (reg != NULL) { - serviceRegistration_retain(reg); - callback.handle = ref->callback.handle; - callback.getUsingBundles = ref->callback.getUsingBundles; - } - celixThreadRwlock_unlock(&ref->lock); - - if (reg != NULL) { - if (callback.getUsingBundles != NULL) { - status = callback.getUsingBundles(callback.handle, reg, out); - } else { - fw_log(logger, OSGI_FRAMEWORK_LOG_ERROR, "getUsingBundles callback not set"); - status = CELIX_BUNDLE_EXCEPTION; - } - serviceRegistration_release(reg); - } - - return status; -} -
http://git-wip-us.apache.org/repos/asf/celix/blob/a1c30887/framework/private/src/service_registration.c ---------------------------------------------------------------------- diff --git a/framework/private/src/service_registration.c b/framework/private/src/service_registration.c deleted file mode 100644 index 5d23dbf..0000000 --- a/framework/private/src/service_registration.c +++ /dev/null @@ -1,291 +0,0 @@ -/** - *Licensed to the Apache Software Foundation (ASF) under one - *or more contributor license agreements. See the NOTICE file - *distributed with this work for additional information - *regarding copyright ownership. The ASF licenses this file - *to you under the Apache License, Version 2.0 (the - *"License"); you may not use this file except in compliance - *with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - *Unless required by applicable law or agreed to in writing, - *software distributed under the License is distributed on an - *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - *specific language governing permissions and limitations - *under the License. - */ -/* - * service_registration.c - * - * \date Aug 6, 2010 - * \author <a href="mailto:[email protected]">Apache Celix Project Team</a> - * \copyright Apache License, Version 2.0 - */ -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <assert.h> - -#include "service_registration_private.h" -#include "constants.h" - -static celix_status_t serviceRegistration_initializeProperties(service_registration_pt registration, properties_pt properties); -static celix_status_t serviceRegistration_createInternal(registry_callback_t callback, bundle_pt bundle, const char* serviceName, unsigned long serviceId, - const 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(registry_callback_t callback, bundle_pt bundle, const char* serviceName, unsigned long serviceId, const void * serviceObject, properties_pt dictionary) { - service_registration_pt registration = NULL; - serviceRegistration_createInternal(callback, bundle, serviceName, serviceId, serviceObject, dictionary, false, ®istration); - return registration; -} - -service_registration_pt serviceRegistration_createServiceFactory(registry_callback_t callback, bundle_pt bundle, const char* serviceName, unsigned long serviceId, const void * serviceObject, properties_pt dictionary) { - service_registration_pt registration = NULL; - serviceRegistration_createInternal(callback, bundle, serviceName, serviceId, serviceObject, dictionary, true, ®istration); - return registration; -} - -static celix_status_t serviceRegistration_createInternal(registry_callback_t callback, bundle_pt bundle, const char* serviceName, unsigned long serviceId, - const void * serviceObject, properties_pt dictionary, bool isFactory, service_registration_pt *out) { - celix_status_t status = CELIX_SUCCESS; - - service_registration_pt reg = calloc(1, sizeof(*reg)); - if (reg) { - reg->callback = callback; - reg->services = NULL; - reg->nrOfServices = 0; - reg->isServiceFactory = isFactory; - reg->className = strndup(serviceName, 1024*10); - reg->bundle = bundle; - reg->refCount = 1; - - reg->serviceId = serviceId; - reg->svcObj = serviceObject; - if (isFactory) { - reg->serviceFactory = (service_factory_pt) reg->svcObj; - } else { - reg->serviceFactory = NULL; - } - - reg->isUnregistering = false; - celixThreadRwlock_create(®->lock, NULL); - - celixThreadRwlock_writeLock(®->lock); - serviceRegistration_initializeProperties(reg, dictionary); - celixThreadRwlock_unlock(®->lock); - - } else { - status = CELIX_ENOMEM; - } - - if (status == CELIX_SUCCESS) { - *out = reg; - } - - return status; -} - -void serviceRegistration_retain(service_registration_pt registration) { - celixThreadRwlock_writeLock(®istration->lock); - registration->refCount += 1; - celixThreadRwlock_unlock(®istration->lock); -} - -void serviceRegistration_release(service_registration_pt registration) { - celixThreadRwlock_writeLock(®istration->lock); - assert(registration->refCount > 0); - registration->refCount -= 1; - if (registration->refCount == 0) { - serviceRegistration_destroy(registration); - } else { - celixThreadRwlock_unlock(®istration->lock); - } -} - -static celix_status_t serviceRegistration_destroy(service_registration_pt registration) { - //fw_log(logger, OSGI_FRAMEWORK_LOG_DEBUG, "Destroying service registration %p\n", registration); - free(registration->className); - registration->className = NULL; - - registration->callback.unregister = NULL; - - properties_destroy(registration->properties); - celixThreadRwlock_unlock(®istration->lock); - celixThreadRwlock_destroy(®istration->lock); - free(registration); - - return CELIX_SUCCESS; -} - -static celix_status_t serviceRegistration_initializeProperties(service_registration_pt registration, properties_pt dictionary) { - char sId[32]; - - if (dictionary == NULL) { - dictionary = properties_create(); - } - - - snprintf(sId, 32, "%lu", 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); - } - - registration->properties = dictionary; - - return CELIX_SUCCESS; -} - -void serviceRegistration_invalidate(service_registration_pt registration) { - celixThreadRwlock_writeLock(®istration->lock); - registration->svcObj = NULL; - celixThreadRwlock_unlock(®istration->lock); -} - -bool serviceRegistration_isValid(service_registration_pt registration) { - bool isValid; - if (registration != NULL) { - celixThreadRwlock_readLock(®istration->lock); - isValid = registration->svcObj != NULL; - celixThreadRwlock_unlock(®istration->lock); - } else { - isValid = false; - } - return isValid; -} - -celix_status_t serviceRegistration_unregister(service_registration_pt registration) { - celix_status_t status = CELIX_SUCCESS; - - bool notValidOrUnregistering; - celixThreadRwlock_readLock(®istration->lock); - notValidOrUnregistering = !serviceRegistration_isValid(registration) || registration->isUnregistering; - celixThreadRwlock_unlock(®istration->lock); - - registry_callback_t callback; - callback.unregister = NULL; - bundle_pt bundle = NULL; - - if (notValidOrUnregistering) { - status = CELIX_ILLEGAL_STATE; - } else { - celixThreadRwlock_writeLock(®istration->lock); - registration->isUnregistering = true; - bundle = registration->bundle; - callback = registration->callback; - celixThreadRwlock_unlock(®istration->lock); - } - - if (status == CELIX_SUCCESS && callback.unregister != NULL) { - callback.unregister(callback.handle, bundle, registration); - } - - framework_logIfError(logger, status, NULL, "Cannot unregister service registration"); - - return status; -} - -celix_status_t serviceRegistration_getService(service_registration_pt registration, bundle_pt bundle, const void** service) { - int status = CELIX_SUCCESS; - celixThreadRwlock_readLock(®istration->lock); - if (registration->isServiceFactory) { - service_factory_pt factory = (void*) registration->serviceFactory; - /*NOTE the service argument of the service_factory should be const void**. - To ensure backwards compatability a cast is made instead. - */ - status = factory->getService(factory->handle, bundle, registration, (void**) service); - } else { - (*service) = registration->svcObj; - } - celixThreadRwlock_unlock(®istration->lock); - return status; -} - -celix_status_t serviceRegistration_ungetService(service_registration_pt registration, bundle_pt bundle, const void** service) { - celixThreadRwlock_readLock(®istration->lock); - if (registration->isServiceFactory) { - service_factory_pt factory = (void*) registration->serviceFactory; - /*NOTE the service argument of the service_factory should be const void**. - To ensure backwards compatability a cast is made instead. - */ - factory->ungetService(factory->handle, bundle, registration, (void**) 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) { - celixThreadRwlock_readLock(®istration->lock); - *properties = registration->properties; - celixThreadRwlock_unlock(®istration->lock); - } else { - status = CELIX_ILLEGAL_ARGUMENT; - } - - framework_logIfError(logger, status, NULL, "Cannot get registration properties"); - - return status; -} - -celix_status_t serviceRegistration_setProperties(service_registration_pt registration, properties_pt properties) { - celix_status_t status; - - properties_pt oldProperties = NULL; - registry_callback_t callback; - - celixThreadRwlock_writeLock(®istration->lock); - oldProperties = registration->properties; - status = serviceRegistration_initializeProperties(registration, properties); - callback = registration->callback; - celixThreadRwlock_unlock(®istration->lock); - - if (status == CELIX_SUCCESS && callback.modified != NULL) { - callback.modified(callback.handle, registration, oldProperties); - } - - return status; -} - - -celix_status_t serviceRegistration_getBundle(service_registration_pt registration, bundle_pt *bundle) { - celix_status_t status = CELIX_SUCCESS; - if (registration == NULL) { - return CELIX_ILLEGAL_ARGUMENT; - } - - if (registration != NULL && *bundle == NULL) { - celixThreadRwlock_readLock(®istration->lock); - *bundle = registration->bundle; - celixThreadRwlock_unlock(®istration->lock); - } else { - status = CELIX_ILLEGAL_ARGUMENT; - } - - framework_logIfError(logger, status, NULL, "Cannot get bundle"); - - return status; -} - -celix_status_t serviceRegistration_getServiceName(service_registration_pt registration, const char **serviceName) { - celix_status_t status = CELIX_SUCCESS; - - if (registration != NULL && *serviceName == NULL) { - celixThreadRwlock_readLock(®istration->lock); - *serviceName = registration->className; - celixThreadRwlock_unlock(®istration->lock); - } else { - status = CELIX_ILLEGAL_ARGUMENT; - } - - - framework_logIfError(logger, status, NULL, "Cannot get service name"); - - return status; -} http://git-wip-us.apache.org/repos/asf/celix/blob/a1c30887/framework/private/src/service_registry.c ---------------------------------------------------------------------- diff --git a/framework/private/src/service_registry.c b/framework/private/src/service_registry.c deleted file mode 100644 index d27cc32..0000000 --- a/framework/private/src/service_registry.c +++ /dev/null @@ -1,800 +0,0 @@ -/** - *Licensed to the Apache Software Foundation (ASF) under one - *or more contributor license agreements. See the NOTICE file - *distributed with this work for additional information - *regarding copyright ownership. The ASF licenses this file - *to you under the Apache License, Version 2.0 (the - *"License"); you may not use this file except in compliance - *with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - *Unless required by applicable law or agreed to in writing, - *software distributed under the License is distributed on an - *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - *specific language governing permissions and limitations - *under the License. - */ -/* - * service_registry.c - * - * \date Aug 6, 2010 - * \author <a href="mailto:[email protected]">Apache Celix Project Team</a> - * \copyright Apache License, Version 2.0 - */ -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <assert.h> - -#include "service_registry_private.h" -#include "service_registration_private.h" -#include "listener_hook_service.h" -#include "constants.h" -#include "service_reference_private.h" -#include "framework_private.h" - -#ifdef DEBUG -#define CHECK_DELETED_REFERENCES true -#else -#define CHECK_DELETED_REFERENCES false -#endif - -static celix_status_t serviceRegistry_registerServiceInternal(service_registry_pt registry, bundle_pt bundle, const char* serviceName, const void * serviceObject, properties_pt dictionary, bool isFactory, service_registration_pt *registration); -static celix_status_t serviceRegistry_addHooks(service_registry_pt registry, const char* serviceName, const void *serviceObject, service_registration_pt registration); -static celix_status_t serviceRegistry_removeHook(service_registry_pt registry, service_registration_pt registration); -static void serviceRegistry_logWarningServiceReferenceUsageCount(service_registry_pt registry, bundle_pt bundle, service_reference_pt ref, size_t usageCount, size_t refCount); -static void serviceRegistry_logWarningServiceRegistration(service_registry_pt registry, service_registration_pt reg); -static celix_status_t serviceRegistry_checkReference(service_registry_pt registry, service_reference_pt ref, - reference_status_t *refStatus); -static void serviceRegistry_logIllegalReference(service_registry_pt registry, service_reference_pt reference, - reference_status_t refStatus); -static celix_status_t serviceRegistry_setReferenceStatus(service_registry_pt registry, service_reference_pt reference, - bool deleted); -static celix_status_t serviceRegistry_getUsingBundles(service_registry_pt registry, service_registration_pt reg, array_list_pt *bundles); -static celix_status_t serviceRegistry_getServiceReference_internal(service_registry_pt registry, bundle_pt owner, service_registration_pt registration, service_reference_pt *out); - -celix_status_t serviceRegistry_create(framework_pt framework, serviceChanged_function_pt serviceChanged, service_registry_pt *out) { - celix_status_t status; - - service_registry_pt reg = calloc(1, sizeof(*reg)); - if (reg == NULL) { - status = CELIX_ENOMEM; - } else { - - reg->callback.handle = reg; - reg->callback.getUsingBundles = (void *)serviceRegistry_getUsingBundles; - reg->callback.unregister = (void *) serviceRegistry_unregisterService; - reg->callback.modified = (void *) serviceRegistry_servicePropertiesModified; - - reg->serviceChanged = serviceChanged; - reg->serviceRegistrations = hashMap_create(NULL, NULL, NULL, NULL); - reg->framework = framework; - reg->currentServiceId = 1UL; - reg->serviceReferences = hashMap_create(NULL, NULL, NULL, NULL); - - reg->checkDeletedReferences = CHECK_DELETED_REFERENCES; - reg->deletedServiceReferences = hashMap_create(NULL, NULL, NULL, NULL); - - arrayList_create(®->listenerHooks); - - status = celixThreadRwlock_create(®->lock, NULL); - } - - if (status == CELIX_SUCCESS) { - *out = reg; - } else { - framework_logIfError(logger, status, NULL, "Cannot create service registry"); - } - - return status; -} - -celix_status_t serviceRegistry_destroy(service_registry_pt registry) { - celixThreadRwlock_writeLock(®istry->lock); - - //destroy service registration map - int size = hashMap_size(registry->serviceRegistrations); - assert(size == 0); - hashMap_destroy(registry->serviceRegistrations, false, false); - - //destroy service references (double) map); - //FIXME. The framework bundle does not (yet) call clearReferences, as result the size could be > 0 for test code. - //size = hashMap_size(registry->serviceReferences); - //assert(size == 0); - hashMap_destroy(registry->serviceReferences, false, false); - - //destroy listener hooks - size = arrayList_size(registry->listenerHooks); - if (size == 0) - arrayList_destroy(registry->listenerHooks); - - hashMap_destroy(registry->deletedServiceReferences, false, false); - - free(registry); - - return CELIX_SUCCESS; -} - -celix_status_t serviceRegistry_getRegisteredServices(service_registry_pt registry, bundle_pt bundle, array_list_pt *services) { - celix_status_t status = CELIX_SUCCESS; - - celixThreadRwlock_writeLock(®istry->lock); - - array_list_pt regs = (array_list_pt) hashMap_get(registry->serviceRegistrations, bundle); - if (regs != NULL) { - unsigned int i; - arrayList_create(services); - - for (i = 0; i < arrayList_size(regs); i++) { - service_registration_pt reg = arrayList_get(regs, i); - if (serviceRegistration_isValid(reg)) { - service_reference_pt reference = NULL; - status = serviceRegistry_getServiceReference_internal(registry, bundle, reg, &reference); - if (status == CELIX_SUCCESS) { - arrayList_add(*services, reference); - } - } - } - } - - celixThreadRwlock_unlock(®istry->lock); - - framework_logIfError(logger, status, NULL, "Cannot get registered services"); - - return status; -} - -celix_status_t serviceRegistry_registerService(service_registry_pt registry, bundle_pt bundle, const char* serviceName, const void* serviceObject, properties_pt dictionary, service_registration_pt *registration) { - return serviceRegistry_registerServiceInternal(registry, bundle, serviceName, serviceObject, dictionary, false, registration); -} - -celix_status_t serviceRegistry_registerServiceFactory(service_registry_pt registry, bundle_pt bundle, const char* serviceName, service_factory_pt factory, properties_pt dictionary, service_registration_pt *registration) { - return serviceRegistry_registerServiceInternal(registry, bundle, serviceName, (const void *) factory, dictionary, true, registration); -} - -static celix_status_t serviceRegistry_registerServiceInternal(service_registry_pt registry, bundle_pt bundle, const char* serviceName, const void* serviceObject, properties_pt dictionary, bool isFactory, service_registration_pt *registration) { - array_list_pt regs; - - if (isFactory) { - *registration = serviceRegistration_createServiceFactory(registry->callback, bundle, serviceName, ++registry->currentServiceId, serviceObject, dictionary); - } else { - *registration = serviceRegistration_create(registry->callback, bundle, serviceName, ++registry->currentServiceId, serviceObject, dictionary); - } - - //long id; - //bundle_getBundleId(bundle, &id); - //fprintf(stderr, "REG: Registering service '%s' for bundle id %li with reg pointer %p\n", serviceName, id, *registration); - - - serviceRegistry_addHooks(registry, serviceName, serviceObject, *registration); - - celixThreadRwlock_writeLock(®istry->lock); - regs = (array_list_pt) hashMap_get(registry->serviceRegistrations, bundle); - if (regs == NULL) { - regs = NULL; - arrayList_create(®s); - hashMap_put(registry->serviceRegistrations, bundle, regs); - } - arrayList_add(regs, *registration); - celixThreadRwlock_unlock(®istry->lock); - - if (registry->serviceChanged != NULL) { - registry->serviceChanged(registry->framework, OSGI_FRAMEWORK_SERVICE_EVENT_REGISTERED, *registration, NULL); - } - - return CELIX_SUCCESS; -} - -celix_status_t serviceRegistry_unregisterService(service_registry_pt registry, bundle_pt bundle, service_registration_pt registration) { - // array_list_t clients; - array_list_pt regs; - - //fprintf(stderr, "REG: Unregistering service registration with pointer %p\n", registration); - - serviceRegistry_removeHook(registry, registration); - - celixThreadRwlock_writeLock(®istry->lock); - regs = (array_list_pt) hashMap_get(registry->serviceRegistrations, bundle); - if (regs != NULL) { - arrayList_removeElement(regs, registration); - int size = arrayList_size(regs); - if (size == 0) { - arrayList_destroy(regs); - hashMap_remove(registry->serviceRegistrations, bundle); - } - } - celixThreadRwlock_unlock(®istry->lock); - - if (registry->serviceChanged != NULL) { - registry->serviceChanged(registry->framework, OSGI_FRAMEWORK_SERVICE_EVENT_UNREGISTERING, registration, NULL); - } - - - celixThreadRwlock_readLock(®istry->lock); - //invalidate service references - hash_map_iterator_pt iter = hashMapIterator_create(registry->serviceReferences); - while (hashMapIterator_hasNext(iter)) { - hash_map_pt refsMap = hashMapIterator_nextValue(iter); - service_reference_pt ref = refsMap != NULL ? - hashMap_get(refsMap, (void*)registration->serviceId) : NULL; - if (ref != NULL) { - serviceReference_invalidate(ref); - } - } - hashMapIterator_destroy(iter); - celixThreadRwlock_unlock(®istry->lock); - - serviceRegistration_invalidate(registration); - serviceRegistration_release(registration); - - return CELIX_SUCCESS; -} - -celix_status_t serviceRegistry_clearServiceRegistrations(service_registry_pt registry, bundle_pt bundle) { - celix_status_t status = CELIX_SUCCESS; - array_list_pt registrations = NULL; - bool registrationsLeft; - - celixThreadRwlock_writeLock(®istry->lock); - registrations = hashMap_get(registry->serviceRegistrations, bundle); - registrationsLeft = (registrations != NULL); - if (registrationsLeft) { - registrationsLeft = (arrayList_size(registrations) > 0); - } - celixThreadRwlock_unlock(®istry->lock); - - while (registrationsLeft) { - service_registration_pt reg = arrayList_get(registrations, 0); - - serviceRegistry_logWarningServiceRegistration(registry, reg); - - if (serviceRegistration_isValid(reg)) { - serviceRegistration_unregister(reg); - } - else { - arrayList_remove(registrations, 0); - } - - // not removed by last unregister call? - celixThreadRwlock_writeLock(®istry->lock); - registrations = hashMap_get(registry->serviceRegistrations, bundle); - registrationsLeft = (registrations != NULL); - if (registrationsLeft) { - registrationsLeft = (arrayList_size(registrations) > 0); - } - celixThreadRwlock_unlock(®istry->lock); - } - - return status; -} - -static void serviceRegistry_logWarningServiceRegistration(service_registry_pt registry __attribute__((unused)), service_registration_pt reg) { - const char *servName = NULL; - serviceRegistration_getServiceName(reg, &servName); - fw_log(logger, OSGI_FRAMEWORK_LOG_WARNING, "Dangling service registration for service %s. Look for missing serviceRegistration_unregister calls.", servName); -} - -celix_status_t serviceRegistry_getServiceReference(service_registry_pt registry, bundle_pt owner, - service_registration_pt registration, service_reference_pt *out) { - celix_status_t status = CELIX_SUCCESS; - - if(celixThreadRwlock_writeLock(®istry->lock) == CELIX_SUCCESS) { - status = serviceRegistry_getServiceReference_internal(registry, owner, registration, out); - celixThreadRwlock_unlock(®istry->lock); - } - - return status; -} - -static celix_status_t serviceRegistry_getServiceReference_internal(service_registry_pt registry, bundle_pt owner, - service_registration_pt registration, service_reference_pt *out) { - //only call after locked registry RWlock - celix_status_t status = CELIX_SUCCESS; - bundle_pt bundle = NULL; - service_reference_pt ref = NULL; - hash_map_pt references = NULL; - - references = hashMap_get(registry->serviceReferences, owner); - if (references == NULL) { - references = hashMap_create(NULL, NULL, NULL, NULL); - hashMap_put(registry->serviceReferences, owner, references); - } - - ref = hashMap_get(references, (void*)registration->serviceId); - - if (ref == NULL) { - status = serviceRegistration_getBundle(registration, &bundle); - if (status == CELIX_SUCCESS) { - status = serviceReference_create(registry->callback, owner, registration, &ref); - } - if (status == CELIX_SUCCESS) { - hashMap_put(references, (void*)registration->serviceId, ref); - hashMap_put(registry->deletedServiceReferences, ref, (void *)false); - } - } else { - serviceReference_retain(ref); - } - - if (status == CELIX_SUCCESS) { - *out = ref; - } - - framework_logIfError(logger, status, NULL, "Cannot create service reference"); - - - return status; -} - -celix_status_t serviceRegistry_getServiceReferences(service_registry_pt registry, bundle_pt owner, const char *serviceName, filter_pt filter, array_list_pt *out) { - celix_status_t status; - hash_map_iterator_pt iterator; - array_list_pt references = NULL; - array_list_pt matchingRegistrations = NULL; - bool matchResult; - - status = arrayList_create(&references); - status = CELIX_DO_IF(status, arrayList_create(&matchingRegistrations)); - - celixThreadRwlock_readLock(®istry->lock); - iterator = hashMapIterator_create(registry->serviceRegistrations); - while (status == CELIX_SUCCESS && hashMapIterator_hasNext(iterator)) { - array_list_pt regs = (array_list_pt) hashMapIterator_nextValue(iterator); - unsigned int regIdx; - for (regIdx = 0; (regs != NULL) && regIdx < arrayList_size(regs); regIdx++) { - service_registration_pt registration = (service_registration_pt) arrayList_get(regs, regIdx); - properties_pt props = NULL; - - status = serviceRegistration_getProperties(registration, &props); - if (status == CELIX_SUCCESS) { - bool matched = false; - matchResult = false; - if (filter != NULL) { - filter_match(filter, props, &matchResult); - } - if ((serviceName == NULL) && ((filter == NULL) || matchResult)) { - matched = true; - } else if (serviceName != NULL) { - const char *className = NULL; - matchResult = false; - serviceRegistration_getServiceName(registration, &className); - if (filter != NULL) { - filter_match(filter, props, &matchResult); - } - if ((strcmp(className, serviceName) == 0) && ((filter == NULL) || matchResult)) { - matched = true; - } - } - if (matched) { - if (serviceRegistration_isValid(registration)) { - serviceRegistration_retain(registration); - arrayList_add(matchingRegistrations, registration); - } - } - } - } - } - celixThreadRwlock_unlock(®istry->lock); - hashMapIterator_destroy(iterator); - - if (status == CELIX_SUCCESS) { - unsigned int i; - unsigned int size = arrayList_size(matchingRegistrations); - - for (i = 0; i < size; i += 1) { - service_registration_pt reg = arrayList_get(matchingRegistrations, i); - service_reference_pt reference = NULL; - celix_status_t subStatus = serviceRegistry_getServiceReference(registry, owner, reg, &reference); - if (subStatus == CELIX_SUCCESS) { - arrayList_add(references, reference); - } else { - status = CELIX_BUNDLE_EXCEPTION; - } - serviceRegistration_release(reg); - } - } - - if(matchingRegistrations != NULL){ - arrayList_destroy(matchingRegistrations); - } - - if (status == CELIX_SUCCESS) { - *out = references; - } else { - //TODO ungetServiceRefs - arrayList_destroy(references); - framework_logIfError(logger, status, NULL, "Cannot get service references"); - } - - return status; -} - -celix_status_t serviceRegistry_retainServiceReference(service_registry_pt registry, bundle_pt bundle, service_reference_pt reference) { - celix_status_t status = CELIX_SUCCESS; - reference_status_t refStatus; - bundle_pt refBundle = NULL; - - celixThreadRwlock_writeLock(®istry->lock); - serviceRegistry_checkReference(registry, reference, &refStatus); - if (refStatus == REF_ACTIVE) { - serviceReference_getOwner(reference, &refBundle); - if (refBundle == bundle) { - serviceReference_retain(reference); - } else { - status = CELIX_ILLEGAL_ARGUMENT; - fw_log(logger, OSGI_FRAMEWORK_LOG_ERROR, "cannot retain a service reference from an other bundle (in ref %p) (provided %p).", refBundle, bundle); - } - } else { - serviceRegistry_logIllegalReference(registry, reference, refStatus); - } - celixThreadRwlock_unlock(®istry->lock); - - return status; -} - - -celix_status_t serviceRegistry_ungetServiceReference(service_registry_pt registry, bundle_pt bundle, service_reference_pt reference) { - celix_status_t status = CELIX_SUCCESS; - bool destroyed = false; - size_t count = 0; - reference_status_t refStatus; - - celixThreadRwlock_writeLock(®istry->lock); - serviceRegistry_checkReference(registry, reference, &refStatus); - if (refStatus == REF_ACTIVE) { - serviceReference_getUsageCount(reference, &count); - serviceReference_release(reference, &destroyed); - if (destroyed) { - - if (count > 0) { - serviceRegistry_logWarningServiceReferenceUsageCount(registry, bundle, reference, count, 0); - } - - hash_map_pt refsMap = hashMap_get(registry->serviceReferences, bundle); - - unsigned long refId = 0UL; - service_reference_pt ref = NULL; - hash_map_iterator_pt iter = hashMapIterator_create(refsMap); - while (hashMapIterator_hasNext(iter)) { - hash_map_entry_pt entry = hashMapIterator_nextEntry(iter); - refId = (unsigned long)hashMapEntry_getKey(entry); //note could be invalid e.g. freed - ref = hashMapEntry_getValue(entry); - - if (ref == reference) { - break; - } else { - ref = NULL; - refId = 0UL; - } - } - hashMapIterator_destroy(iter); - - if (ref != NULL) { - hashMap_remove(refsMap, (void*)refId); - int size = hashMap_size(refsMap); - if (size == 0) { - hashMap_destroy(refsMap, false, false); - hashMap_remove(registry->serviceReferences, bundle); - } - serviceRegistry_setReferenceStatus(registry, reference, true); - } else { - fw_log(logger, OSGI_FRAMEWORK_LOG_ERROR, "Cannot find reference %p in serviceReferences map", - reference); - } - } - } else { - serviceRegistry_logIllegalReference(registry, reference, refStatus); - } - celixThreadRwlock_unlock(®istry->lock); - - return status; -} - -static celix_status_t serviceRegistry_setReferenceStatus(service_registry_pt registry, service_reference_pt reference, - bool deleted) { - //precondition write locked on registry->lock - if (registry->checkDeletedReferences) { - hashMap_put(registry->deletedServiceReferences, reference, (void *) deleted); - } - return CELIX_SUCCESS; -} - -static void serviceRegistry_logIllegalReference(service_registry_pt registry __attribute__((unused)), service_reference_pt reference, - reference_status_t refStatus) { - fw_log(logger, OSGI_FRAMEWORK_LOG_ERROR, - "Error handling service reference %p, status is %i",reference, refStatus); -} - -static celix_status_t serviceRegistry_checkReference(service_registry_pt registry, service_reference_pt ref, - reference_status_t *out) { - //precondition read or write locked on registry->lock - celix_status_t status = CELIX_SUCCESS; - - if (registry->checkDeletedReferences) { - reference_status_t refStatus = REF_UNKNOWN; - - if (hashMap_containsKey(registry->deletedServiceReferences, ref)) { - bool deleted = (bool) hashMap_get(registry->deletedServiceReferences, ref); - refStatus = deleted ? REF_DELETED : REF_ACTIVE; - } - - *out = refStatus; - } else { - *out = REF_ACTIVE; - } - - return status; -} - -static void serviceRegistry_logWarningServiceReferenceUsageCount(service_registry_pt registry __attribute__((unused)), bundle_pt bundle, service_reference_pt ref, size_t usageCount, size_t refCount) { - if (usageCount > 0) { - fw_log(logger, OSGI_FRAMEWORK_LOG_WARNING, "Service Reference destroyed with usage count is %zu, expected 0. Look for missing bundleContext_ungetService calls.", usageCount); - } - if (refCount > 0) { - fw_log(logger, OSGI_FRAMEWORK_LOG_WARNING, "Dangling service reference. Reference count is %zu, expected 1. Look for missing bundleContext_ungetServiceReference calls.", refCount); - } - - if(usageCount > 0 || refCount > 0) { - module_pt module_ptr = NULL; - bundle_getCurrentModule(bundle, &module_ptr); - const char* bundle_name = NULL; - module_getSymbolicName(module_ptr, &bundle_name); - - const char* service_name = "unknown"; - const char* bundle_provider_name = "unknown"; - if (refCount > 0 && ref != NULL) { - serviceReference_getProperty(ref, OSGI_FRAMEWORK_OBJECTCLASS, &service_name); - service_registration_pt reg = NULL; - bundle_pt bundle = NULL; - module_pt mod = NULL; - serviceReference_getServiceRegistration(ref, ®); - serviceRegistration_getBundle(reg, &bundle); - bundle_getCurrentModule(bundle, &mod); - module_getSymbolicName(mod, &bundle_provider_name); - } - - fw_log(logger, OSGI_FRAMEWORK_LOG_WARNING, "Previous Dangling service reference warnings caused by bundle '%s', for service '%s', provided by bundle '%s'", bundle_name, service_name, bundle_provider_name); - } -} - - -celix_status_t serviceRegistry_clearReferencesFor(service_registry_pt registry, bundle_pt bundle) { - celix_status_t status = CELIX_SUCCESS; - - celixThreadRwlock_writeLock(®istry->lock); - - hash_map_pt refsMap = hashMap_remove(registry->serviceReferences, bundle); - if (refsMap != NULL) { - hash_map_iterator_pt iter = hashMapIterator_create(refsMap); - while (hashMapIterator_hasNext(iter)) { - service_reference_pt ref = hashMapIterator_nextValue(iter); - size_t refCount; - size_t usageCount; - - serviceReference_getUsageCount(ref, &usageCount); - serviceReference_getReferenceCount(ref, &refCount); - serviceRegistry_logWarningServiceReferenceUsageCount(registry, bundle, ref, usageCount, refCount); - - while (usageCount > 0) { - serviceReference_decreaseUsage(ref, &usageCount); - } - - bool destroyed = false; - while (!destroyed) { - serviceReference_release(ref, &destroyed); - } - serviceRegistry_setReferenceStatus(registry, ref, true); - - } - hashMapIterator_destroy(iter); - hashMap_destroy(refsMap, false, false); - } - - celixThreadRwlock_unlock(®istry->lock); - - return status; -} - - -celix_status_t serviceRegistry_getServicesInUse(service_registry_pt registry, bundle_pt bundle, array_list_pt *out) { - - array_list_pt result = NULL; - arrayList_create(&result); - - //LOCK - celixThreadRwlock_readLock(®istry->lock); - - hash_map_pt refsMap = hashMap_get(registry->serviceReferences, bundle); - - if(refsMap) { - hash_map_iterator_pt iter = hashMapIterator_create(refsMap); - while (hashMapIterator_hasNext(iter)) { - service_reference_pt ref = hashMapIterator_nextValue(iter); - arrayList_add(result, ref); - } - hashMapIterator_destroy(iter); - } - - //UNLOCK - celixThreadRwlock_unlock(®istry->lock); - - *out = result; - - return CELIX_SUCCESS; -} - -celix_status_t serviceRegistry_getService(service_registry_pt registry, bundle_pt bundle, service_reference_pt reference, const void **out) { - celix_status_t status = CELIX_SUCCESS; - service_registration_pt registration = NULL; - size_t count = 0; - const void *service = NULL; - reference_status_t refStatus; - - - - celixThreadRwlock_readLock(®istry->lock); - serviceRegistry_checkReference(registry, reference, &refStatus); - if (refStatus == REF_ACTIVE) { - serviceReference_getServiceRegistration(reference, ®istration); - - if (serviceRegistration_isValid(registration)) { - serviceReference_increaseUsage(reference, &count); - if (count == 1) { - serviceRegistration_getService(registration, bundle, &service); - serviceReference_setService(reference, service); - } - - /* NOTE the out argument of sr_getService should be 'const void**' - To ensure backwards compatability a cast is made instead. - */ - serviceReference_getService(reference, (void **)out); - } else { - *out = NULL; //invalid service registration - } - } else { - serviceRegistry_logIllegalReference(registry, reference, refStatus); - status = CELIX_BUNDLE_EXCEPTION; - } - celixThreadRwlock_unlock(®istry->lock); - - return status; -} - -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; - const void *service = NULL; - size_t count = 0; - celix_status_t subStatus = CELIX_SUCCESS; - reference_status_t refStatus; - - celixThreadRwlock_readLock(®istry->lock); - serviceRegistry_checkReference(registry, reference, &refStatus); - celixThreadRwlock_unlock(®istry->lock); - - if (refStatus == REF_ACTIVE) { - subStatus = serviceReference_decreaseUsage(reference, &count); - if (count == 0) { - /*NOTE the argument service of sr_getService should be 'const void**' - TO ensure backwards compatability a cast is made instead. - */ - serviceReference_getService(reference, (void**)&service); - serviceReference_getServiceRegistration(reference, ®); - if (reg != NULL) { - serviceRegistration_ungetService(reg, bundle, &service); - } - } - } else { - serviceRegistry_logIllegalReference(registry, reference, refStatus); - status = CELIX_BUNDLE_EXCEPTION; - } - - if (result) { - *result = (subStatus == CELIX_SUCCESS); - } - - - return status; -} - -static celix_status_t serviceRegistry_addHooks(service_registry_pt registry, const char* serviceName, const void* serviceObject __attribute__((unused)), service_registration_pt registration) { - celix_status_t status = CELIX_SUCCESS; - - if (strcmp(OSGI_FRAMEWORK_LISTENER_HOOK_SERVICE_NAME, serviceName) == 0) { - celixThreadRwlock_writeLock(®istry->lock); - arrayList_add(registry->listenerHooks, registration); - celixThreadRwlock_unlock(®istry->lock); - } - - return status; -} - -static celix_status_t serviceRegistry_removeHook(service_registry_pt registry, service_registration_pt registration) { - celix_status_t status = CELIX_SUCCESS; - const char* serviceName = NULL; - - properties_pt props = NULL; - serviceRegistration_getProperties(registration, &props); - serviceName = properties_get(props, (char *) OSGI_FRAMEWORK_OBJECTCLASS); - if (strcmp(OSGI_FRAMEWORK_LISTENER_HOOK_SERVICE_NAME, serviceName) == 0) { - celixThreadRwlock_writeLock(®istry->lock); - arrayList_removeElement(registry->listenerHooks, registration); - celixThreadRwlock_unlock(®istry->lock); - } - - return status; -} - -celix_status_t serviceRegistry_getListenerHooks(service_registry_pt registry, bundle_pt owner, array_list_pt *out) { - celix_status_t status; - array_list_pt result; - - status = arrayList_create(&result); - if (status == CELIX_SUCCESS) { - unsigned int i; - unsigned size = arrayList_size(registry->listenerHooks); - - for (i = 0; i < size; i += 1) { - celixThreadRwlock_readLock(®istry->lock); - service_registration_pt registration = arrayList_get(registry->listenerHooks, i); - serviceRegistration_retain(registration); - celixThreadRwlock_unlock(®istry->lock); - - service_reference_pt reference = NULL; - serviceRegistry_getServiceReference(registry, owner, registration, &reference); - arrayList_add(result, reference); - serviceRegistration_release(registration); - } - } - - if (status == CELIX_SUCCESS) { - *out = result; - } else { - if (result != NULL) { - arrayList_destroy(result); - } - framework_logIfError(logger, status, NULL, "Cannot get listener hooks"); - } - - return status; -} - -celix_status_t serviceRegistry_servicePropertiesModified(service_registry_pt registry, service_registration_pt registration, properties_pt oldprops) { - if (registry->serviceChanged != NULL) { - registry->serviceChanged(registry->framework, OSGI_FRAMEWORK_SERVICE_EVENT_MODIFIED, registration, oldprops); - } - return CELIX_SUCCESS; -} - -static celix_status_t serviceRegistry_getUsingBundles(service_registry_pt registry, service_registration_pt registration, array_list_pt *out) { - celix_status_t status; - array_list_pt bundles = NULL; - hash_map_iterator_pt iter; - - status = arrayList_create(&bundles); - if (status == CELIX_SUCCESS) { - celixThreadRwlock_readLock(®istry->lock); - iter = hashMapIterator_create(registry->serviceReferences); - while (hashMapIterator_hasNext(iter)) { - hash_map_entry_pt entry = hashMapIterator_nextEntry(iter); - bundle_pt registrationUser = hashMapEntry_getKey(entry); - hash_map_pt regMap = hashMapEntry_getValue(entry); - if (hashMap_containsKey(regMap, (void*)registration->serviceId)) { - arrayList_add(bundles, registrationUser); - } - } - hashMapIterator_destroy(iter); - celixThreadRwlock_unlock(®istry->lock); - } - - if (status == CELIX_SUCCESS) { - *out = bundles; - } else { - if (bundles != NULL) { - arrayList_destroy(bundles); - } - } - - return status; -} http://git-wip-us.apache.org/repos/asf/celix/blob/a1c30887/framework/private/src/service_tracker.c ---------------------------------------------------------------------- diff --git a/framework/private/src/service_tracker.c b/framework/private/src/service_tracker.c deleted file mode 100644 index 2631058..0000000 --- a/framework/private/src/service_tracker.c +++ /dev/null @@ -1,449 +0,0 @@ -/** - *Licensed to the Apache Software Foundation (ASF) under one - *or more contributor license agreements. See the NOTICE file - *distributed with this work for additional information - *regarding copyright ownership. The ASF licenses this file - *to you under the Apache License, Version 2.0 (the - *"License"); you may not use this file except in compliance - *with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - *Unless required by applicable law or agreed to in writing, - *software distributed under the License is distributed on an - *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - *specific language governing permissions and limitations - *under the License. - */ -/* - * service_tracker.c - * - * \date Apr 20, 2010 - * \author <a href="mailto:[email protected]">Apache Celix Project Team</a> - * \copyright Apache License, Version 2.0 - */ -#include <stdlib.h> -#include <string.h> -#include <stdio.h> -#include <service_reference_private.h> -#include <framework_private.h> -#include <assert.h> - -#include "service_tracker_private.h" -#include "bundle_context.h" -#include "constants.h" -#include "service_reference.h" -#include "celix_log.h" - -static celix_status_t serviceTracker_invokeAddingService(service_tracker_pt tracker, service_reference_pt reference, - void **service); -static celix_status_t serviceTracker_track(service_tracker_pt tracker, service_reference_pt reference, service_event_pt event); -static celix_status_t serviceTracker_untrack(service_tracker_pt tracker, service_reference_pt reference, service_event_pt event); -static celix_status_t serviceTracker_invokeAddService(service_tracker_pt tracker, service_reference_pt ref, void *service); -static celix_status_t serviceTracker_invokeModifiedService(service_tracker_pt tracker, service_reference_pt ref, void *service); - -static celix_status_t serviceTracker_invokeRemovingService(service_tracker_pt tracker, service_reference_pt ref, - void *service); - -celix_status_t serviceTracker_create(bundle_context_pt context, const char * service, service_tracker_customizer_pt customizer, service_tracker_pt *tracker) { - celix_status_t status = CELIX_SUCCESS; - - if (service == NULL || *tracker != NULL) { - status = CELIX_ILLEGAL_ARGUMENT; - } else { - if (status == CELIX_SUCCESS) { - char filter[512]; - snprintf(filter, sizeof(filter), "(%s=%s)", OSGI_FRAMEWORK_OBJECTCLASS, service); - serviceTracker_createWithFilter(context, filter, customizer, tracker); - } - } - - framework_logIfError(logger, status, NULL, "Cannot create service tracker"); - - return status; -} - -celix_status_t serviceTracker_createWithFilter(bundle_context_pt context, const char * filter, service_tracker_customizer_pt customizer, service_tracker_pt *tracker) { - celix_status_t status = CELIX_SUCCESS; - - *tracker = (service_tracker_pt) malloc(sizeof(**tracker)); - if (!*tracker) { - status = CELIX_ENOMEM; - } else { - (*tracker)->context = context; - (*tracker)->filter = strdup(filter); - - (*tracker)->tracker = *tracker; - celixThreadRwlock_create(&(*tracker)->lock, NULL); - (*tracker)->trackedServices = NULL; - arrayList_create(&(*tracker)->trackedServices); - (*tracker)->customizer = customizer; - (*tracker)->listener = NULL; - } - - framework_logIfError(logger, status, NULL, "Cannot create service tracker [filter=%s]", filter); - - return status; -} - -celix_status_t serviceTracker_destroy(service_tracker_pt tracker) { - if (tracker->listener != NULL) { - bundleContext_removeServiceListener(tracker->context, tracker->listener); - } - if (tracker->customizer != NULL) { - serviceTrackerCustomizer_destroy(tracker->customizer); - } - - celixThreadRwlock_writeLock(&tracker->lock); - arrayList_destroy(tracker->trackedServices); - celixThreadRwlock_unlock(&tracker->lock); - - - if (tracker->listener != NULL) { - free (tracker->listener); - } - - celixThreadRwlock_destroy(&tracker->lock); - - free(tracker->filter); - free(tracker); - - return CELIX_SUCCESS; -} - -celix_status_t serviceTracker_open(service_tracker_pt tracker) { - service_listener_pt listener; - array_list_pt initial = NULL; - celix_status_t status = CELIX_SUCCESS; - listener = (service_listener_pt) malloc(sizeof(*listener)); - - status = bundleContext_getServiceReferences(tracker->context, NULL, tracker->filter, &initial); //REF COUNT to 1 - if (status == CELIX_SUCCESS && listener != NULL) { - service_reference_pt initial_reference; - unsigned int i; - - listener->handle = tracker; - listener->serviceChanged = (void *) serviceTracker_serviceChanged; - status = bundleContext_addServiceListener(tracker->context, listener, tracker->filter); - if (status == CELIX_SUCCESS) { - tracker->listener = listener; - - for (i = 0; i < arrayList_size(initial); i++) { - initial_reference = (service_reference_pt) arrayList_get(initial, i); - serviceTracker_track(tracker, initial_reference, NULL); //REF COUNT to 2 - bundleContext_ungetServiceReference(tracker->context, initial_reference); //REF COUNT to 1 - } - - arrayList_destroy(initial); - - initial = NULL; - } - } - - if(status != CELIX_SUCCESS && listener != NULL){ - free(listener); - } - - framework_logIfError(logger, status, NULL, "Cannot open tracker"); - - return status; -} - -celix_status_t serviceTracker_close(service_tracker_pt tracker) { - celix_status_t status = CELIX_SUCCESS; - - if (status == CELIX_SUCCESS) { - array_list_pt refs = serviceTracker_getServiceReferences(tracker); - if (refs != NULL) { - unsigned int i; - for (i = 0; i < arrayList_size(refs); i++) { - service_reference_pt ref = (service_reference_pt) arrayList_get(refs, i); - status = serviceTracker_untrack(tracker, ref, NULL); - } - } - arrayList_destroy(refs); - } - if (status == CELIX_SUCCESS) { - status = bundleContext_removeServiceListener(tracker->context, tracker->listener); - if(status == CELIX_SUCCESS) { - free(tracker->listener); - tracker->listener = NULL; - } - } - framework_logIfError(logger, status, NULL, "Cannot close tracker"); - - return status; -} - -service_reference_pt serviceTracker_getServiceReference(service_tracker_pt tracker) { - tracked_pt tracked; - service_reference_pt result = NULL; - unsigned int i; - - celixThreadRwlock_readLock(&tracker->lock); - for (i = 0; i < arrayList_size(tracker->trackedServices); i++) { - tracked = (tracked_pt) arrayList_get(tracker->trackedServices, i); - result = tracked->reference; - break; - } - celixThreadRwlock_unlock(&tracker->lock); - - return result; -} - -array_list_pt serviceTracker_getServiceReferences(service_tracker_pt tracker) { - tracked_pt tracked; - unsigned int i; - array_list_pt references = NULL; - arrayList_create(&references); - - celixThreadRwlock_readLock(&tracker->lock); - for (i = 0; i < arrayList_size(tracker->trackedServices); i++) { - tracked = (tracked_pt) arrayList_get(tracker->trackedServices, i); - arrayList_add(references, tracked->reference); - } - celixThreadRwlock_unlock(&tracker->lock); - - return references; -} - -void *serviceTracker_getService(service_tracker_pt tracker) { - tracked_pt tracked; - void *service = NULL; - unsigned int i; - - celixThreadRwlock_readLock(&tracker->lock); - for (i = 0; i < arrayList_size(tracker->trackedServices); i++) { - tracked = (tracked_pt) arrayList_get(tracker->trackedServices, i); - service = tracked->service; - break; - } - celixThreadRwlock_unlock(&tracker->lock); - - return service; -} - -array_list_pt serviceTracker_getServices(service_tracker_pt tracker) { - tracked_pt tracked; - unsigned int i; - array_list_pt references = NULL; - arrayList_create(&references); - - celixThreadRwlock_readLock(&tracker->lock); - for (i = 0; i < arrayList_size(tracker->trackedServices); i++) { - tracked = (tracked_pt) arrayList_get(tracker->trackedServices, i); - arrayList_add(references, tracked->service); - } - celixThreadRwlock_unlock(&tracker->lock); - - return references; -} - -void *serviceTracker_getServiceByReference(service_tracker_pt tracker, service_reference_pt reference) { - tracked_pt tracked; - void *service = NULL; - unsigned int i; - - celixThreadRwlock_readLock(&tracker->lock); - for (i = 0; i < arrayList_size(tracker->trackedServices); i++) { - bool equals = false; - tracked = (tracked_pt) arrayList_get(tracker->trackedServices, i); - serviceReference_equals(reference, tracked->reference, &equals); - if (equals) { - service = tracked->service; - break; - } - } - celixThreadRwlock_unlock(&tracker->lock); - - return service; -} - -void serviceTracker_serviceChanged(service_listener_pt listener, service_event_pt event) { - service_tracker_pt tracker = listener->handle; - switch (event->type) { - case OSGI_FRAMEWORK_SERVICE_EVENT_REGISTERED: - serviceTracker_track(tracker, event->reference, event); - break; - case OSGI_FRAMEWORK_SERVICE_EVENT_MODIFIED: - serviceTracker_track(tracker, event->reference, event); - break; - case OSGI_FRAMEWORK_SERVICE_EVENT_UNREGISTERING: - serviceTracker_untrack(tracker, event->reference, event); - break; - case OSGI_FRAMEWORK_SERVICE_EVENT_MODIFIED_ENDMATCH: - //TODO - break; - } -} - -static celix_status_t serviceTracker_track(service_tracker_pt tracker, service_reference_pt reference, service_event_pt event) { - celix_status_t status = CELIX_SUCCESS; - - tracked_pt tracked = NULL; - bool found = false; - unsigned int i; - - bundleContext_retainServiceReference(tracker->context, reference); - - celixThreadRwlock_readLock(&tracker->lock); - for (i = 0; i < arrayList_size(tracker->trackedServices); i++) { - bool equals = false; - tracked = (tracked_pt) arrayList_get(tracker->trackedServices, i); - status = serviceReference_equals(reference, tracked->reference, &equals); - if (status != CELIX_SUCCESS) { - break; - } - if (equals) { - found = true; - break; - } - } - celixThreadRwlock_unlock(&tracker->lock); - - if (status == CELIX_SUCCESS && !found /*new*/) { - void * service = NULL; - status = serviceTracker_invokeAddingService(tracker, reference, &service); - if (status == CELIX_SUCCESS) { - if (service != NULL) { - tracked = (tracked_pt) calloc(1, sizeof (*tracked)); - assert(reference != NULL); - tracked->reference = reference; - tracked->service = service; - - celixThreadRwlock_writeLock(&tracker->lock); - arrayList_add(tracker->trackedServices, tracked); - celixThreadRwlock_unlock(&tracker->lock); - - serviceTracker_invokeAddService(tracker, reference, service); - } - } - - } else { - status = serviceTracker_invokeModifiedService(tracker, reference, tracked->service); - } - - framework_logIfError(logger, status, NULL, "Cannot track reference"); - - return status; -} - -static celix_status_t serviceTracker_invokeModifiedService(service_tracker_pt tracker, service_reference_pt ref, void *service) { - celix_status_t status = CELIX_SUCCESS; - if (tracker->customizer != NULL) { - void *handle = NULL; - modified_callback_pt function = NULL; - - serviceTrackerCustomizer_getHandle(tracker->customizer, &handle); - serviceTrackerCustomizer_getModifiedFunction(tracker->customizer, &function); - - if (function != NULL) { - function(handle, ref, service); - } - } - return status; -} - -static celix_status_t serviceTracker_invokeAddService(service_tracker_pt tracker, service_reference_pt ref, void *service) { - celix_status_t status = CELIX_SUCCESS; - if (tracker->customizer != NULL) { - void *handle = NULL; - added_callback_pt function = NULL; - - serviceTrackerCustomizer_getHandle(tracker->customizer, &handle); - serviceTrackerCustomizer_getAddedFunction(tracker->customizer, &function); - if (function != NULL) { - function(handle, ref, service); - } - } - return status; -} - -static celix_status_t serviceTracker_invokeAddingService(service_tracker_pt tracker, service_reference_pt reference, - void **service) { - celix_status_t status = CELIX_SUCCESS; - - if (tracker->customizer != NULL) { - void *handle = NULL; - adding_callback_pt function = NULL; - - status = serviceTrackerCustomizer_getHandle(tracker->customizer, &handle); - - if (status == CELIX_SUCCESS) { - status = serviceTrackerCustomizer_getAddingFunction(tracker->customizer, &function); - } - - if (status == CELIX_SUCCESS) { - if (function != NULL) { - status = function(handle, reference, service); - } else { - status = bundleContext_getService(tracker->context, reference, service); - } - } - } else { - status = bundleContext_getService(tracker->context, reference, service); - } - - framework_logIfError(logger, status, NULL, "Cannot handle addingService"); - - return status; -} - -static celix_status_t serviceTracker_untrack(service_tracker_pt tracker, service_reference_pt reference, service_event_pt event) { - celix_status_t status = CELIX_SUCCESS; - tracked_pt tracked = NULL; - unsigned int i; - bool found = false; - - celixThreadRwlock_writeLock(&tracker->lock); - for (i = 0; i < arrayList_size(tracker->trackedServices); i++) { - bool equals; - tracked = (tracked_pt) arrayList_get(tracker->trackedServices, i); - serviceReference_equals(reference, tracked->reference, &equals); - if (equals) { - found = true; - arrayList_remove(tracker->trackedServices, i); - break; - } - } - celixThreadRwlock_unlock(&tracker->lock); - - if (found && tracked != NULL) { - serviceTracker_invokeRemovingService(tracker, tracked->reference, tracked->service); - bundleContext_ungetServiceReference(tracker->context, reference); - free(tracked); - } - - framework_logIfError(logger, status, NULL, "Cannot untrack reference"); - - return status; -} - -static celix_status_t serviceTracker_invokeRemovingService(service_tracker_pt tracker, service_reference_pt ref, void *service) { - celix_status_t status = CELIX_SUCCESS; - bool ungetSuccess = true; - if (tracker->customizer != NULL) { - void *handle = NULL; - removed_callback_pt function = NULL; - - serviceTrackerCustomizer_getHandle(tracker->customizer, &handle); - serviceTrackerCustomizer_getRemovedFunction(tracker->customizer, &function); - - if (function != NULL) { - status = function(handle, ref, service); - } - if (status == CELIX_SUCCESS) { - status = bundleContext_ungetService(tracker->context, ref, &ungetSuccess); - } - } else { - status = bundleContext_ungetService(tracker->context, ref, &ungetSuccess); - } - - if (!ungetSuccess) { - framework_log(logger, OSGI_FRAMEWORK_LOG_ERROR, __FUNCTION__, __FILE__, __LINE__, "Error ungetting service"); - status = CELIX_BUNDLE_EXCEPTION; - } - - return status; -} http://git-wip-us.apache.org/repos/asf/celix/blob/a1c30887/framework/private/src/service_tracker_customizer.c ---------------------------------------------------------------------- diff --git a/framework/private/src/service_tracker_customizer.c b/framework/private/src/service_tracker_customizer.c deleted file mode 100644 index b62a23a..0000000 --- a/framework/private/src/service_tracker_customizer.c +++ /dev/null @@ -1,107 +0,0 @@ -/** - *Licensed to the Apache Software Foundation (ASF) under one - *or more contributor license agreements. See the NOTICE file - *distributed with this work for additional information - *regarding copyright ownership. The ASF licenses this file - *to you under the Apache License, Version 2.0 (the - *"License"); you may not use this file except in compliance - *with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - *Unless required by applicable law or agreed to in writing, - *software distributed under the License is distributed on an - *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - *specific language governing permissions and limitations - *under the License. - */ -/* - * service_tracker_customizer.c - * - * \date Nov 15, 2012 - * \author <a href="mailto:[email protected]">Apache Celix Project Team</a> - * \copyright Apache License, Version 2.0 - */ - -#include <stdlib.h> - -#include "service_tracker_customizer_private.h" -#include "celix_log.h" - -celix_status_t serviceTrackerCustomizer_create(void *handle, - adding_callback_pt addingFunction, added_callback_pt addedFunction, - modified_callback_pt modifiedFunction, removed_callback_pt removedFunction, service_tracker_customizer_pt *customizer) { - celix_status_t status = CELIX_SUCCESS; - - if (handle == NULL || *customizer != NULL) { - status = CELIX_ILLEGAL_ARGUMENT; - } else { - *customizer = malloc(sizeof(**customizer)); - if (!*customizer) { - status = CELIX_ENOMEM; - } else { - (*customizer)->handle = handle; - (*customizer)->addingService = addingFunction; - (*customizer)->addedService = addedFunction; - (*customizer)->modifiedService = modifiedFunction; - (*customizer)->removedService = removedFunction; - } - } - - framework_logIfError(logger, status, NULL, "Cannot create customizer"); - - return status; -} - -celix_status_t serviceTrackerCustomizer_destroy(service_tracker_customizer_pt customizer) { - customizer->handle = NULL; - customizer->addingService = NULL; - customizer->addedService = NULL; - customizer->modifiedService = NULL; - customizer->removedService = NULL; - - free(customizer); - - return CELIX_SUCCESS; -} - -celix_status_t serviceTrackerCustomizer_getHandle(service_tracker_customizer_pt customizer, void **handle) { - celix_status_t status = CELIX_SUCCESS; - - *handle = customizer->handle; - - return status; -} - -celix_status_t serviceTrackerCustomizer_getAddingFunction(service_tracker_customizer_pt customizer, adding_callback_pt *function) { - celix_status_t status = CELIX_SUCCESS; - - *function = customizer->addingService; - - return status; -} - -celix_status_t serviceTrackerCustomizer_getAddedFunction(service_tracker_customizer_pt customizer, added_callback_pt *function) { - celix_status_t status = CELIX_SUCCESS; - - *function = customizer->addedService; - - return status; -} - -celix_status_t serviceTrackerCustomizer_getModifiedFunction(service_tracker_customizer_pt customizer, modified_callback_pt *function) { - celix_status_t status = CELIX_SUCCESS; - - *function = customizer->modifiedService; - - return status; -} - -celix_status_t serviceTrackerCustomizer_getRemovedFunction(service_tracker_customizer_pt customizer, removed_callback_pt *function) { - celix_status_t status = CELIX_SUCCESS; - - *function = customizer->removedService; - - return status; -}
