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/17 12:57:38 UTC
[21/38] celix git commit: CELIX-272: Add callback structure for serv
reg/ref instead of dependency to serv registry. Fix in
serviceRegistry_destroy
CELIX-272: Add callback structure for serv reg/ref instead of dependency to serv registry. Fix in serviceRegistry_destroy
Project: http://git-wip-us.apache.org/repos/asf/celix/repo
Commit: http://git-wip-us.apache.org/repos/asf/celix/commit/eae936a3
Tree: http://git-wip-us.apache.org/repos/asf/celix/tree/eae936a3
Diff: http://git-wip-us.apache.org/repos/asf/celix/diff/eae936a3
Branch: refs/heads/develop
Commit: eae936a3b8e0501c68bb7f4964288ed34cccff7c
Parents: 5e30209
Author: Pepijn Noltes <pe...@gmail.com>
Authored: Mon Nov 16 16:15:45 2015 +0100
Committer: Pepijn Noltes <pe...@gmail.com>
Committed: Mon Nov 16 16:15:45 2015 +0100
----------------------------------------------------------------------
.../private/include/registry_callback_private.h | 42 ++++++++
.../private/include/service_reference_private.h | 5 +-
.../include/service_registration_private.h | 7 +-
.../private/include/service_registry_private.h | 2 +
framework/private/src/service_reference.c | 37 ++++++-
framework/private/src/service_registration.c | 2 +-
framework/private/src/service_registry.c | 106 +++++++++++++------
framework/public/include/service_reference.h | 1 +
8 files changed, 157 insertions(+), 45 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/celix/blob/eae936a3/framework/private/include/registry_callback_private.h
----------------------------------------------------------------------
diff --git a/framework/private/include/registry_callback_private.h b/framework/private/include/registry_callback_private.h
new file mode 100644
index 0000000..146a1d1
--- /dev/null
+++ b/framework/private/include/registry_callback_private.h
@@ -0,0 +1,42 @@
+/**
+ *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_private.h
+ *
+ * \date Nov 16, 2015
+ * \author <a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
+ * \copyright Apache License, Version 2.0
+ */
+
+
+#ifndef REGISTRY_CALLBACK_H_
+#define REGISTRY_CALLBACK_H_
+
+#include "celix_errno.h"
+#include "service_reference.h"
+#include "service_registration.h"
+
+typedef struct registry_callback_struct {
+ void *handle;
+ celix_status_t (*getUsingBundles)(void *handle, service_registration_pt reg, array_list_pt *bundles);
+ celix_status_t (*unregister)(void *handle, bundle_pt bundle, service_registration_pt reg);
+ celix_status_t (*modified)(void *handle, service_registration_pt registration, properties_pt oldProperties);
+} registry_callback_t;
+
+#endif /* REGISTRY_CALLBACK_H_ */
http://git-wip-us.apache.org/repos/asf/celix/blob/eae936a3/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 7eea45e..b0b8afb 100644
--- a/framework/private/include/service_reference_private.h
+++ b/framework/private/include/service_reference_private.h
@@ -28,9 +28,12 @@
#ifndef SERVICE_REFERENCE_PRIVATE_H_
#define SERVICE_REFERENCE_PRIVATE_H_
+#include "registry_callback_private.h"
#include "service_reference.h"
+
struct serviceReference {
+ registry_callback_t callback;
bundle_pt referenceOwner;
struct serviceRegistration * registration;
bundle_pt registrationBundle;
@@ -42,7 +45,7 @@ struct serviceReference {
celix_thread_rwlock_t lock;
};
-celix_status_t serviceReference_create(bundle_pt referenceOwner, service_registration_pt registration, service_reference_pt *reference);
+celix_status_t serviceReference_create(registry_callback_t callback, 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);
http://git-wip-us.apache.org/repos/asf/celix/blob/eae936a3/framework/private/include/service_registration_private.h
----------------------------------------------------------------------
diff --git a/framework/private/include/service_registration_private.h b/framework/private/include/service_registration_private.h
index 2b1bf6c..4b48e70 100644
--- a/framework/private/include/service_registration_private.h
+++ b/framework/private/include/service_registration_private.h
@@ -28,14 +28,9 @@
#ifndef SERVICE_REGISTRATION_PRIVATE_H_
#define SERVICE_REGISTRATION_PRIVATE_H_
+#include "registry_callback_private.h"
#include "service_registration.h"
-typedef struct registry_callback_struct {
- void *handle;
- celix_status_t (*unregister)(void *handle, bundle_pt bundle, service_registration_pt reg);
- celix_status_t (*modified)(void *handle, service_registration_pt registration, properties_pt oldProperties);
-} registry_callback_t;
-
struct serviceRegistration {
registry_callback_t callback;
http://git-wip-us.apache.org/repos/asf/celix/blob/eae936a3/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 f3edd17..28c6148 100644
--- a/framework/private/include/service_registry_private.h
+++ b/framework/private/include/service_registry_private.h
@@ -28,10 +28,12 @@
#ifndef SERVICE_REGISTRY_PRIVATE_H_
#define SERVICE_REGISTRY_PRIVATE_H_
+#include "registry_callback_private.h"
#include "service_registry.h"
struct serviceRegistry {
framework_pt framework;
+ registry_callback_t callback;
hash_map_pt serviceRegistrations; //key = bundle (reg owner), value = registration
hash_map_pt serviceReferences; //key = bundle, value = map (key = registration, value = reference)
http://git-wip-us.apache.org/repos/asf/celix/blob/eae936a3/framework/private/src/service_reference.c
----------------------------------------------------------------------
diff --git a/framework/private/src/service_reference.c b/framework/private/src/service_reference.c
index 2f829c2..dfbafd0 100644
--- a/framework/private/src/service_reference.c
+++ b/framework/private/src/service_reference.c
@@ -38,14 +38,14 @@
static void serviceReference_destroy(service_reference_pt);
static void serviceReference_logWarningUsageCountBelowZero(service_reference_pt ref);
-celix_status_t serviceReference_create(bundle_pt referenceOwner, service_registration_pt registration, service_reference_pt *out) {
+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 {
- serviceRegistration_retain(registration);
+ ref->callback = callback;
ref->referenceOwner = referenceOwner;
ref->registration = registration;
ref->service = NULL;
@@ -95,7 +95,7 @@ celix_status_t serviceReference_release(service_reference_pt ref, bool *out) {
}
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);
+ //fw_log(logger, OSGI_FRAMEWORK_LOG_DEBUG, "Destroying service reference %p\n", ref);
size_t local = 0;
celixThreadRwlock_writeLock(&ref->lock);
ref->usageCount += 1;
@@ -321,3 +321,34 @@ unsigned int serviceReference_hashCode(void *referenceP) {
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/eae936a3/framework/private/src/service_registration.c
----------------------------------------------------------------------
diff --git a/framework/private/src/service_registration.c b/framework/private/src/service_registration.c
index dc8ae9b..f1fea32 100644
--- a/framework/private/src/service_registration.c
+++ b/framework/private/src/service_registration.c
@@ -103,7 +103,7 @@ void serviceRegistration_release(service_registration_pt registration) {
}
static celix_status_t serviceRegistration_destroy(service_registration_pt registration) {
- fw_log(logger, OSGI_FRAMEWORK_LOG_DEBUG, "Destroying service registration %p\n", registration);
+ //fw_log(logger, OSGI_FRAMEWORK_LOG_DEBUG, "Destroying service registration %p\n", registration);
free(registration->className);
registration->className = NULL;
http://git-wip-us.apache.org/repos/asf/celix/blob/eae936a3/framework/private/src/service_registry.c
----------------------------------------------------------------------
diff --git a/framework/private/src/service_registry.c b/framework/private/src/service_registry.c
index 13fe01a..9f90025 100644
--- a/framework/private/src/service_registry.c
+++ b/framework/private/src/service_registry.c
@@ -26,6 +26,7 @@
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
+#include <assert.h>
#include "service_registry_private.h"
#include "service_registration_private.h"
@@ -44,6 +45,9 @@ static celix_status_t serviceRegistry_checkReference(service_registry_pt registr
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);
+
celix_status_t serviceRegistry_create(framework_pt framework, serviceChanged_function_pt serviceChanged, service_registry_pt *out) {
celix_status_t status;
@@ -51,7 +55,13 @@ celix_status_t serviceRegistry_create(framework_pt framework, serviceChanged_fun
if (reg == NULL) {
status = CELIX_ENOMEM;
} else {
- reg->serviceChanged = serviceChanged;
+
+ reg->callback.handle = reg;
+ reg->callback.getUsingBundles = NULL; /*TODO*/
+ 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 = 1l;
@@ -73,16 +83,25 @@ celix_status_t serviceRegistry_create(framework_pt framework, serviceChanged_fun
}
celix_status_t serviceRegistry_destroy(service_registry_pt registry) {
- celixThreadRwlock_writeLock(®istry->lock);
+ 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);
+ 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);
- registry->framework = NULL;
- registry->listenerHooks = NULL;
- registry->serviceChanged = NULL;
- registry->serviceReferences = NULL;
- registry->serviceRegistrations = NULL;
+ hashMap_destroy(registry->deletedServiceReferences, false, false);
+
free(registry);
return CELIX_SUCCESS;
@@ -128,15 +147,10 @@ celix_status_t serviceRegistry_registerServiceFactory(service_registry_pt regist
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) {
array_list_pt regs;
- registry_callback_t callback;
- callback.handle = registry;
- callback.unregister = (void *) serviceRegistry_unregisterService;
- callback.modified = (void *) serviceRegistry_servicePropertiesModified;
-
if (isFactory) {
- *registration = serviceRegistration_createServiceFactory(callback, bundle, serviceName, ++registry->currentServiceId, serviceObject, dictionary);
+ *registration = serviceRegistration_createServiceFactory(registry->callback, bundle, serviceName, ++registry->currentServiceId, serviceObject, dictionary);
} else {
- *registration = serviceRegistration_create(callback, bundle, serviceName, ++registry->currentServiceId, serviceObject, dictionary);
+ *registration = serviceRegistration_create(registry->callback, bundle, serviceName, ++registry->currentServiceId, serviceObject, dictionary);
}
serviceRegistry_addHooks(registry, serviceName, serviceObject, *registration);
@@ -183,7 +197,8 @@ celix_status_t serviceRegistry_unregisterService(service_registry_pt registry, b
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);
+ service_reference_pt ref = refsMap != NULL ?
+ hashMap_get(refsMap, registration) : NULL;
if (ref != NULL) {
serviceReference_invalidate(ref);
}
@@ -247,7 +262,7 @@ celix_status_t serviceRegistry_getServiceReference(service_registry_pt registry,
if (ref == NULL) {
status = serviceRegistration_getBundle(registration, &bundle);
if (status == CELIX_SUCCESS) {
- status = serviceReference_create(owner, registration, &ref);
+ status = serviceReference_create(registry->callback, owner, registration, &ref);
}
if (status == CELIX_SUCCESS) {
hashMap_put(references, registration, ref);
@@ -314,6 +329,7 @@ celix_status_t serviceRegistry_getServiceReferences(service_registry_pt registry
}
if (matched) {
if (serviceRegistration_isValid(registration)) {
+ serviceRegistration_retain(registration);
arrayList_add(matchingRegistrations, registration);
}
}
@@ -328,12 +344,13 @@ celix_status_t serviceRegistry_getServiceReferences(service_registry_pt registry
for (i = 0; i < size; i += 1) {
service_registration_pt reg = arrayList_get(matchingRegistrations, i);
service_reference_pt reference = NULL;
- status = serviceRegistry_getServiceReference(registry, owner, reg, &reference);
- if (status == CELIX_SUCCESS) {
+ celix_status_t subStatues = serviceRegistry_getServiceReference(registry, owner, reg, &reference);
+ if (subStatues == CELIX_SUCCESS) {
arrayList_add(references, reference);
} else {
- break;
+ status = CELIX_BUNDLE_EXCEPTION;
}
+ serviceRegistration_release(reg);
}
arrayList_destroy(matchingRegistrations);
}
@@ -357,6 +374,7 @@ celix_status_t serviceRegistry_ungetServiceReference(service_registry_pt registr
service_registration_pt reg = NULL;
reference_status_t refStatus;
+ celixThreadRwlock_writeLock(®istry->lock);
serviceRegistry_checkReference(registry, reference, &refStatus);
if (refStatus == REF_ACTIVE) {
serviceReference_getUsageCount(reference, &count);
@@ -368,19 +386,32 @@ celix_status_t serviceRegistry_ungetServiceReference(service_registry_pt registr
}
- celixThreadRwlock_writeLock(®istry->lock);
hash_map_pt refsMap = hashMap_get(registry->serviceReferences, bundle);
hashMap_remove(refsMap, reg);
- hashMap_put(registry->deletedServiceReferences, reference, (void *)true);
- celixThreadRwlock_unlock(®istry->lock);
+ int size = hashMap_size(refsMap);
+ if (size == 0) {
+ hashMap_destroy(refsMap, false, false);
+ hashMap_remove(registry->serviceReferences, bundle);
+ }
+ serviceRegistry_setReferenceStatus(registry, reference, true);
}
} else {
serviceRegistry_logIllegalReference(registry, reference, refStatus);
}
+ celixThreadRwlock_unlock(®istry->lock);
return status;
}
+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) {
@@ -389,17 +420,21 @@ static void serviceRegistry_logIllegalReference(service_registry_pt registry __a
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;
- reference_status_t refStatus = REF_UNKNOWN;
- celixThreadRwlock_readLock(®istry->lock);
- if (hashMap_containsKey(registry->deletedServiceReferences, ref)) {
- bool deleted = (bool) hashMap_get(registry->deletedServiceReferences, ref);
- refStatus = deleted ? REF_DELETED : REF_ACTIVE;
- }
- celixThreadRwlock_unlock(®istry->lock);
+ if (registry->checkDeletedReferences) {
+ reference_status_t refStatus = REF_UNKNOWN;
- *out = refStatus;
+ 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;
}
@@ -440,7 +475,7 @@ celix_status_t serviceRegistry_clearReferencesFor(service_registry_pt registry,
while (!destroyed) {
serviceReference_release(ref, &destroyed);
}
- hashMap_put(registry->deletedServiceReferences, ref, (void *)true);
+ serviceRegistry_setReferenceStatus(registry, ref, true);
}
hashMapIterator_destroy(iter);
@@ -484,10 +519,11 @@ celix_status_t serviceRegistry_getService(service_registry_pt registry, bundle_p
void *service = NULL;
reference_status_t refStatus;
- serviceRegistry_checkReference(registry, reference, &refStatus);
+
+ celixThreadRwlock_readLock(®istry->lock);
+ serviceRegistry_checkReference(registry, reference, &refStatus);
if (refStatus == REF_ACTIVE) {
- celixThreadRwlock_readLock(®istry->lock);
serviceReference_getServiceRegistration(reference, ®istration);
if (serviceRegistration_isValid(registration)) {
@@ -501,11 +537,11 @@ celix_status_t serviceRegistry_getService(service_registry_pt registry, bundle_p
} else {
*out = NULL; //invalid service registration
}
- celixThreadRwlock_unlock(®istry->lock);
} else {
serviceRegistry_logIllegalReference(registry, reference, refStatus);
status = CELIX_BUNDLE_EXCEPTION;
}
+ celixThreadRwlock_unlock(®istry->lock);
return status;
}
@@ -518,7 +554,9 @@ celix_status_t serviceRegistry_ungetService(service_registry_pt registry, bundle
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);
http://git-wip-us.apache.org/repos/asf/celix/blob/eae936a3/framework/public/include/service_reference.h
----------------------------------------------------------------------
diff --git a/framework/public/include/service_reference.h b/framework/public/include/service_reference.h
index b99359e..f6cb9e5 100644
--- a/framework/public/include/service_reference.h
+++ b/framework/public/include/service_reference.h
@@ -48,5 +48,6 @@ FRAMEWORK_EXPORT celix_status_t serviceReference_equals(service_reference_pt ref
FRAMEWORK_EXPORT unsigned int serviceReference_hashCode(void *referenceP);
FRAMEWORK_EXPORT int serviceReference_equals2(void *reference1, void *reference2);
FRAMEWORK_EXPORT celix_status_t serviceReference_compareTo(service_reference_pt reference, service_reference_pt compareTo, int *compare);
+FRAMEWORK_EXPORT celix_status_t serviceReference_getUsingBundles(service_reference_pt ref, array_list_pt *out);
#endif /* SERVICE_REFERENCE_H_ */