You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@celix.apache.org by bp...@apache.org on 2015/12/01 17:59:00 UTC
celix git commit: CELIX-310: serviceRegistry_getRegisteredServices
deadlock fix
Repository: celix
Updated Branches:
refs/heads/develop e3b4e59d2 -> 7a6d31f42
CELIX-310: serviceRegistry_getRegisteredServices deadlock fix
Project: http://git-wip-us.apache.org/repos/asf/celix/repo
Commit: http://git-wip-us.apache.org/repos/asf/celix/commit/7a6d31f4
Tree: http://git-wip-us.apache.org/repos/asf/celix/tree/7a6d31f4
Diff: http://git-wip-us.apache.org/repos/asf/celix/diff/7a6d31f4
Branch: refs/heads/develop
Commit: 7a6d31f42a84e7bbc960711fed3a4a0f91f72e18
Parents: e3b4e59
Author: Bjoern Petri <bp...@apache.org>
Authored: Tue Dec 1 17:58:06 2015 +0100
Committer: Bjoern Petri <bp...@apache.org>
Committed: Tue Dec 1 17:58:06 2015 +0100
----------------------------------------------------------------------
framework/private/src/service_registry.c | 41 ++++++++++++++++-----------
1 file changed, 24 insertions(+), 17 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/celix/blob/7a6d31f4/framework/private/src/service_registry.c
----------------------------------------------------------------------
diff --git a/framework/private/src/service_registry.c b/framework/private/src/service_registry.c
index b366f53..09fd340 100644
--- a/framework/private/src/service_registry.c
+++ b/framework/private/src/service_registry.c
@@ -53,6 +53,7 @@ static void serviceRegistry_logIllegalReference(service_registry_pt registry, se
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;
@@ -119,7 +120,7 @@ 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 status = CELIX_SUCCESS;
- celixThreadRwlock_readLock(®istry->lock);
+ celixThreadRwlock_writeLock(®istry->lock);
array_list_pt regs = (array_list_pt) hashMap_get(registry->serviceRegistrations, bundle);
if (regs != NULL) {
@@ -130,7 +131,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_getServiceReference(registry, bundle, reg, &reference);
+ status = serviceRegistry_getServiceReference_internal(registry, bundle, reg, &reference);
if (status == CELIX_SUCCESS) {
arrayList_add(*services, reference);
}
@@ -276,17 +277,25 @@ static void serviceRegistry_logWarningServiceRegistration(service_registry_pt re
}
celix_status_t serviceRegistry_getServiceReference(service_registry_pt registry, bundle_pt owner,
- service_registration_pt registration,
- service_reference_pt *out) {
+ 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;
-
- //LOCK
- celixThreadRwlock_writeLock(®istry->lock);
-
references = hashMap_get(registry->serviceReferences, owner);
if (references == NULL) {
references = hashMap_create(NULL, NULL, NULL, NULL);
@@ -308,10 +317,6 @@ celix_status_t serviceRegistry_getServiceReference(service_registry_pt registry,
serviceReference_retain(ref);
}
- //UNLOCK
- celixThreadRwlock_unlock(®istry->lock);
-
-
if (status == CELIX_SUCCESS) {
*out = ref;
}
@@ -328,8 +333,6 @@ celix_status_t serviceRegistry_getServiceReferences(service_registry_pt registry
array_list_pt references = NULL;
array_list_pt matchingRegistrations = NULL;
bool matchResult;
- unsigned int i;
- int size;
status = arrayList_create(&references);
status = CELIX_DO_IF(status, arrayList_create(&matchingRegistrations));
@@ -376,7 +379,9 @@ celix_status_t serviceRegistry_getServiceReferences(service_registry_pt registry
hashMapIterator_destroy(iterator);
if (status == CELIX_SUCCESS) {
- size = arrayList_size(matchingRegistrations);
+ 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;
@@ -690,11 +695,13 @@ celix_status_t serviceRegistry_removeHook(service_registry_pt registry, service_
celix_status_t serviceRegistry_getListenerHooks(service_registry_pt registry, bundle_pt owner, array_list_pt *out) {
celix_status_t status;
array_list_pt result;
- unsigned int i;
status = arrayList_create(&result);
if (status == CELIX_SUCCESS) {
- for (i = 0; i < arrayList_size(registry->listenerHooks); i += 1) {
+ 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);