You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@celix.apache.org by pn...@apache.org on 2015/11/11 13:58:11 UTC
[5/7] celix git commit: CELIX-272: Refactoring of ServiceRegistry.
Added warning log of incorrect handling service refs/regs
CELIX-272: Refactoring of ServiceRegistry. Added warning log of incorrect handling service refs/regs
Project: http://git-wip-us.apache.org/repos/asf/celix/repo
Commit: http://git-wip-us.apache.org/repos/asf/celix/commit/592d65f9
Tree: http://git-wip-us.apache.org/repos/asf/celix/tree/592d65f9
Diff: http://git-wip-us.apache.org/repos/asf/celix/diff/592d65f9
Branch: refs/heads/feature/CELIX-272_synchronization_service_registry
Commit: 592d65f900e6193b8b74d5dac0c2875bfa7e355f
Parents: 5fbd1f5
Author: Pepijn Noltes <pe...@gmail.com>
Authored: Wed Nov 11 13:24:55 2015 +0100
Committer: Pepijn Noltes <pe...@gmail.com>
Committed: Wed Nov 11 13:24:55 2015 +0100
----------------------------------------------------------------------
.../private/src/dm_component_impl.c | 15 +-
.../private/src/provider_activator.c | 1 +
.../private/include/service_reference_private.h | 19 +-
.../private/include/service_registry_private.h | 4 +-
.../service_tracker_customizer_private.h | 4 +
framework/private/src/bundle_context.c | 2 +-
framework/private/src/framework.c | 32 +-
framework/private/src/properties.c | 2 +
framework/private/src/service_reference.c | 180 +++++--
framework/private/src/service_registration.c | 17 -
framework/private/src/service_registry.c | 476 +++++++------------
framework/private/src/service_tracker.c | 155 +++---
framework/public/include/service_reference.h | 2 -
framework/public/include/service_registration.h | 1 -
framework/public/include/service_registry.h | 19 +-
15 files changed, 449 insertions(+), 480 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/celix/blob/592d65f9/dependency_manager/private/src/dm_component_impl.c
----------------------------------------------------------------------
diff --git a/dependency_manager/private/src/dm_component_impl.c b/dependency_manager/private/src/dm_component_impl.c
index aa34389..fe782bb 100644
--- a/dependency_manager/private/src/dm_component_impl.c
+++ b/dependency_manager/private/src/dm_component_impl.c
@@ -1093,14 +1093,13 @@ celix_status_t component_registerServices(dm_component_pt component) {
celix_status_t status = CELIX_SUCCESS;
if (component->context) {
- unsigned int i;
-
- for (i = 0; i < arrayList_size(component->dm_interfaces); i++) {
- dm_interface_t *interface = arrayList_get(component->dm_interfaces, i);
- properties_pt regProps = NULL;
- properties_copy(interface->properties, ®Props);
- bundleContext_registerService(component->context, interface->serviceName, interface->service, regProps, &interface->registration);
- }
+ unsigned int i;
+ for (i = 0; i < arrayList_size(component->dm_interfaces); i++) {
+ dm_interface_t *interface = arrayList_get(component->dm_interfaces, i);
+ properties_pt regProps = NULL;
+ properties_copy(interface->properties, ®Props);
+ bundleContext_registerService(component->context, interface->serviceName, interface->service, regProps, &interface->registration);
+ }
}
return status;
http://git-wip-us.apache.org/repos/asf/celix/blob/592d65f9/examples/locking/math_provider/private/src/provider_activator.c
----------------------------------------------------------------------
diff --git a/examples/locking/math_provider/private/src/provider_activator.c b/examples/locking/math_provider/private/src/provider_activator.c
index 319980f..0407005 100644
--- a/examples/locking/math_provider/private/src/provider_activator.c
+++ b/examples/locking/math_provider/private/src/provider_activator.c
@@ -73,6 +73,7 @@ celix_status_t bundleActivator_create(bundle_context_pt context, void **userData
activator->context = context;
activator->benchmarkName = NULL;
activator->freqService = NULL;
+ activator->registration = NULL;
activator->freqRegistration = NULL;
activator->updateFrequency = 0;
activator->nrOfThreads = 0;
http://git-wip-us.apache.org/repos/asf/celix/blob/592d65f9/framework/private/include/service_reference_private.h
----------------------------------------------------------------------
diff --git a/framework/private/include/service_reference_private.h b/framework/private/include/service_reference_private.h
index 114eae1..2ac4ee5 100644
--- a/framework/private/include/service_reference_private.h
+++ b/framework/private/include/service_reference_private.h
@@ -31,19 +31,28 @@
#include "service_reference.h"
struct serviceReference {
- bundle_pt bundle;
+ bundle_pt referenceOwner;
struct serviceRegistration * registration;
+ bundle_pt registrationBundle;
size_t refCount;
- celix_thread_mutex_t mutex; //protects refCount
+ size_t usageCount;
+
+ celix_thread_rwlock_t lock;
};
-celix_status_t serviceReference_create(bundle_pt bundle, service_registration_pt registration, service_reference_pt *reference);
+celix_status_t serviceReference_create(bundle_pt referenceOwner, service_registration_pt registration, service_reference_pt *reference);
+
+celix_status_t serviceReference_retain(service_reference_pt ref);
+celix_status_t serviceReference_release(service_reference_pt ref, bool *destroyed);
-void serviceReference_retain(service_reference_pt ref);
-void serviceReference_release(service_reference_pt ref);
+celix_status_t serviceReference_increaseUsage(service_reference_pt ref);
+celix_status_t serviceReference_decreaseUsage(service_reference_pt ref);
celix_status_t serviceReference_invalidate(service_reference_pt reference);
celix_status_t serviceReference_isValid(service_reference_pt reference, bool *result);
+celix_status_t serviceReference_getUsageCount(service_reference_pt reference, size_t *count);
+celix_status_t serviceReference_getReferenceCount(service_reference_pt reference, size_t *count);
+
#endif /* SERVICE_REFERENCE_PRIVATE_H_ */
http://git-wip-us.apache.org/repos/asf/celix/blob/592d65f9/framework/private/include/service_registry_private.h
----------------------------------------------------------------------
diff --git a/framework/private/include/service_registry_private.h b/framework/private/include/service_registry_private.h
index d89f28e..c5a731c 100644
--- a/framework/private/include/service_registry_private.h
+++ b/framework/private/include/service_registry_private.h
@@ -33,8 +33,7 @@
struct serviceRegistry {
framework_pt framework;
hash_map_pt serviceRegistrations;
- hash_map_pt serviceReferences;
- hash_map_pt inUseMap;
+ hash_map_pt serviceReferences; //key = bundle, value = map (key = registration, value = reference)
serviceChanged_function_pt serviceChanged;
long currentServiceId;
@@ -44,6 +43,7 @@ struct serviceRegistry {
celix_thread_mutexattr_t mutexAttr;
celix_thread_mutex_t referencesMapMutex;
+
};
struct usageCount {
http://git-wip-us.apache.org/repos/asf/celix/blob/592d65f9/framework/private/include/service_tracker_customizer_private.h
----------------------------------------------------------------------
diff --git a/framework/private/include/service_tracker_customizer_private.h b/framework/private/include/service_tracker_customizer_private.h
index bda3cde..61fb52f 100644
--- a/framework/private/include/service_tracker_customizer_private.h
+++ b/framework/private/include/service_tracker_customizer_private.h
@@ -38,7 +38,11 @@ struct serviceTrackerCustomizer {
celix_status_t (*addingService)(void * handle, service_reference_pt reference, void **service);
celix_status_t (*addedService)(void * handle, service_reference_pt reference, void * service);
celix_status_t (*modifiedService)(void * handle, service_reference_pt reference, void * service);
+
+ /*TODO rename to removingService. because it is invoke during remove not after!*/
celix_status_t (*removedService)(void * handle, service_reference_pt reference, void * service);
+
+ /*TODO add removed function ? invoked after the remove ?? */
};
http://git-wip-us.apache.org/repos/asf/celix/blob/592d65f9/framework/private/src/bundle_context.c
----------------------------------------------------------------------
diff --git a/framework/private/src/bundle_context.c b/framework/private/src/bundle_context.c
index 35d27ce..f84d767 100644
--- a/framework/private/src/bundle_context.c
+++ b/framework/private/src/bundle_context.c
@@ -133,7 +133,7 @@ celix_status_t bundleContext_registerService(bundle_context_pt context, char * s
status = CELIX_ILLEGAL_ARGUMENT;
}
- framework_logIfError(logger, status, NULL, "Failed to register service");
+ framework_logIfError(logger, status, NULL, "Failed to register service. serviceName '%s'", serviceName);
return status;
}
http://git-wip-us.apache.org/repos/asf/celix/blob/592d65f9/framework/private/src/framework.c
----------------------------------------------------------------------
diff --git a/framework/private/src/framework.c b/framework/private/src/framework.c
index 47aabb3..7e66dbe 100644
--- a/framework/private/src/framework.c
+++ b/framework/private/src/framework.c
@@ -910,7 +910,7 @@ celix_status_t fw_stopBundle(framework_pt framework, bundle_pt bundle, bool reco
}
if (id != 0) {
- status = CELIX_DO_IF(status, serviceRegistry_unregisterServices(framework->registry, bundle));
+ status = CELIX_DO_IF(status, serviceRegistry_clearServiceRegistrations(framework->registry, bundle));
if (status == CELIX_SUCCESS) {
module_pt module = NULL;
char *symbolicName = NULL;
@@ -919,8 +919,7 @@ celix_status_t fw_stopBundle(framework_pt framework, bundle_pt bundle, bool reco
module_getSymbolicName(module, &symbolicName);
bundle_getBundleId(bundle, &id);
- serviceRegistry_ungetServices(framework->registry, bundle);
- serviceRegistry_ungetServiceReferences(framework->registry, bundle);
+ serviceRegistry_clearReferencesFor(framework->registry, bundle);
}
// #TODO remove listeners for bundle
@@ -1294,14 +1293,13 @@ celix_status_t fw_registerService(framework_pt framework, service_registration_p
}
}
- bool ungetResult = false;
-
- status = CELIX_DO_IF(status, serviceRegistry_createServiceReference(framework->registry, framework->bundle, *registration, &ref));
+ status = CELIX_DO_IF(status, serviceRegistry_getServiceReference(framework->registry, framework->bundle,
+ *registration, &ref));
status = CELIX_DO_IF(status, fw_getService(framework,framework->bundle, ref, (void **) &hook));
if (status == CELIX_SUCCESS) {
hook->added(hook->handle, infos);
}
- status = CELIX_DO_IF(status, serviceRegistry_ungetService(framework->registry, framework->bundle, ref, &ungetResult));
+ status = CELIX_DO_IF(status, serviceRegistry_ungetService(framework->registry, framework->bundle, ref, NULL));
status = CELIX_DO_IF(status, serviceRegistry_ungetServiceReference(framework->registry, framework->bundle, ref));
int i = 0;
@@ -1633,15 +1631,21 @@ void fw_serviceChanged(framework_pt framework, service_event_type_e eventType, s
event = (service_event_pt) malloc(sizeof(*event));
- serviceRegistry_createServiceReference(framework->registry, element->bundle, registration, &reference);
+ serviceRegistry_getServiceReference(framework->registry, element->bundle, registration, &reference);
event->type = eventType;
event->reference = reference;
element->listener->serviceChanged(element->listener, event);
- free(event);
- //TODO cleanup service reference
+ if (eventType != OSGI_FRAMEWORK_SERVICE_EVENT_REGISTERED) {
+ serviceRegistry_ungetServiceReference(framework->registry, element->bundle, reference);
+ }
+ if (eventType == OSGI_FRAMEWORK_SERVICE_EVENT_UNREGISTERING) {
+ serviceRegistry_ungetServiceReference(framework->registry, element->bundle, reference);
+ }
+
+ free(event);
} else if (eventType == OSGI_FRAMEWORK_SERVICE_EVENT_MODIFIED) {
bool matchResult = false;
@@ -1654,14 +1658,16 @@ void fw_serviceChanged(framework_pt framework, service_event_type_e eventType, s
service_reference_pt reference = NULL;
service_event_pt endmatch = (service_event_pt) malloc(sizeof(*endmatch));
- serviceRegistry_createServiceReference(framework->registry, element->bundle, registration, &reference);
+ serviceRegistry_getServiceReference(framework->registry, element->bundle, registration, &reference);
endmatch->reference = reference;
endmatch->type = OSGI_FRAMEWORK_SERVICE_EVENT_MODIFIED_ENDMATCH;
element->listener->serviceChanged(element->listener, endmatch);
- //TODO clean up serviceReference after serviceChanged update
- }
+ serviceRegistry_ungetServiceReference(framework->registry, element->bundle, reference);
+ free(endmatch);
+
+ }
}
}
}
http://git-wip-us.apache.org/repos/asf/celix/blob/592d65f9/framework/private/src/properties.c
----------------------------------------------------------------------
diff --git a/framework/private/src/properties.c b/framework/private/src/properties.c
index 271eed1..5f1b67e 100644
--- a/framework/private/src/properties.c
+++ b/framework/private/src/properties.c
@@ -200,6 +200,8 @@ celix_status_t properties_copy(properties_pt properties, properties_pt *out) {
if (status == CELIX_SUCCESS) {
*out = copy;
}
+
+ return status;
}
char * properties_get(properties_pt properties, char * key) {
http://git-wip-us.apache.org/repos/asf/celix/blob/592d65f9/framework/private/src/service_reference.c
----------------------------------------------------------------------
diff --git a/framework/private/src/service_reference.c b/framework/private/src/service_reference.c
index 24fdc99..73e9778 100644
--- a/framework/private/src/service_reference.c
+++ b/framework/private/src/service_reference.c
@@ -41,79 +41,145 @@
#include "celix_log.h"
static void serviceReference_destroy(service_reference_pt);
+static void serviceReference_logWarningUsageCountBelowZero(service_reference_pt ref);
-celix_status_t serviceReference_create(bundle_pt bundle, service_registration_pt registration, service_reference_pt *out) {
+celix_status_t serviceReference_create(bundle_pt referenceOwner, service_registration_pt registration, service_reference_pt *out) {
celix_status_t status = CELIX_SUCCESS;
service_reference_pt ref = calloc(1, sizeof(*ref));
if (!ref) {
status = CELIX_ENOMEM;
} else {
- ref->bundle = bundle;
+ serviceRegistration_retain(registration);
+ ref->referenceOwner = referenceOwner;
ref->registration = registration;
- celixThreadMutex_create(&ref->mutex, NULL);
+ serviceRegistration_getBundle(registration, &ref->registrationBundle);
+ celixThreadRwlock_create(&ref->lock, NULL);
ref->refCount = 1;
+ ref->usageCount = 0;
}
if (status == CELIX_SUCCESS) {
*out = ref;
- } else {
- framework_logIfError(logger, status, NULL, "Cannot create service reference");
}
+ framework_logIfError(logger, status, NULL, "Cannot create service reference");
+
return status;
}
-void serviceReference_retain(service_reference_pt ref) {
- celixThreadMutex_lock(&ref->mutex);
+celix_status_t serviceReference_retain(service_reference_pt ref) {
+ celixThreadRwlock_writeLock(&ref->lock);
ref->refCount += 1;
- celixThreadMutex_unlock(&ref->mutex);
+ celixThreadRwlock_unlock(&ref->lock);
+ return CELIX_SUCCESS;
}
-void serviceReference_release(service_reference_pt ref) {
- celixThreadMutex_lock(&ref->mutex);
+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) {
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) {
+ celixThreadRwlock_writeLock(&ref->lock);
+ ref->usageCount += 1;
+ celixThreadRwlock_unlock(&ref->lock);
+ return CELIX_SUCCESS;
+}
+
+celix_status_t serviceReference_decreaseUsage(service_reference_pt ref) {
+ celix_status_t status = CELIX_SUCCESS;
+ celixThreadRwlock_writeLock(&ref->lock);
+ if (ref->usageCount == 0) {
+ serviceReference_logWarningUsageCountBelowZero(ref);
+ status = CELIX_BUNDLE_EXCEPTION;
} else {
- celixThreadMutex_unlock(&ref->mutex);
+ ref->usageCount -= 1;
}
+ celixThreadRwlock_unlock(&ref->lock);
+ return status;
+}
+
+static void serviceReference_logWarningUsageCountBelowZero(service_reference_pt ref) {
+ 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;
}
static void serviceReference_destroy(service_reference_pt ref) {
assert(ref->refCount == 0);
- celixThreadMutex_destroy(&ref->mutex);
- ref->bundle = NULL;
+ celixThreadRwlock_destroy(&ref->lock);
ref->registration = NULL;
free(ref);
}
-celix_status_t serviceReference_getBundle(service_reference_pt reference, bundle_pt *bundle) {
- *bundle = reference->bundle;
- return CELIX_SUCCESS;
+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_getServiceRegistration(service_reference_pt reference, service_registration_pt *registration) {
- *registration = reference->registration;
- return CELIX_SUCCESS;
+celix_status_t serviceReference_getServiceRegistration(service_reference_pt ref, service_registration_pt *out) {
+ celixThreadRwlock_readLock(&ref->lock);
+ *out = ref->registration;
+ celixThreadRwlock_unlock(&ref->lock);
+ return CELIX_SUCCESS;
}
-celix_status_t serviceReference_getProperty(service_reference_pt reference, char *key, char **value) {
+celix_status_t serviceReference_getProperty(service_reference_pt ref, char *key, char **value) {
celix_status_t status = CELIX_SUCCESS;
properties_pt props = NULL;
-
- serviceRegistration_getProperties(reference->registration, &props);
- *value = properties_get(props, key);
-
+ celixThreadRwlock_readLock(&ref->lock);
+ if (ref->registration != NULL) {
+ status = serviceRegistration_getProperties(ref->registration, &props);
+ if (status == CELIX_SUCCESS) {
+ *value = properties_get(props, key);
+ }
+ } else {
+ *value = NULL;
+ }
+ celixThreadRwlock_unlock(&ref->lock);
return status;
}
-FRAMEWORK_EXPORT celix_status_t serviceReference_getPropertyKeys(service_reference_pt reference, char **keys[], unsigned int *size) {
+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;
- serviceRegistration_getProperties(reference->registration, &props);
+ celixThreadRwlock_readLock(&ref->lock);
+ serviceRegistration_getProperties(ref->registration, &props);
hash_map_iterator_pt it;
int i = 0;
int vsize = hashMap_size(props);
@@ -125,18 +191,30 @@ FRAMEWORK_EXPORT celix_status_t serviceReference_getPropertyKeys(service_referen
i++;
}
hashMapIterator_destroy(it);
-
+ celixThreadRwlock_unlock(&ref->lock);
return status;
}
-celix_status_t serviceReference_invalidate(service_reference_pt reference) {
- reference->registration = NULL;
- return CELIX_SUCCESS;
+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 reference, bool *result) {
- (*result) = reference->registration != NULL;
- return CELIX_SUCCESS;
+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, bundle_pt requester, char * serviceName) {
@@ -148,19 +226,12 @@ bool serviceReference_isAssignableTo(service_reference_pt reference, bundle_pt r
return allow;
}
-celix_status_t serviceReference_getUsingBundles(service_reference_pt reference, array_list_pt *bundles) {
- celix_status_t status = CELIX_SUCCESS;
-
- service_registry_pt registry = NULL;
- serviceRegistration_getRegistry(reference->registration, ®istry);
-
- *bundles = serviceRegistry_getUsingBundles(registry, reference);
-
- return status;
-}
-
celix_status_t serviceReference_equals(service_reference_pt reference, service_reference_pt compareTo, bool *equal) {
- *equal = (reference->registration == compareTo->registration);
+ service_registration_pt reg1;
+ service_registration_pt reg2;
+ serviceReference_getServiceRegistration(reference, ®1);
+ serviceReference_getServiceRegistration(compareTo, ®2);
+ *equal = (reg1 == reg2);
return CELIX_SUCCESS;
}
@@ -196,14 +267,25 @@ celix_status_t serviceReference_compareTo(service_reference_pt reference, servic
}
unsigned int serviceReference_hashCode(void *referenceP) {
- service_reference_pt reference = referenceP;
+ service_reference_pt ref = 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 (reference != NULL) {
- intptr_t bundleA = (intptr_t) reference->bundle;
- intptr_t registrationA = (intptr_t) reference->registration;
+ if (bundle != NULL && reg != NULL) {
+ intptr_t bundleA = (intptr_t) bundle;
+ intptr_t registrationA = (intptr_t) reg;
result += bundleA + registrationA;
}
http://git-wip-us.apache.org/repos/asf/celix/blob/592d65f9/framework/private/src/service_registration.c
----------------------------------------------------------------------
diff --git a/framework/private/src/service_registration.c b/framework/private/src/service_registration.c
index 718a633..3bd9ddd 100644
--- a/framework/private/src/service_registration.c
+++ b/framework/private/src/service_registration.c
@@ -112,11 +112,8 @@ static celix_status_t serviceRegistration_destroy(service_registration_pt regist
registration->registry = NULL;
properties_destroy(registration->properties);
-
celixThreadMutex_destroy(®istration->mutex);
-
free(registration);
- registration = NULL;
return CELIX_SUCCESS;
}
@@ -227,20 +224,6 @@ celix_status_t serviceRegistration_getRegistry(service_registration_pt registrat
return status;
}
-celix_status_t serviceRegistration_getServiceReferences(service_registration_pt registration, array_list_pt *references) {
- celix_status_t status = CELIX_SUCCESS;
-
- if (registration != NULL && *references == NULL) {
- serviceRegistry_getServiceReferencesForRegistration(registration->registry, registration, references);
- } else {
- status = CELIX_ILLEGAL_ARGUMENT;
- }
-
- framework_logIfError(logger, status, NULL, "Cannot get service reference");
-
- return status;
-}
-
celix_status_t serviceRegistration_getBundle(service_registration_pt registration, bundle_pt *bundle) {
celix_status_t status = CELIX_SUCCESS;
http://git-wip-us.apache.org/repos/asf/celix/blob/592d65f9/framework/private/src/service_registry.c
----------------------------------------------------------------------
diff --git a/framework/private/src/service_registry.c b/framework/private/src/service_registry.c
index ec72f6d..d38b07e 100644
--- a/framework/private/src/service_registry.c
+++ b/framework/private/src/service_registry.c
@@ -37,15 +37,12 @@
#include "framework_private.h"
#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,
- 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);
celix_status_t serviceRegistry_addHooks(service_registry_pt registry, char *serviceName, void *serviceObject, service_registration_pt registration);
celix_status_t serviceRegistry_removeHook(service_registry_pt registry, service_registration_pt registration);
+static void serviceRegistry_logWarningServiceReferenceUsageCount(service_registry_pt registry, size_t usageCount, size_t refCount);
+static void serviceRegistry_logWarningServiceRegistration(service_registry_pt registry, service_registration_pt reg);
+
celix_status_t serviceRegistry_create(framework_pt framework, serviceChanged_function_pt serviceChanged, service_registry_pt *registry) {
celix_status_t status = CELIX_SUCCESS;
@@ -56,7 +53,6 @@ celix_status_t serviceRegistry_create(framework_pt framework, serviceChanged_fun
} else {
(*registry)->serviceChanged = serviceChanged;
- (*registry)->inUseMap = hashMap_create(NULL, NULL, NULL, NULL);
(*registry)->serviceRegistrations = hashMap_create(NULL, NULL, NULL, NULL);
(*registry)->framework = framework;
(*registry)->currentServiceId = 1l;
@@ -76,7 +72,6 @@ celix_status_t serviceRegistry_create(framework_pt framework, serviceChanged_fun
}
celix_status_t serviceRegistry_destroy(service_registry_pt registry) {
- hashMap_destroy(registry->inUseMap, false, false);
hashMap_destroy(registry->serviceRegistrations, false, false);
hashMap_destroy(registry->serviceReferences, false, false);
arrayList_destroy(registry->listenerHooks);
@@ -84,7 +79,6 @@ celix_status_t serviceRegistry_destroy(service_registry_pt registry) {
celixThreadMutexAttr_destroy(®istry->mutexAttr);
celixThreadMutex_destroy(®istry->referencesMapMutex);
registry->framework = NULL;
- registry->inUseMap = NULL;
registry->listenerHooks = NULL;
registry->serviceChanged = NULL;
registry->serviceReferences = NULL;
@@ -94,68 +88,6 @@ celix_status_t serviceRegistry_destroy(service_registry_pt registry) {
return CELIX_SUCCESS;
}
-static celix_status_t serviceRegistry_getUsageCount(service_registry_pt registry, bundle_pt bundle, service_reference_pt reference, usage_count_pt *usageCount) {
- array_list_pt usages = (array_list_pt) hashMap_get(registry->inUseMap, bundle);
- *usageCount = NULL;
- unsigned int i;
- for (i = 0; (usages != NULL) && (i < arrayList_size(usages)); i++) {
- usage_count_pt usage = (usage_count_pt) arrayList_get(usages, i);
- bool equals = false;
- serviceReference_equals(usage->reference, reference, &equals);
- if (equals) {
- *usageCount = usage;
- break;
- }
- }
- return CELIX_SUCCESS;
-}
-
-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);
- }
- arrayList_add(usages, usage);
- hashMap_put(registry->inUseMap, bundle, usages);
- *usageCount = usage;
- return CELIX_SUCCESS;
-}
-
-static celix_status_t serviceRegistry_flushUsageCount(service_registry_pt registry, bundle_pt bundle, service_reference_pt reference) {
- array_list_pt usages = hashMap_get(registry->inUseMap, bundle);
- if (usages != NULL) {
- array_list_iterator_pt iter = arrayListIterator_create(usages);
- while (arrayListIterator_hasNext(iter)) {
- usage_count_pt usage = arrayListIterator_next(iter);
- bool equals = false;
- serviceReference_equals(usage->reference, reference, &equals);
- if (equals) {
- arrayListIterator_remove(iter);
- serviceRegistration_release(usage->registration);
- free(usage);
- }
- }
- arrayListIterator_destroy(iter);
- if (arrayList_size(usages) > 0) {
- hashMap_put(registry->inUseMap, bundle, usages);
- } else {
- array_list_pt removed = hashMap_remove(registry->inUseMap, bundle);
- arrayList_destroy(removed);
- }
- }
- 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;
@@ -169,7 +101,7 @@ celix_status_t serviceRegistry_getRegisteredServices(service_registry_pt registr
service_registration_pt reg = arrayList_get(regs, i);
if (serviceRegistration_isValid(reg)) {
service_reference_pt reference = NULL;
- status = serviceRegistry_createServiceReference(registry, bundle, reg, &reference);
+ status = serviceRegistry_getServiceReference(registry, bundle, reg, &reference);
if (status == CELIX_SUCCESS) {
arrayList_add(*services, reference);
}
@@ -227,9 +159,7 @@ celix_status_t serviceRegistry_registerServiceInternal(service_registry_pt regis
celix_status_t serviceRegistry_unregisterService(service_registry_pt registry, bundle_pt bundle, service_registration_pt registration) {
// array_list_t clients;
- unsigned int i;
array_list_pt regs;
- array_list_pt references = NULL;
celixThreadMutex_lock(®istry->mutex);
@@ -238,7 +168,6 @@ celix_status_t serviceRegistry_unregisterService(service_registry_pt registry, b
regs = (array_list_pt) hashMap_get(registry->serviceRegistrations, bundle);
if (regs != NULL) {
arrayList_removeElement(regs, registration);
- hashMap_put(registry->serviceRegistrations, bundle, regs);
}
celixThreadMutex_unlock(®istry->mutex);
@@ -248,27 +177,17 @@ celix_status_t serviceRegistry_unregisterService(service_registry_pt registry, b
}
celixThreadMutex_lock(®istry->mutex);
- // unget service
-
- serviceRegistration_getServiceReferences(registration, &references);
- for (i = 0; i < arrayList_size(references); i++) {
- service_reference_pt reference = (service_reference_pt) arrayList_get(references, i);
- array_list_pt clients = NULL;
- unsigned int j;
-
- clients = serviceRegistry_getUsingBundles(registry, reference);
- for (j = 0; (clients != NULL) && (j < arrayList_size(clients)); j++) {
- bundle_pt client = (bundle_pt) arrayList_get(clients, j);
- bool ungetResult = true;
- while (ungetResult) {
- serviceRegistry_ungetService(registry, client, reference, &ungetResult);
- }
- }
- arrayList_destroy(clients);
- serviceReference_invalidate(reference);
- }
- arrayList_destroy(references);
+ //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 = hashMap_get(refsMap, registration);
+ if (ref != NULL) {
+ serviceReference_invalidate(ref);
+ }
+ }
+ hashMapIterator_destroy(iter);
serviceRegistration_invalidate(registration);
serviceRegistration_release(registration);
@@ -278,94 +197,87 @@ celix_status_t serviceRegistry_unregisterService(service_registry_pt registry, b
return CELIX_SUCCESS;
}
-celix_status_t serviceRegistry_unregisterServices(service_registry_pt registry, bundle_pt bundle) {
- array_list_pt regs = NULL;
- unsigned int i;
- celixThreadMutex_lock(®istry->mutex);
- regs = (array_list_pt) hashMap_get(registry->serviceRegistrations, bundle);
- celixThreadMutex_unlock(®istry->mutex);
-
- for (i = 0; (regs != NULL) && i < arrayList_size(regs); i++) {
- service_registration_pt reg = arrayList_get(regs, i);
- if (serviceRegistration_isValid(reg)) {
- serviceRegistration_unregister(reg);
- }
- }
+celix_status_t serviceRegistry_clearServiceRegistrations(service_registry_pt registry, bundle_pt bundle) {
+ celix_status_t status = CELIX_SUCCESS;
+ array_list_pt registrations = NULL;
- if (regs != NULL && arrayList_isEmpty(regs)) {
- celixThreadMutex_lock(®istry->mutex);
- array_list_pt removed = hashMap_remove(registry->serviceRegistrations, bundle);
- celixThreadMutex_unlock(®istry->mutex);
- arrayList_destroy(removed);
- removed = NULL;
- }
- celixThreadMutex_lock(®istry->mutex);
- hashMap_remove(registry->serviceRegistrations, bundle);
- celixThreadMutex_unlock(®istry->mutex);
+ celixThreadMutex_lock(®istry->mutex);
- return CELIX_SUCCESS;
-}
+ registrations = hashMap_get(registry->serviceRegistrations, bundle);
+ while (registrations != NULL && arrayList_size(registrations) > 0) {
+ service_registration_pt reg = arrayList_get(registrations, 0);
+ serviceRegistry_logWarningServiceRegistration(registry, reg);
-celix_status_t serviceRegistry_createServiceReference(service_registry_pt registry, bundle_pt owner, service_registration_pt registration, service_reference_pt *reference) {
- celix_status_t status = CELIX_SUCCESS;
+ if (serviceRegistration_isValid(reg)) {
+ serviceRegistration_unregister(reg);
+ }
+ serviceRegistration_release(reg);
+ }
+ hashMap_remove(registry->serviceRegistrations, bundle);
- bundle_pt bundle = NULL;
+ celixThreadMutex_unlock(®istry->mutex);
- serviceRegistration_getBundle(registration, &bundle);
- serviceReference_create(bundle, registration, reference);
- // Lock
- celixThreadMutex_lock(®istry->referencesMapMutex);
- array_list_pt references = hashMap_get(registry->serviceReferences, owner);
- if (references == NULL) {
- arrayList_create(&references);
- }
- arrayList_add(references, *reference);
- hashMap_put(registry->serviceReferences, owner, references);
+ return status;
+}
- // Unlock
- celixThreadMutex_unlock(®istry->referencesMapMutex);
+static void serviceRegistry_logWarningServiceRegistration(service_registry_pt registry, service_registration_pt reg) {
+ 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", servName);
+}
- framework_logIfError(logger, status, NULL, "Cannot create service reference");
+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;
+ bundle_pt bundle = NULL;
+ service_reference_pt ref = NULL;
+ hash_map_pt references = NULL;
- return status;
-}
+ // Lock
+ celixThreadMutex_lock(®istry->referencesMapMutex);
+
+ references = hashMap_get(registry->serviceReferences, owner);
+ if (references == NULL) {
+ references = hashMap_create(NULL, NULL, NULL, NULL);
+ if (references != NULL) {
+ hashMap_put(registry->serviceReferences, owner, references);
+ } else {
+ status = CELIX_BUNDLE_EXCEPTION;
+ framework_logIfError(logger, status, NULL, "Cannot create hash map");
+ }
+ }
-celix_status_t serviceRegistry_getServiceReferencesForRegistration(service_registry_pt registry, service_registration_pt registration, array_list_pt *references) {
- celix_status_t status = CELIX_SUCCESS;
- hash_map_values_pt referenceValues = NULL;
- hash_map_iterator_pt iterator = NULL;
-
- arrayList_create(references);
-
- celixThreadMutex_lock(®istry->referencesMapMutex);
- referenceValues = hashMapValues_create(registry->serviceReferences);
- iterator = hashMapValues_iterator(referenceValues);
- while (hashMapIterator_hasNext(iterator)) {
- array_list_pt refs = (array_list_pt) hashMapIterator_nextValue(iterator);
- unsigned int refIdx;
- for (refIdx = 0; (refs != NULL) && refIdx < arrayList_size(refs); refIdx++) {
- service_registration_pt reg = NULL;
- service_reference_pt reference = (service_reference_pt) arrayList_get(refs, refIdx);
- bool valid = false;
- serviceReference_isValid(reference, &valid);
- if (valid) {
- serviceReference_getServiceRegistration(reference, ®);
- if (reg == registration) {
- arrayList_add(*references, reference);
- }
+ if (status == CELIX_SUCCESS) {
+ ref = hashMap_get(references, registration);
+ if (ref == NULL) {
+ status = serviceRegistration_getBundle(registration, &bundle);
+ if (status == CELIX_SUCCESS) {
+ status = serviceReference_create(owner, registration, &ref);
}
+ if (status == CELIX_SUCCESS) {
+ hashMap_put(references, registration, ref);
+ }
+ } else {
+ serviceReference_retain(ref);
}
}
- hashMapIterator_destroy(iterator);
- hashMapValues_destroy(referenceValues);
- celixThreadMutex_unlock(®istry->referencesMapMutex);
+ if (status == CELIX_SUCCESS) {
+ *out = ref;
+ }
- return status;
+ // Unlock
+ celixThreadMutex_unlock(®istry->referencesMapMutex);
+
+ 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 *references) {
@@ -407,7 +319,7 @@ celix_status_t serviceRegistry_getServiceReferences(service_registry_pt registry
if (matched) {
if (serviceRegistration_isValid(registration)) {
service_reference_pt reference = NULL;
- serviceRegistry_createServiceReference(registry, owner, registration, &reference);
+ serviceRegistry_getServiceReference(registry, owner, registration, &reference);
arrayList_add(*references, reference);
}
}
@@ -423,195 +335,131 @@ celix_status_t serviceRegistry_getServiceReferences(service_registry_pt registry
return status;
}
-celix_status_t serviceRegistry_ungetServiceReference(service_registry_pt registry, bundle_pt owner, service_reference_pt reference) {
+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;
+ service_registration_pt reg = NULL;
- bool valid = false;
- serviceReference_isValid(reference, &valid);
- if (valid) {
- bool ungetResult = true;
- while (ungetResult) {
- serviceRegistry_ungetService(registry, owner, reference, &ungetResult);
+ celixThreadMutex_lock(®istry->mutex);
+ serviceReference_getUsageCount(reference, &count);
+ serviceReference_getServiceRegistration(reference, ®);
+ serviceReference_release(reference, &destroyed);
+ if (destroyed) {
+ if (count > 0) {
+ serviceRegistry_logWarningServiceReferenceUsageCount(registry, 0, count);
}
+ hash_map_pt refsMap = hashMap_get(registry->serviceReferences, bundle);
+ hashMap_remove(refsMap, reg);
}
+ celixThreadMutex_unlock(®istry->mutex);
+ return status;
+}
- celixThreadMutex_lock(®istry->referencesMapMutex);
- array_list_pt references = hashMap_get(registry->serviceReferences, owner);
- if (references != NULL) {
- arrayList_removeElement(references, reference);
- serviceReference_release(reference);
- if (arrayList_size(references) > 0) {
- hashMap_put(registry->serviceReferences, owner, references);
- } else {
- array_list_pt removed = hashMap_remove(registry->serviceReferences, owner);
- arrayList_destroy(removed);
- }
+void serviceRegistry_logWarningServiceReferenceUsageCount(service_registry_pt registry, size_t usageCount, size_t refCount) {
+ if (usageCount > 0) {
+ fw_log(logger, OSGI_FRAMEWORK_LOG_WARNING, "Service Reference destroyed will usage count is %zu. Look for missing bundleContext_ungetService calls", usageCount);
+ }
+ if (refCount > 0) {
+ fw_log(logger, OSGI_FRAMEWORK_LOG_WARNING, "Dangling service reference. Reference count is %zu. Look for missing bundleContext_ungetServiceReference", refCount);
}
- celixThreadMutex_unlock(®istry->referencesMapMutex);
-
- return status;
}
-celix_status_t serviceRegistry_ungetServiceReferences(service_registry_pt registry, bundle_pt owner) {
+
+celix_status_t serviceRegistry_clearReferencesFor(service_registry_pt registry, bundle_pt bundle) {
celix_status_t status = CELIX_SUCCESS;
- celixThreadMutex_lock(®istry->referencesMapMutex);
- array_list_pt references = hashMap_get(registry->serviceReferences, owner);
- celixThreadMutex_unlock(®istry->referencesMapMutex);
+ celixThreadMutex_lock(®istry->mutex);
+ hash_map_pt refsMap = hashMap_remove(registry->serviceReferences, bundle);
+ celixThreadMutex_unlock(®istry->mutex);
+
+ 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, usageCount, refCount);
+
+ while (usageCount > 0) {
+ serviceReference_decreaseUsage(ref);
+ serviceReference_getUsageCount(ref, &usageCount);
+ }
+
+ bool destroyed = false;
+ while (!destroyed) {
+ serviceReference_release(ref, &destroyed);
+ }
- if (references != NULL) {
- array_list_pt referencesClone = arrayList_clone(references);
- int refIdx = 0;
- for (refIdx = 0; refIdx < arrayList_size(referencesClone); refIdx++) {
- service_reference_pt reference = arrayList_get(referencesClone, refIdx);
- serviceRegistry_ungetServiceReference(registry, owner, reference);
}
- arrayList_destroy(referencesClone);
+ hashMapIterator_destroy(iter);
}
return status;
}
-celix_status_t serviceRegistry_getServicesInUse(service_registry_pt registry, bundle_pt bundle, array_list_pt *services) {
+
+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
celixThreadMutex_lock(®istry->mutex);
- array_list_pt usages = hashMap_get(registry->inUseMap, bundle);
- if (usages != NULL) {
- unsigned int i;
- arrayList_create(services);
-
- for (i = 0; i < arrayList_size(usages); i++) {
- usage_count_pt usage = arrayList_get(usages, i);
- arrayList_add(*services, usage->reference);
- }
- }
+
+ hash_map_pt refsMap = hashMap_get(registry->serviceReferences, bundle);
+
+ 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
celixThreadMutex_unlock(®istry->mutex);
+
+ *out = result;
+
return CELIX_SUCCESS;
}
-celix_status_t serviceRegistry_getService(service_registry_pt registry, bundle_pt bundle, service_reference_pt reference, void **service) {
+celix_status_t serviceRegistry_getService(service_registry_pt registry, bundle_pt bundle, service_reference_pt reference, void **out) {
celix_status_t status = CELIX_SUCCESS;
service_registration_pt registration = NULL;
- *service = NULL;
- usage_count_pt usage = NULL;
+
serviceReference_getServiceRegistration(reference, ®istration);
celixThreadMutex_lock(®istry->mutex);
if (serviceRegistration_isValid(registration)) {
- status = serviceRegistry_getUsageCount(registry, bundle, reference, &usage);
- if (usage == NULL) {
- status = serviceRegistry_addUsageCount(registry, bundle, reference, registration, &usage);
- }
- usage->count++;
- *service = usage->service;
- }
- celixThreadMutex_unlock(®istry->mutex);
-
- if ((usage != NULL) && (*service == NULL)) {
- status = serviceRegistration_getService(registration, bundle, service);
- }
- celixThreadMutex_lock(®istry->mutex);
- if ((!serviceRegistration_isValid(registration)) || (*service == NULL)) {
- serviceRegistry_flushUsageCount(registry, bundle, reference);
+ serviceReference_increaseUsage(reference);
+ serviceRegistration_getService(registration, bundle, out);
} else {
- usage->service = *service;
- }
+ *out = NULL; //invalid service registration
+ }
+
celixThreadMutex_unlock(®istry->mutex);
+
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 registration = NULL;
- usage_count_pt usage = NULL;
- serviceReference_getServiceRegistration(reference, ®istration);
-
- celixThreadMutex_lock(®istry->mutex);
-
- status = serviceRegistry_getUsageCount(registry, bundle, reference, &usage);
- if (usage == NULL) {
- celixThreadMutex_unlock(®istry->mutex);
- if (result) {
- *result = false;
- }
- return CELIX_SUCCESS;
- }
-
- if (usage->count == 1) {
- serviceRegistration_ungetService(registration, bundle, &usage->service);
- }
- usage->count--;
-
- if ((!serviceRegistration_isValid(registration)) || (usage->count <= 0)) {
- usage->service = NULL;
- serviceRegistry_flushUsageCount(registry, bundle, reference);
- }
-
- celixThreadMutex_unlock(®istry->mutex);
-
- if (result) {
- *result = true;
- }
+ celix_status_t subStatus = serviceReference_decreaseUsage(reference);
+ if (result) {
+ *result = (subStatus == CELIX_SUCCESS);
+ }
return status;
}
-void serviceRegistry_ungetServices(service_registry_pt registry, bundle_pt bundle) {
- array_list_pt fusages;
- array_list_pt usages;
- unsigned int i;
-
- celixThreadMutex_lock(®istry->mutex);
- usages = hashMap_get(registry->inUseMap, bundle);
- celixThreadMutex_unlock(®istry->mutex);
-
- if (usages == NULL || arrayList_isEmpty(usages)) {
- return;
- }
-
- // usage arrays?
- fusages = arrayList_clone(usages);
-
- for (i = 0; i < arrayList_size(fusages); i++) {
- usage_count_pt usage = arrayList_get(fusages, i);
- service_reference_pt reference = usage->reference;
- bool ungetResult = true;
- while (ungetResult) {
- serviceRegistry_ungetService(registry, bundle, reference, &ungetResult);
- }
- }
-
- arrayList_destroy(fusages);
-}
-
-array_list_pt serviceRegistry_getUsingBundles(service_registry_pt registry, service_reference_pt reference) {
- array_list_pt bundles = NULL;
- hash_map_iterator_pt iter;
- arrayList_create(&bundles);
-
- celixThreadMutex_lock(®istry->mutex);
- iter = hashMapIterator_create(registry->inUseMap);
- while (hashMapIterator_hasNext(iter)) {
- hash_map_entry_pt entry = hashMapIterator_nextEntry(iter);
- bundle_pt bundle = hashMapEntry_getKey(entry);
- array_list_pt usages = hashMapEntry_getValue(entry);
- unsigned int i;
- for (i = 0; i < arrayList_size(usages); i++) {
- usage_count_pt usage = arrayList_get(usages, i);
- bool equals = false;
- serviceReference_equals(usage->reference, reference, &equals);
- if (equals) {
- arrayList_add(bundles, bundle);
- }
- }
- }
- hashMapIterator_destroy(iter);
- celixThreadMutex_unlock(®istry->mutex);
- return bundles;
-}
-
celix_status_t serviceRegistry_addHooks(service_registry_pt registry, char *serviceName, void *serviceObject, service_registration_pt registration) {
celix_status_t status = CELIX_SUCCESS;
@@ -653,7 +501,7 @@ celix_status_t serviceRegistry_getListenerHooks(service_registry_pt registry, bu
for (i = 0; i < arrayList_size(registry->listenerHooks); i++) {
service_registration_pt registration = arrayList_get(registry->listenerHooks, i);
service_reference_pt reference = NULL;
- serviceRegistry_createServiceReference(registry, owner, registration, &reference);
+ serviceRegistry_getServiceReference(registry, owner, registration, &reference);
arrayList_add(*hooks, reference);
}
celixThreadMutex_unlock(®istry->mutex);
http://git-wip-us.apache.org/repos/asf/celix/blob/592d65f9/framework/private/src/service_tracker.c
----------------------------------------------------------------------
diff --git a/framework/private/src/service_tracker.c b/framework/private/src/service_tracker.c
index b81b4d0..b5edbd6 100644
--- a/framework/private/src/service_tracker.c
+++ b/framework/private/src/service_tracker.c
@@ -26,6 +26,8 @@
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
+#include <service_reference_private.h>
+#include <framework_private.h>
#include "service_tracker_private.h"
#include "bundle_context.h"
@@ -33,9 +35,15 @@
#include "service_reference.h"
#include "celix_log.h"
-static celix_status_t serviceTracker_addingService(service_tracker_pt tracker, service_reference_pt reference, void **service);
+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, char * service, service_tracker_customizer_pt customizer, service_tracker_pt *tracker) {
celix_status_t status = CELIX_SUCCESS;
@@ -214,6 +222,8 @@ void serviceTracker_serviceChanged(service_listener_pt listener, service_event_p
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;
@@ -221,6 +231,7 @@ void serviceTracker_serviceChanged(service_listener_pt listener, service_event_p
serviceTracker_untrack(tracker, event->reference, event);
break;
case OSGI_FRAMEWORK_SERVICE_EVENT_MODIFIED_ENDMATCH:
+ //TODO
break;
}
}
@@ -229,51 +240,32 @@ static celix_status_t serviceTracker_track(service_tracker_pt tracker, service_r
celix_status_t status = CELIX_SUCCESS;
tracked_pt tracked = NULL;
- int found = -1;
+ bool found = false;
unsigned int i;
for (i = 0; i < arrayList_size(tracker->tracked); i++) {
bool equals = false;
tracked = (tracked_pt) arrayList_get(tracker->tracked, i);
serviceReference_equals(reference, tracked->reference, &equals);
if (equals) {
- found = 0;
+ found = true;
break;
}
}
- if (found) {
+ if (!found /*new*/) {
void * service = NULL;
- status = serviceTracker_addingService(tracker, reference, &service);
+ status = serviceTracker_invokeAddingService(tracker, reference, &service);
if (status == CELIX_SUCCESS) {
if (service != NULL) {
- tracked = (tracked_pt) malloc(sizeof(*tracked));
+ tracked = (tracked_pt) calloc(1, sizeof(*tracked));
tracked->reference = reference;
tracked->service = service;
arrayList_add(tracker->tracked, tracked);
- 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, reference, service);
- }
- }
+ serviceTracker_invokeAddService(tracker, reference, service);
}
}
} else {
- 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, reference, tracked->service);
- }
- }
+ status = serviceTracker_invokeModifiedService(tracker, reference, tracked->service);
}
framework_logIfError(logger, status, NULL, "Cannot track reference");
@@ -281,7 +273,39 @@ static celix_status_t serviceTracker_track(service_tracker_pt tracker, service_r
return status;
}
-static celix_status_t serviceTracker_addingService(service_tracker_pt tracker, service_reference_pt reference, void **service) {
+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) {
@@ -289,19 +313,21 @@ static celix_status_t serviceTracker_addingService(service_tracker_pt tracker,
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) {
- 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);
- }
- }
+ if (function != NULL) {
+ status = function(handle, reference, service);
+ } else {
+ status = bundleContext_getService(tracker->context, reference, service);
+ }
}
} else {
- status = bundleContext_getService(tracker->context, reference, service);
- }
+ status = bundleContext_getService(tracker->context, reference, service);
+ }
framework_logIfError(logger, status, NULL, "Cannot handle addingService");
@@ -312,7 +338,6 @@ static celix_status_t serviceTracker_untrack(service_tracker_pt tracker, service
celix_status_t status = CELIX_SUCCESS;
tracked_pt tracked = NULL;
unsigned int i;
- bool result = false;
for (i = 0; i < arrayList_size(tracker->tracked); i++) {
bool equals;
@@ -320,28 +345,10 @@ static celix_status_t serviceTracker_untrack(service_tracker_pt tracker, service
serviceReference_equals(reference, tracked->reference, &equals);
if (equals) {
arrayList_remove(tracker->tracked, i);
- if (status == CELIX_SUCCESS) {
- 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, reference, tracked->service);
- } else {
- status = bundleContext_ungetService(tracker->context, reference, &result);
- }
- } else {
- status = bundleContext_ungetService(tracker->context, reference, &result);
- }
-
- // ungetServiceReference
- bundleContext_ungetServiceReference(tracker->context, reference);
- //break;
- }
+ serviceTracker_invokeRemovingService(tracker, tracked->reference, tracked->service);
+ bundleContext_ungetService(tracker->context, tracked->reference, tracked->service);
free(tracked);
+ break;
}
}
@@ -349,3 +356,31 @@ static celix_status_t serviceTracker_untrack(service_tracker_pt tracker, service
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/592d65f9/framework/public/include/service_reference.h
----------------------------------------------------------------------
diff --git a/framework/public/include/service_reference.h b/framework/public/include/service_reference.h
index f1e1427..b99359e 100644
--- a/framework/public/include/service_reference.h
+++ b/framework/public/include/service_reference.h
@@ -39,8 +39,6 @@ FRAMEWORK_EXPORT celix_status_t serviceReference_getBundle(service_reference_pt
FRAMEWORK_EXPORT bool serviceReference_isAssignableTo(service_reference_pt reference, bundle_pt requester, char * serviceName);
-FRAMEWORK_EXPORT celix_status_t serviceReference_getUsingBundles(service_reference_pt reference, array_list_pt *bundles);
-
FRAMEWORK_EXPORT celix_status_t serviceReference_getProperty(service_reference_pt reference, char *key, char **value);
FRAMEWORK_EXPORT celix_status_t serviceReference_getPropertyKeys(service_reference_pt reference, char **keys[], unsigned int *size);
http://git-wip-us.apache.org/repos/asf/celix/blob/592d65f9/framework/public/include/service_registration.h
----------------------------------------------------------------------
diff --git a/framework/public/include/service_registration.h b/framework/public/include/service_registration.h
index 5775154..22685a9 100644
--- a/framework/public/include/service_registration.h
+++ b/framework/public/include/service_registration.h
@@ -40,6 +40,5 @@ typedef struct serviceRegistration * service_registration_pt;
FRAMEWORK_EXPORT celix_status_t serviceRegistration_unregister(service_registration_pt registration);
FRAMEWORK_EXPORT celix_status_t serviceRegistration_getProperties(service_registration_pt registration, properties_pt *properties);
FRAMEWORK_EXPORT celix_status_t serviceRegistration_setProperties(service_registration_pt registration, properties_pt properties);
-FRAMEWORK_EXPORT celix_status_t serviceRegistration_getServiceReferences(service_registration_pt registration, array_list_pt *references);
#endif /* SERVICE_REGISTRATION_H_ */
http://git-wip-us.apache.org/repos/asf/celix/blob/592d65f9/framework/public/include/service_registry.h
----------------------------------------------------------------------
diff --git a/framework/public/include/service_registry.h b/framework/public/include/service_registry.h
index 7a33f37..5c013cc 100644
--- a/framework/public/include/service_registry.h
+++ b/framework/public/include/service_registry.h
@@ -43,21 +43,24 @@ celix_status_t serviceRegistry_destroy(service_registry_pt registry);
celix_status_t serviceRegistry_getRegisteredServices(service_registry_pt registry, bundle_pt bundle, array_list_pt *services);
celix_status_t serviceRegistry_getServicesInUse(service_registry_pt registry, bundle_pt bundle, array_list_pt *services);
+
celix_status_t serviceRegistry_registerService(service_registry_pt registry, bundle_pt bundle, char * serviceName, void * serviceObject, properties_pt dictionary, service_registration_pt *registration);
celix_status_t serviceRegistry_registerServiceFactory(service_registry_pt registry, bundle_pt bundle, char * serviceName, service_factory_pt factory, properties_pt dictionary, service_registration_pt *registration);
+
celix_status_t serviceRegistry_unregisterService(service_registry_pt registry, bundle_pt bundle, service_registration_pt registration);
-celix_status_t serviceRegistry_unregisterServices(service_registry_pt registry, bundle_pt bundle);
+celix_status_t serviceRegistry_clearServiceRegistrations(service_registry_pt registry, bundle_pt bundle);
+
+celix_status_t serviceRegistry_getServiceReference(service_registry_pt registry, bundle_pt bundle, service_registration_pt registration, service_reference_pt *reference);
celix_status_t serviceRegistry_getServiceReferences(service_registry_pt registry, bundle_pt bundle, const char *serviceName, filter_pt filter, array_list_pt *references);
+celix_status_t serviceRegistry_ungetServiceReference(service_registry_pt registry, bundle_pt bundle, service_reference_pt reference);
+
celix_status_t serviceRegistry_getService(service_registry_pt registry, bundle_pt bundle, service_reference_pt reference, void **service);
celix_status_t serviceRegistry_ungetService(service_registry_pt registry, bundle_pt bundle, service_reference_pt reference, bool *result);
-void serviceRegistry_ungetServices(service_registry_pt registry, bundle_pt bundle);
-array_list_pt serviceRegistry_getUsingBundles(service_registry_pt registry, service_reference_pt reference);
-service_registration_pt serviceRegistry_findRegistration(service_registry_pt registry, service_reference_pt reference);
-celix_status_t serviceRegistry_ungetServiceReference(service_registry_pt registry, bundle_pt bundle, service_reference_pt reference);
-celix_status_t serviceRegistry_ungetServiceReferences(service_registry_pt registry, bundle_pt bundle);
-celix_status_t serviceRegistry_createServiceReference(service_registry_pt registry, bundle_pt bundle, service_registration_pt registration, service_reference_pt *reference);
-celix_status_t serviceRegistry_getServiceReferencesForRegistration(service_registry_pt registry, service_registration_pt registration, array_list_pt *references);
+celix_status_t serviceRegistry_clearReferencesFor(service_registry_pt registry, bundle_pt bundle);
+
+
+service_registration_pt serviceRegistry_findRegistration(service_registry_pt registry, service_reference_pt reference);
celix_status_t serviceRegistry_getListenerHooks(service_registry_pt registry, bundle_pt bundle, array_list_pt *hooks);