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:18 UTC

[01/38] celix git commit: CELIX-272: Added locking/threading example to test synchronization solutions and isues. Introduced release/retain concept for service reference and service registration.

Repository: celix
Updated Branches:
  refs/heads/develop 0366d0262 -> 61b082893


http://git-wip-us.apache.org/repos/asf/celix/blob/e0231e51/framework/private/src/service_registration.c
----------------------------------------------------------------------
diff --git a/framework/private/src/service_registration.c b/framework/private/src/service_registration.c
index 1817784..718a633 100644
--- a/framework/private/src/service_registration.c
+++ b/framework/private/src/service_registration.c
@@ -26,6 +26,7 @@
 #include <stdlib.h>
 #include <stdio.h>
 #include <string.h>
+#include <assert.h>
 
 #include "service_registration_private.h"
 #include "constants.h"
@@ -35,9 +36,9 @@
 #include "celix_threads.h"
 
 static celix_status_t serviceRegistration_initializeProperties(service_registration_pt registration, properties_pt properties);
-
-celix_status_t serviceRegistration_createInternal(service_registry_pt registry, bundle_pt bundle, char * serviceName, long serviceId,
+static celix_status_t serviceRegistration_createInternal(service_registry_pt registry, bundle_pt bundle, char * serviceName, long serviceId,
         void * serviceObject, properties_pt dictionary, bool isFactory, service_registration_pt *registration);
+static celix_status_t serviceRegistration_destroy(service_registration_pt registration);
 
 service_registration_pt serviceRegistration_create(service_registry_pt registry, bundle_pt bundle, char * serviceName, long serviceId, void * serviceObject, properties_pt dictionary) {
     service_registration_pt registration = NULL;
@@ -51,39 +52,61 @@ service_registration_pt serviceRegistration_createServiceFactory(service_registr
     return registration;
 }
 
-celix_status_t serviceRegistration_createInternal(service_registry_pt registry, bundle_pt bundle, char * serviceName, long serviceId,
-        void * serviceObject, properties_pt dictionary, bool isFactory, service_registration_pt *registration) {
+static celix_status_t serviceRegistration_createInternal(service_registry_pt registry, bundle_pt bundle, char * serviceName, long serviceId,
+        void * serviceObject, properties_pt dictionary, bool isFactory, service_registration_pt *out) {
     celix_status_t status = CELIX_SUCCESS;
 
-    *registration = malloc(sizeof(**registration));
-    if (*registration) {
-        (*registration)->services = NULL;
-        (*registration)->nrOfServices = 0;
-		(*registration)->isServiceFactory = isFactory;
-		(*registration)->registry = registry;
-		(*registration)->className = strdup(serviceName);
-		(*registration)->bundle = bundle;
-
-		(*registration)->serviceId = serviceId;
-		(*registration)->svcObj = serviceObject;
+	service_registration_pt  reg = calloc(1, sizeof(*reg));
+    if (reg) {
+        reg->services = NULL;
+        reg->nrOfServices = 0;
+		reg->isServiceFactory = isFactory;
+		reg->registry = registry;
+		reg->className = strdup(serviceName);
+		reg->bundle = bundle;
+		reg->refCount = 1;
+
+		reg->serviceId = serviceId;
+		reg->svcObj = serviceObject;
 		if (isFactory) {
-			(*registration)->serviceFactory = (service_factory_pt) (*registration)->svcObj;
+			reg->serviceFactory = (service_factory_pt) reg->svcObj;
 		} else {
-			(*registration)->serviceFactory = NULL;
+			reg->serviceFactory = NULL;
 		}
 
-		(*registration)->isUnregistering = false;
-		celixThreadMutex_create(&(*registration)->mutex, NULL);
+		reg->isUnregistering = false;
+		celixThreadMutex_create(&reg->mutex, NULL);
 
-		serviceRegistration_initializeProperties(*registration, dictionary);
+		serviceRegistration_initializeProperties(reg, dictionary);
     } else {
     	status = CELIX_ENOMEM;
     }
 
+	if (status == CELIX_SUCCESS) {
+		*out = reg;
+	}
+
 	return status;
 }
 
-celix_status_t serviceRegistration_destroy(service_registration_pt registration) {
+void serviceRegistration_retain(service_registration_pt registration) {
+	celixThreadMutex_lock(&registration->mutex);
+	registration->refCount += 1;
+	celixThreadMutex_unlock(&registration->mutex);
+}
+
+void serviceRegistration_release(service_registration_pt registration) {
+	celixThreadMutex_lock(&registration->mutex);
+	assert(registration->refCount > 0);
+	registration->refCount -= 1;
+	if (registration->refCount == 0) {
+		serviceRegistration_destroy(registration);
+	} else {
+		celixThreadMutex_unlock(&registration->mutex);
+	}
+}
+
+static celix_status_t serviceRegistration_destroy(service_registration_pt registration) {
     free(registration->className);
 	registration->className = NULL;
 	registration->registry = NULL;
@@ -99,7 +122,7 @@ celix_status_t serviceRegistration_destroy(service_registration_pt registration)
 }
 
 static celix_status_t serviceRegistration_initializeProperties(service_registration_pt registration, properties_pt dictionary) {
-	char * sId = (char *)malloc(sizeof(registration->serviceId) + 1);
+    char sId[32];
 
 	if (dictionary == NULL) {
 		dictionary = properties_create();
@@ -107,15 +130,13 @@ static celix_status_t serviceRegistration_initializeProperties(service_registrat
 
 	registration->properties = dictionary;
 
-	sprintf(sId, "%ld", registration->serviceId);
+	snprintf(sId, 32, "%ld", registration->serviceId);
 	properties_set(dictionary, (char *) OSGI_FRAMEWORK_SERVICE_ID, sId);
 
 	if (properties_get(dictionary, (char *) OSGI_FRAMEWORK_OBJECTCLASS) == NULL) {
 		properties_set(dictionary, (char *) OSGI_FRAMEWORK_OBJECTCLASS, registration->className);
 	}
 
-	free(sId);
-
 	return CELIX_SUCCESS;
 }
 

http://git-wip-us.apache.org/repos/asf/celix/blob/e0231e51/framework/private/src/service_registry.c
----------------------------------------------------------------------
diff --git a/framework/private/src/service_registry.c b/framework/private/src/service_registry.c
index f9cea4e..ec72f6d 100644
--- a/framework/private/src/service_registry.c
+++ b/framework/private/src/service_registry.c
@@ -38,7 +38,9 @@
 #include "celix_log.h"
 
 static celix_status_t serviceRegistry_getUsageCount(service_registry_pt registry, bundle_pt bundle, service_reference_pt reference, usage_count_pt *usageCount);
-static celix_status_t serviceRegistry_addUsageCount(service_registry_pt registry, bundle_pt bundle, service_reference_pt reference, usage_count_pt *usageCount);
+static celix_status_t serviceRegistry_addUsageCount(service_registry_pt registry, bundle_pt bundle,
+                                                   service_reference_pt reference,
+                                                   service_registration_pt registration, usage_count_pt *usageCount);
 static celix_status_t serviceRegistry_flushUsageCount(service_registry_pt registry, bundle_pt bundle, service_reference_pt reference);
 
 celix_status_t serviceRegistry_registerServiceInternal(service_registry_pt registry, bundle_pt bundle, char * serviceName, void * serviceObject, properties_pt dictionary, bool isFactory, service_registration_pt *registration);
@@ -108,12 +110,17 @@ static celix_status_t serviceRegistry_getUsageCount(service_registry_pt registry
 	return CELIX_SUCCESS;
 }
 
-static celix_status_t serviceRegistry_addUsageCount(service_registry_pt registry, bundle_pt bundle, service_reference_pt reference, usage_count_pt *usageCount) {
+static celix_status_t serviceRegistry_addUsageCount(service_registry_pt registry, bundle_pt bundle,
+                                                   service_reference_pt reference,
+                                                   service_registration_pt registration, usage_count_pt *usageCount) {
 	array_list_pt usages = hashMap_get(registry->inUseMap, bundle);
 	usage_count_pt usage = malloc(sizeof(*usage));
 	usage->reference = reference;
 	usage->count = 0;
 	usage->service = NULL;
+    usage->registration = registration;
+
+    serviceRegistration_retain(registration);
 
 	if (usages == NULL) {
 		arrayList_create(&usages);
@@ -134,6 +141,7 @@ static celix_status_t serviceRegistry_flushUsageCount(service_registry_pt regist
 			serviceReference_equals(usage->reference, reference, &equals);
 			if (equals) {
 				arrayListIterator_remove(iter);
+                serviceRegistration_release(usage->registration);
 				free(usage);
 			}
 		}
@@ -262,10 +270,8 @@ celix_status_t serviceRegistry_unregisterService(service_registry_pt registry, b
 	}
 	arrayList_destroy(references);
 
-	//TODO not needed, the registration is destroyed, any reference to the registration is invalid and will result in a segfault
-	serviceRegistration_invalidate(registration);
-
-	// serviceRegistration_destroy(registration);
+    serviceRegistration_invalidate(registration);
+    serviceRegistration_release(registration);
 
 	celixThreadMutex_unlock(&registry->mutex);
 
@@ -345,7 +351,7 @@ celix_status_t serviceRegistry_getServiceReferencesForRegistration(service_regis
             service_registration_pt reg = NULL;
             service_reference_pt reference = (service_reference_pt) arrayList_get(refs, refIdx);
             bool valid = false;
-            serviceRefernce_isValid(reference, &valid);
+			serviceReference_isValid(reference, &valid);
             if (valid) {
                 serviceReference_getServiceRegistration(reference, &reg);
                 if (reg == registration) {
@@ -421,7 +427,7 @@ celix_status_t serviceRegistry_ungetServiceReference(service_registry_pt registr
     celix_status_t status = CELIX_SUCCESS;
 
     bool valid = false;
-    serviceRefernce_isValid(reference, &valid);
+	serviceReference_isValid(reference, &valid);
     if (valid) {
         bool ungetResult = true;
         while (ungetResult) {
@@ -433,7 +439,7 @@ celix_status_t serviceRegistry_ungetServiceReference(service_registry_pt registr
     array_list_pt references = hashMap_get(registry->serviceReferences, owner);
     if (references != NULL) {
         arrayList_removeElement(references, reference);
-        serviceReference_destroy(&reference);
+        serviceReference_release(reference);
         if (arrayList_size(references) > 0) {
             hashMap_put(registry->serviceReferences, owner, references);
         } else {
@@ -494,7 +500,7 @@ celix_status_t serviceRegistry_getService(service_registry_pt registry, bundle_p
 	if (serviceRegistration_isValid(registration)) {
 		status = serviceRegistry_getUsageCount(registry, bundle, reference, &usage);
 		if (usage == NULL) {
-			status = serviceRegistry_addUsageCount(registry, bundle, reference, &usage);
+			status = serviceRegistry_addUsageCount(registry, bundle, reference, registration, &usage);
 		}
 		usage->count++;
 		*service = usage->service;

http://git-wip-us.apache.org/repos/asf/celix/blob/e0231e51/framework/public/include/properties.h
----------------------------------------------------------------------
diff --git a/framework/public/include/properties.h b/framework/public/include/properties.h
index c4803cb..9fa5f68 100644
--- a/framework/public/include/properties.h
+++ b/framework/public/include/properties.h
@@ -31,6 +31,7 @@
 
 #include "hash_map.h"
 #include "framework_exports.h"
+#include "celix_errno.h"
 
 typedef hash_map_pt properties_pt;
 
@@ -44,4 +45,6 @@ FRAMEWORK_EXPORT char * properties_get(properties_pt properties, char * key);
 FRAMEWORK_EXPORT char * properties_getWithDefault(properties_pt properties, char * key, char * defaultValue);
 FRAMEWORK_EXPORT char * properties_set(properties_pt properties, char * key, char * value);
 
+FRAMEWORK_EXPORT celix_status_t properties_copy(properties_pt properties, properties_pt *copy);
+
 #endif /* PROPERTIES_H_ */


[04/38] celix git commit: CELIX-272: Remove unneeded ungetServiceReference from shell

Posted by pn...@apache.org.
CELIX-272: Remove unneeded ungetServiceReference from shell


Project: http://git-wip-us.apache.org/repos/asf/celix/repo
Commit: http://git-wip-us.apache.org/repos/asf/celix/commit/5fbd1f5d
Tree: http://git-wip-us.apache.org/repos/asf/celix/tree/5fbd1f5d
Diff: http://git-wip-us.apache.org/repos/asf/celix/diff/5fbd1f5d

Branch: refs/heads/develop
Commit: 5fbd1f5d2fe2a7f3ecb1c2f44eb6bbcdd995e29f
Parents: a0926be
Author: Pepijn Noltes <pe...@gmail.com>
Authored: Wed Nov 11 13:23:15 2015 +0100
Committer: Pepijn Noltes <pe...@gmail.com>
Committed: Wed Nov 11 13:23:15 2015 +0100

----------------------------------------------------------------------
 shell/private/src/shell.c | 5 -----
 1 file changed, 5 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/celix/blob/5fbd1f5d/shell/private/src/shell.c
----------------------------------------------------------------------
diff --git a/shell/private/src/shell.c b/shell/private/src/shell.c
index d4fe9cc..378d614 100644
--- a/shell/private/src/shell.c
+++ b/shell/private/src/shell.c
@@ -176,11 +176,6 @@ celix_status_t shell_removeCommand(shell_pt shell_ptr, service_reference_pt refe
 		status = sub_status;
 	}
 
-	sub_status = bundleContext_ungetServiceReference(shell_ptr->bundle_context_ptr, reference_ptr);
-	if (sub_status != CELIX_SUCCESS && status == CELIX_SUCCESS) {
-		status = sub_status;
-	}
-
 	return status;
 }
 


[31/38] celix git commit: CELIX-272: Added rpath for libdfi to rsa dfi test

Posted by pn...@apache.org.
CELIX-272: Added rpath for libdfi to rsa dfi test


Project: http://git-wip-us.apache.org/repos/asf/celix/repo
Commit: http://git-wip-us.apache.org/repos/asf/celix/commit/c641ae01
Tree: http://git-wip-us.apache.org/repos/asf/celix/tree/c641ae01
Diff: http://git-wip-us.apache.org/repos/asf/celix/diff/c641ae01

Branch: refs/heads/develop
Commit: c641ae01cccdc88350339d839228e6e001ac4f7f
Parents: d0dbdb3
Author: Pepijn Noltes <pe...@gmail.com>
Authored: Mon Nov 16 21:16:32 2015 +0100
Committer: Pepijn Noltes <pe...@gmail.com>
Committed: Mon Nov 16 21:16:32 2015 +0100

----------------------------------------------------------------------
 remote_services/remote_service_admin_dfi/rsa_tst/CMakeLists.txt | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/celix/blob/c641ae01/remote_services/remote_service_admin_dfi/rsa_tst/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_dfi/rsa_tst/CMakeLists.txt b/remote_services/remote_service_admin_dfi/rsa_tst/CMakeLists.txt
index 99d6a23..299ccd6 100644
--- a/remote_services/remote_service_admin_dfi/rsa_tst/CMakeLists.txt
+++ b/remote_services/remote_service_admin_dfi/rsa_tst/CMakeLists.txt
@@ -28,7 +28,7 @@ add_subdirectory(bundle)
 
 SET(CMAKE_SKIP_BUILD_RPATH  FALSE) #TODO needed?
 SET(CMAKE_BUILD_WITH_INSTALL_RPATH TRUE) #TODO needed?
-SET(CMAKE_INSTALL_RPATH "${PROJECT_BINARY_DIR}/framework" "${PROJECT_BINARY_DIR}/utils")
+SET(CMAKE_INSTALL_RPATH "${PROJECT_BINARY_DIR}/framework" "${PROJECT_BINARY_DIR}/utils" "${PROJECT_BINARY_DIR}/remote_services/remote_service_admin_dfi/dynamic_function_interface")
 
 add_executable(test_rsa_dfi
     run_tests.cpp


[27/38] celix git commit: CELIX-272: Cleanup include framework

Posted by pn...@apache.org.
CELIX-272: Cleanup include framework


Project: http://git-wip-us.apache.org/repos/asf/celix/repo
Commit: http://git-wip-us.apache.org/repos/asf/celix/commit/e4259dbc
Tree: http://git-wip-us.apache.org/repos/asf/celix/tree/e4259dbc
Diff: http://git-wip-us.apache.org/repos/asf/celix/diff/e4259dbc

Branch: refs/heads/develop
Commit: e4259dbc0574af314d3611279bd87c70c0416d79
Parents: c34e595
Author: Pepijn Noltes <pe...@gmail.com>
Authored: Mon Nov 16 21:13:53 2015 +0100
Committer: Pepijn Noltes <pe...@gmail.com>
Committed: Mon Nov 16 21:13:53 2015 +0100

----------------------------------------------------------------------
 framework/private/src/framework.c | 16 +---------------
 1 file changed, 1 insertion(+), 15 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/celix/blob/e4259dbc/framework/private/src/framework.c
----------------------------------------------------------------------
diff --git a/framework/private/src/framework.c b/framework/private/src/framework.c
index c3bc147..84f428d 100644
--- a/framework/private/src/framework.c
+++ b/framework/private/src/framework.c
@@ -27,9 +27,8 @@
 #include <stdio.h>
 #include <string.h>
 #include <sys/stat.h>
-#include <sys/types.h>
 #include "celixbool.h"
-#include <math.h>
+
 #ifdef _WIN32
 #include <winbase.h>
 #include <windows.h>
@@ -39,26 +38,13 @@
 #include <uuid/uuid.h>
 
 #include "framework_private.h"
-#include "filter.h"
 #include "constants.h"
-#include "archive.h"
-#include "bundle.h"
-#include "wire.h"
 #include "resolver.h"
 #include "utils.h"
-#include "bundle_activator.h"
-#include "service_registry.h"
-#include "bundle_cache.h"
-#include "bundle_archive.h"
-#include "bundle_revision.h"
-#include "bundle_context.h"
 #include "linked_list_iterator.h"
 #include "service_reference_private.h"
 #include "listener_hook_service.h"
 #include "service_registration_private.h"
-#include "celix_log.h"
-
-#include "celix_threads.h"
 
 typedef celix_status_t (*create_function_pt)(bundle_context_pt context, void **userData);
 typedef celix_status_t (*start_function_pt)(void * handle, bundle_context_pt context);


[29/38] celix git commit: CELIX-272: Remove unneeded ungetService from export registration dfi

Posted by pn...@apache.org.
CELIX-272: Remove unneeded ungetService from export registration dfi


Project: http://git-wip-us.apache.org/repos/asf/celix/repo
Commit: http://git-wip-us.apache.org/repos/asf/celix/commit/0a177d9f
Tree: http://git-wip-us.apache.org/repos/asf/celix/tree/0a177d9f
Diff: http://git-wip-us.apache.org/repos/asf/celix/diff/0a177d9f

Branch: refs/heads/develop
Commit: 0a177d9f464c934be143a732d2b9cad715175694
Parents: 93c6a62
Author: Pepijn Noltes <pe...@gmail.com>
Authored: Mon Nov 16 21:15:35 2015 +0100
Committer: Pepijn Noltes <pe...@gmail.com>
Committed: Mon Nov 16 21:15:35 2015 +0100

----------------------------------------------------------------------
 framework/private/src/service_registry.c          | 18 ++++++++++++------
 .../rsa/private/src/export_registration_dfi.c     |  1 -
 2 files changed, 12 insertions(+), 7 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/celix/blob/0a177d9f/framework/private/src/service_registry.c
----------------------------------------------------------------------
diff --git a/framework/private/src/service_registry.c b/framework/private/src/service_registry.c
index db6e305..28d22e0 100644
--- a/framework/private/src/service_registry.c
+++ b/framework/private/src/service_registry.c
@@ -94,7 +94,7 @@ celix_status_t serviceRegistry_destroy(service_registry_pt registry) {
 
     //destroy service references (double) map);
     size = hashMap_size(registry->serviceReferences);
-    assert(size == 0);
+    //assert(size == 0); FIXME This gives a problem in the remote_service_admin_dfi test. seems that the bundleActivator_stop of the calculator is activated twice ??
     hashMap_destroy(registry->serviceReferences, false, false);
 
     //destroy listener hooks
@@ -155,17 +155,21 @@ celix_status_t serviceRegistry_registerServiceInternal(service_registry_pt regis
 	    *registration = serviceRegistration_create(registry->callback, bundle, serviceName, ++registry->currentServiceId, serviceObject, dictionary);
 	}
 
-	serviceRegistry_addHooks(registry, serviceName, serviceObject, *registration);
+    //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(&registry->lock);
 	regs = (array_list_pt) hashMap_get(registry->serviceRegistrations, bundle);
 	if (regs == NULL) {
 		regs = NULL;
 		arrayList_create(&regs);
-	}
+        hashMap_put(registry->serviceRegistrations, bundle, regs);
+    }
 	arrayList_add(regs, *registration);
-	hashMap_put(registry->serviceRegistrations, bundle, regs);
-
 	celixThreadRwlock_unlock(&registry->lock);
 
 	if (registry->serviceChanged != NULL) {
@@ -179,6 +183,7 @@ celix_status_t serviceRegistry_unregisterService(service_registry_pt registry, b
 	// array_list_t clients;
 	array_list_pt regs;
 
+    //fprintf(stderr, "REG: Unregistering service registration with pointer %p\n", registration);
 
 	serviceRegistry_removeHook(registry, registration);
 
@@ -422,7 +427,8 @@ celix_status_t serviceRegistry_setReferenceStatus(service_registry_pt registry,
 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 has ref status %i", reference, refStatus);
+    fw_log(logger, OSGI_FRAMEWORK_LOG_ERROR, "Error handling service reference %p from registration %p and bundle (owner) %p, ref has ref status %i",
+           reference, reference->registration, reference->referenceOwner, refStatus);
 }
 
 celix_status_t serviceRegistry_checkReference(service_registry_pt registry, service_reference_pt ref,

http://git-wip-us.apache.org/repos/asf/celix/blob/0a177d9f/remote_services/remote_service_admin_dfi/rsa/private/src/export_registration_dfi.c
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_dfi/rsa/private/src/export_registration_dfi.c b/remote_services/remote_service_admin_dfi/rsa/private/src/export_registration_dfi.c
index 0567870..7ef0daf 100644
--- a/remote_services/remote_service_admin_dfi/rsa/private/src/export_registration_dfi.c
+++ b/remote_services/remote_service_admin_dfi/rsa/private/src/export_registration_dfi.c
@@ -190,7 +190,6 @@ static void exportRegistration_removeServ(export_registration_pt reg, service_re
 
 celix_status_t exportRegistration_stop(export_registration_pt reg) {
     celix_status_t status = CELIX_SUCCESS;
-    status = bundleContext_ungetService(reg->context, reg->exportReference.reference, NULL);
     if (status == CELIX_SUCCESS) {
         bundleContext_ungetServiceReference(reg->context, reg->exportReference.reference);
     }


[28/38] celix git commit: CELIX-272: Fix threading issue remote_shell

Posted by pn...@apache.org.
CELIX-272: Fix threading issue remote_shell


Project: http://git-wip-us.apache.org/repos/asf/celix/repo
Commit: http://git-wip-us.apache.org/repos/asf/celix/commit/93c6a622
Tree: http://git-wip-us.apache.org/repos/asf/celix/tree/93c6a622
Diff: http://git-wip-us.apache.org/repos/asf/celix/diff/93c6a622

Branch: refs/heads/develop
Commit: 93c6a622126c24ce81d4d07b9c73d5086b75ff2b
Parents: e4259db
Author: Pepijn Noltes <pe...@gmail.com>
Authored: Mon Nov 16 21:14:19 2015 +0100
Committer: Pepijn Noltes <pe...@gmail.com>
Committed: Mon Nov 16 21:14:19 2015 +0100

----------------------------------------------------------------------
 remote_shell/private/include/shell_mediator.h |  1 +
 remote_shell/private/src/activator.c          |  1 +
 remote_shell/private/src/shell_mediator.c     | 39 +++++++++++-----------
 3 files changed, 21 insertions(+), 20 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/celix/blob/93c6a622/remote_shell/private/include/shell_mediator.h
----------------------------------------------------------------------
diff --git a/remote_shell/private/include/shell_mediator.h b/remote_shell/private/include/shell_mediator.h
index faf86e8..24e8250 100644
--- a/remote_shell/private/include/shell_mediator.h
+++ b/remote_shell/private/include/shell_mediator.h
@@ -47,6 +47,7 @@ struct shell_mediator {
 typedef struct shell_mediator *shell_mediator_pt;
 
 celix_status_t shellMediator_create(bundle_context_pt context, shell_mediator_pt *instance);
+celix_status_t shellMediator_stop(shell_mediator_pt instance);
 celix_status_t shellMediator_destroy(shell_mediator_pt instance);
 celix_status_t shellMediator_executeCommand(shell_mediator_pt instance, char *command, FILE *out, FILE *err);
 

http://git-wip-us.apache.org/repos/asf/celix/blob/93c6a622/remote_shell/private/src/activator.c
----------------------------------------------------------------------
diff --git a/remote_shell/private/src/activator.c b/remote_shell/private/src/activator.c
index 062420d..4344258 100644
--- a/remote_shell/private/src/activator.c
+++ b/remote_shell/private/src/activator.c
@@ -102,6 +102,7 @@ celix_status_t bundleActivator_stop(void * userData, bundle_context_pt context)
 	bundle_instance_pt bi = (bundle_instance_pt) userData;
 
 	connectionListener_stop(bi->connectionListener);
+	shellMediator_stop(bi->shellMediator);
 	shellMediator_destroy(bi->shellMediator);
 
 	remoteShell_stopConnections(bi->remoteShell);

http://git-wip-us.apache.org/repos/asf/celix/blob/93c6a622/remote_shell/private/src/shell_mediator.c
----------------------------------------------------------------------
diff --git a/remote_shell/private/src/shell_mediator.c b/remote_shell/private/src/shell_mediator.c
index ab60f3e..9b08035 100644
--- a/remote_shell/private/src/shell_mediator.c
+++ b/remote_shell/private/src/shell_mediator.c
@@ -36,9 +36,7 @@
 #include "log_service.h"
 #include "shell_mediator.h"
 
-static celix_status_t shellMediator_addingService(void *handler, service_reference_pt reference, void **service);
 static celix_status_t shellMediator_addedService(void *handler, service_reference_pt reference, void * service);
-static celix_status_t shellMediator_modifiedService(void *handler, service_reference_pt reference, void * service);
 static celix_status_t shellMediator_removedService(void *handler, service_reference_pt reference, void * service);
 
 celix_status_t shellMediator_create(bundle_context_pt context, shell_mediator_pt *instance) {
@@ -56,8 +54,8 @@ celix_status_t shellMediator_create(bundle_context_pt context, shell_mediator_pt
 
 		status = CELIX_DO_IF(status, celixThreadMutex_create(&(*instance)->mutex, NULL));
 
-		status = CELIX_DO_IF(status, serviceTrackerCustomizer_create((*instance), shellMediator_addingService, shellMediator_addedService,
-				shellMediator_modifiedService, shellMediator_removedService, &customizer));
+		status = CELIX_DO_IF(status, serviceTrackerCustomizer_create((*instance), NULL, shellMediator_addedService,
+				NULL, shellMediator_removedService, &customizer));
 		status = CELIX_DO_IF(status, serviceTracker_create(context, (char * )OSGI_SHELL_SERVICE_NAME, customizer, &(*instance)->tracker));
 
 		if (status == CELIX_SUCCESS) {
@@ -74,18 +72,31 @@ celix_status_t shellMediator_create(bundle_context_pt context, shell_mediator_pt
 	return status;
 }
 
+celix_status_t shellMediator_stop(shell_mediator_pt instance) {
+	service_tracker_pt tracker;
+	celixThreadMutex_lock(&instance->mutex);
+	tracker = instance->tracker;
+	celixThreadMutex_unlock(&instance->mutex);
+
+	if (tracker != NULL) {
+		serviceTracker_close(tracker);
+	}
+}
+
 celix_status_t shellMediator_destroy(shell_mediator_pt instance) {
 	celix_status_t status = CELIX_SUCCESS;
 
 	celixThreadMutex_lock(&instance->mutex);
 
 	instance->shellService = NULL;
-	serviceTracker_close(instance->tracker);
-	celixThreadMutex_unlock(&instance->mutex);
-
+	serviceTracker_destroy(instance->tracker);
 	logHelper_stop(instance->loghelper);
-
 	status = logHelper_destroy(&instance->loghelper);
+	celixThreadMutex_destroy(&instance->mutex);
+
+
+	free(instance);
+
 
 	return status;
 }
@@ -105,13 +116,6 @@ celix_status_t shellMediator_executeCommand(shell_mediator_pt instance, char *co
 	return status;
 }
 
-static celix_status_t shellMediator_addingService(void *handler, service_reference_pt reference, void **service) {
-	celix_status_t status = CELIX_SUCCESS;
-	shell_mediator_pt instance = (shell_mediator_pt) handler;
-	bundleContext_getService(instance->context, reference, service);
-	return status;
-}
-
 static celix_status_t shellMediator_addedService(void *handler, service_reference_pt reference, void * service) {
 	celix_status_t status = CELIX_SUCCESS;
 	shell_mediator_pt instance = (shell_mediator_pt) handler;
@@ -121,11 +125,6 @@ static celix_status_t shellMediator_addedService(void *handler, service_referenc
 	return status;
 }
 
-static celix_status_t shellMediator_modifiedService(void *handler, service_reference_pt reference, void * service) {
-	celix_status_t status = CELIX_SUCCESS;
-	//ignore
-	return status;
-}
 
 static celix_status_t shellMediator_removedService(void *handler, service_reference_pt reference, void * service) {
 	celix_status_t status = CELIX_SUCCESS;


[23/38] celix git commit: CELIX-272: Remove memory leaks from framework and dep manager

Posted by pn...@apache.org.
CELIX-272: Remove memory leaks from framework and dep manager


Project: http://git-wip-us.apache.org/repos/asf/celix/repo
Commit: http://git-wip-us.apache.org/repos/asf/celix/commit/7199e5c4
Tree: http://git-wip-us.apache.org/repos/asf/celix/tree/7199e5c4
Diff: http://git-wip-us.apache.org/repos/asf/celix/diff/7199e5c4

Branch: refs/heads/develop
Commit: 7199e5c473b5b024c214fb50779949556799fba7
Parents: 8c02ecf
Author: Pepijn Noltes <pe...@gmail.com>
Authored: Mon Nov 16 18:16:16 2015 +0100
Committer: Pepijn Noltes <pe...@gmail.com>
Committed: Mon Nov 16 18:16:16 2015 +0100

----------------------------------------------------------------------
 dependency_manager/private/src/dm_service_dependency.c | 3 +++
 framework/private/src/bundle_cache.c                   | 2 +-
 framework/private/src/framework.c                      | 1 +
 framework/private/src/service_registry.c               | 8 ++++++++
 4 files changed, 13 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/celix/blob/7199e5c4/dependency_manager/private/src/dm_service_dependency.c
----------------------------------------------------------------------
diff --git a/dependency_manager/private/src/dm_service_dependency.c b/dependency_manager/private/src/dm_service_dependency.c
index d29a8fe..636fd47 100644
--- a/dependency_manager/private/src/dm_service_dependency.c
+++ b/dependency_manager/private/src/dm_service_dependency.c
@@ -360,6 +360,8 @@ celix_status_t serviceDependency_invokeSet(dm_service_dependency_pt dependency,
 		}
 	}
 
+    arrayList_destroy(serviceReferences);
+
 	if (curServRef) {
 		status = bundleContext_getService(event->context, curServRef, &service);
 	} else {
@@ -646,6 +648,7 @@ celix_status_t serviceDependency_getServiceDependencyInfo(dm_service_dependency_
 		if (refs != NULL) {
 			info->count = arrayList_size(refs);
 		}
+		arrayList_destroy(refs);
 
 		celixThreadMutex_unlock(&dep->lock);
 	} else {

http://git-wip-us.apache.org/repos/asf/celix/blob/7199e5c4/framework/private/src/bundle_cache.c
----------------------------------------------------------------------
diff --git a/framework/private/src/bundle_cache.c b/framework/private/src/bundle_cache.c
index 46a43e4..3c1530a 100644
--- a/framework/private/src/bundle_cache.c
+++ b/framework/private/src/bundle_cache.c
@@ -112,7 +112,7 @@ celix_status_t bundleCache_getArchives(bundle_cache_pt cache, array_list_pt *arc
                     && (strcmp(dp.d_name, "bundle0") != 0)) {
 
                     bundle_archive_pt archive = NULL;
-                    status = bundleArchive_recreate(strdup(archiveRoot), &archive);
+                    status = bundleArchive_recreate(archiveRoot, &archive);
                     if (status == CELIX_SUCCESS) {
                         arrayList_add(list, archive);
                     }

http://git-wip-us.apache.org/repos/asf/celix/blob/7199e5c4/framework/private/src/framework.c
----------------------------------------------------------------------
diff --git a/framework/private/src/framework.c b/framework/private/src/framework.c
index d603207..25e2442 100644
--- a/framework/private/src/framework.c
+++ b/framework/private/src/framework.c
@@ -2354,6 +2354,7 @@ static void *fw_eventDispatcher(void *fw) {
 
                     fw_invokeBundleListener(framework, listener->listener, event, listener->bundle);
 
+                    free(event->bundleSymbolicName);
                     free(event);
                 } else if (request->type == FRAMEWORK_EVENT_TYPE) {
                     fw_framework_listener_pt listener = (fw_framework_listener_pt) arrayList_get(request->listeners, i);

http://git-wip-us.apache.org/repos/asf/celix/blob/7199e5c4/framework/private/src/service_registry.c
----------------------------------------------------------------------
diff --git a/framework/private/src/service_registry.c b/framework/private/src/service_registry.c
index 9f90025..db6e305 100644
--- a/framework/private/src/service_registry.c
+++ b/framework/private/src/service_registry.c
@@ -66,6 +66,8 @@ celix_status_t serviceRegistry_create(framework_pt framework, serviceChanged_fun
 		reg->framework = framework;
 		reg->currentServiceId = 1l;
 		reg->serviceReferences = hashMap_create(NULL, NULL, NULL, NULL);
+
+        reg->checkDeletedReferences = true;
         reg->deletedServiceReferences = hashMap_create(NULL, NULL, NULL, NULL);
 
 		arrayList_create(&reg->listenerHooks);
@@ -184,6 +186,11 @@ 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);
+        int size = arrayList_size(regs);
+        if (size == 0) {
+            arrayList_destroy(regs);
+            hashMap_remove(registry->serviceRegistrations, bundle);
+        }
 	}
 	celixThreadRwlock_unlock(&registry->lock);
 
@@ -479,6 +486,7 @@ celix_status_t serviceRegistry_clearReferencesFor(service_registry_pt registry,
 
         }
         hashMapIterator_destroy(iter);
+        hashMap_destroy(refsMap, false, false);
     }
 
     celixThreadRwlock_unlock(&registry->lock);


[32/38] celix git commit: CELIX-272: Add ifdef to check if cmake uses RELEASE build, in that case do not use deleted service reference check.

Posted by pn...@apache.org.
CELIX-272: Add ifdef to check if cmake uses RELEASE build, in that case do not use deleted service reference check.


Project: http://git-wip-us.apache.org/repos/asf/celix/repo
Commit: http://git-wip-us.apache.org/repos/asf/celix/commit/03da4ec9
Tree: http://git-wip-us.apache.org/repos/asf/celix/tree/03da4ec9
Diff: http://git-wip-us.apache.org/repos/asf/celix/diff/03da4ec9

Branch: refs/heads/develop
Commit: 03da4ec92f9c96bd94f36b301637fdac4e3022fd
Parents: c641ae0
Author: Pepijn Noltes <pe...@gmail.com>
Authored: Tue Nov 17 09:36:03 2015 +0100
Committer: Pepijn Noltes <pe...@gmail.com>
Committed: Tue Nov 17 09:36:03 2015 +0100

----------------------------------------------------------------------
 framework/private/src/service_registry.c | 21 +++++++++++++++------
 1 file changed, 15 insertions(+), 6 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/celix/blob/03da4ec9/framework/private/src/service_registry.c
----------------------------------------------------------------------
diff --git a/framework/private/src/service_registry.c b/framework/private/src/service_registry.c
index 28d22e0..277fe77 100644
--- a/framework/private/src/service_registry.c
+++ b/framework/private/src/service_registry.c
@@ -35,6 +35,12 @@
 #include "service_reference_private.h"
 #include "framework_private.h"
 
+#ifdef NDEBUG
+#define CHECK_DELETED_REFERENCES false
+#else
+#define CHECK_DELETED_REFERENCES true
+#endif
+
 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);
@@ -67,7 +73,7 @@ celix_status_t serviceRegistry_create(framework_pt framework, serviceChanged_fun
 		reg->currentServiceId = 1l;
 		reg->serviceReferences = hashMap_create(NULL, NULL, NULL, NULL);
 
-        reg->checkDeletedReferences = true;
+        reg->checkDeletedReferences = CHECK_DELETED_REFERENCES;
         reg->deletedServiceReferences = hashMap_create(NULL, NULL, NULL, NULL);
 
 		arrayList_create(&reg->listenerHooks);
@@ -248,7 +254,7 @@ celix_status_t serviceRegistry_clearServiceRegistrations(service_registry_pt reg
 static void serviceRegistry_logWarningServiceRegistration(service_registry_pt registry __attribute__((unused)), 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);
+    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,
@@ -427,8 +433,11 @@ celix_status_t serviceRegistry_setReferenceStatus(service_registry_pt registry,
 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 from registration %p and bundle (owner) %p, ref has ref status %i",
-           reference, reference->registration, reference->referenceOwner, refStatus);
+    service_registration_pt reg = reference != NULL ? reference->registration : NULL;
+    bundle_pt bundle = reference != NULL ? reference->referenceOwner : NULL;
+    fw_log(logger, OSGI_FRAMEWORK_LOG_ERROR,
+           "Error handling service reference %p from registration %p and bundle (owner) %p, ref has ref status %i",
+           reference, reg, bundle, refStatus);
 }
 
 celix_status_t serviceRegistry_checkReference(service_registry_pt registry, service_reference_pt ref,
@@ -454,10 +463,10 @@ celix_status_t serviceRegistry_checkReference(service_registry_pt registry, serv
 
 void serviceRegistry_logWarningServiceReferenceUsageCount(service_registry_pt registry __attribute__((unused)), 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);
+        fw_log(logger, OSGI_FRAMEWORK_LOG_WARNING, "Service Reference destroyed with 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);
+        fw_log(logger, OSGI_FRAMEWORK_LOG_WARNING, "Dangling service reference. Reference count is %zu.  Look for missing bundleContext_ungetServiceReference calls.", refCount);
     }
 }
 


[10/38] celix git commit: CELIX-272: Disabling some test, due to an issue (concurency) issue with deleting the bundle cache.

Posted by pn...@apache.org.
CELIX-272: Disabling some test, due to an issue (concurency) issue with deleting the bundle cache.


Project: http://git-wip-us.apache.org/repos/asf/celix/repo
Commit: http://git-wip-us.apache.org/repos/asf/celix/commit/0133d040
Tree: http://git-wip-us.apache.org/repos/asf/celix/tree/0133d040
Diff: http://git-wip-us.apache.org/repos/asf/celix/diff/0133d040

Branch: refs/heads/develop
Commit: 0133d040633770a76c6b57bf13f43b5ee2460b39
Parents: ca19830
Author: Pepijn Noltes <pe...@gmail.com>
Authored: Wed Nov 11 18:03:52 2015 +0100
Committer: Pepijn Noltes <pe...@gmail.com>
Committed: Wed Nov 11 18:03:52 2015 +0100

----------------------------------------------------------------------
 remote_services/remote_service_admin_dfi/rsa_tst/CMakeLists.txt | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/celix/blob/0133d040/remote_services/remote_service_admin_dfi/rsa_tst/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_dfi/rsa_tst/CMakeLists.txt b/remote_services/remote_service_admin_dfi/rsa_tst/CMakeLists.txt
index 99d6a23..e666e92 100644
--- a/remote_services/remote_service_admin_dfi/rsa_tst/CMakeLists.txt
+++ b/remote_services/remote_service_admin_dfi/rsa_tst/CMakeLists.txt
@@ -32,7 +32,7 @@ SET(CMAKE_INSTALL_RPATH "${PROJECT_BINARY_DIR}/framework" "${PROJECT_BINARY_DIR}
 
 add_executable(test_rsa_dfi
     run_tests.cpp
-    rsa_tests.cpp
+    #rsa_tests.cpp
     rsa_client_server_tests.cpp
 
     ${PROJECT_SOURCE_DIR}/remote_services/remote_service_admin/private/src/endpoint_description.c


[06/38] celix git commit: CELIX-272: Fix log warning text

Posted by pn...@apache.org.
CELIX-272: Fix log warning text


Project: http://git-wip-us.apache.org/repos/asf/celix/repo
Commit: http://git-wip-us.apache.org/repos/asf/celix/commit/f0778a7d
Tree: http://git-wip-us.apache.org/repos/asf/celix/tree/f0778a7d
Diff: http://git-wip-us.apache.org/repos/asf/celix/diff/f0778a7d

Branch: refs/heads/develop
Commit: f0778a7d080c6cc804721ba5fd8c240ae48fdf45
Parents: 592d65f
Author: Pepijn Noltes <pe...@gmail.com>
Authored: Wed Nov 11 13:57:11 2015 +0100
Committer: Pepijn Noltes <pe...@gmail.com>
Committed: Wed Nov 11 13:57:11 2015 +0100

----------------------------------------------------------------------
 framework/private/src/service_registry.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/celix/blob/f0778a7d/framework/private/src/service_registry.c
----------------------------------------------------------------------
diff --git a/framework/private/src/service_registry.c b/framework/private/src/service_registry.c
index d38b07e..9f84ded 100644
--- a/framework/private/src/service_registry.c
+++ b/framework/private/src/service_registry.c
@@ -226,7 +226,7 @@ celix_status_t serviceRegistry_clearServiceRegistrations(service_registry_pt reg
 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);
+    fw_log(logger, OSGI_FRAMEWORK_LOG_WARNING, "Dangling service registration for service %s. Look for missing serviceRegistration_unregister.", servName);
 }
 
 celix_status_t serviceRegistry_getServiceReference(service_registry_pt registry, bundle_pt owner,
@@ -358,10 +358,10 @@ celix_status_t serviceRegistry_ungetServiceReference(service_registry_pt registr
 
 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);
+        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);
+        fw_log(logger, OSGI_FRAMEWORK_LOG_WARNING, "Dangling service reference. Reference count is %zu. Look for missing bundleContext_ungetServiceReference.", refCount);
     }
 }
 


[34/38] celix git commit: CELIX-272: Introduce celixThread_once code and call in the framwork to ensure a single logger initialization even when runnign mutiple frameworks in the same process

Posted by pn...@apache.org.
CELIX-272: Introduce celixThread_once code and call in the framwork to ensure a single logger initialization even when runnign mutiple frameworks in the same process


Project: http://git-wip-us.apache.org/repos/asf/celix/repo
Commit: http://git-wip-us.apache.org/repos/asf/celix/commit/a40693f5
Tree: http://git-wip-us.apache.org/repos/asf/celix/tree/a40693f5
Diff: http://git-wip-us.apache.org/repos/asf/celix/diff/a40693f5

Branch: refs/heads/develop
Commit: a40693f56a416085f2bca95aa4018ea89057cbe1
Parents: cf7acae
Author: Pepijn Noltes <pe...@gmail.com>
Authored: Tue Nov 17 10:15:05 2015 +0100
Committer: Pepijn Noltes <pe...@gmail.com>
Committed: Tue Nov 17 10:15:05 2015 +0100

----------------------------------------------------------------------
 framework/private/src/framework.c    | 10 ++++++++--
 utils/private/src/celix_threads.c    |  4 ++++
 utils/public/include/celix_threads.h |  3 +++
 3 files changed, 15 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/celix/blob/a40693f5/framework/private/src/framework.c
----------------------------------------------------------------------
diff --git a/framework/private/src/framework.c b/framework/private/src/framework.c
index 84f428d..0823781 100644
--- a/framework/private/src/framework.c
+++ b/framework/private/src/framework.c
@@ -152,6 +152,13 @@ typedef struct request *request_pt;
 
 framework_logger_pt logger;
 
+//TODO introduce a counter + mutex to control the freeing of the logger when mutiple threads are running a framework.
+static celix_thread_once_t loggerInit = CELIX_THREAD_ONCE_INIT;
+static void framework_loggerInit(void) {
+    logger = malloc(sizeof(*logger));
+    logger->logFunction = frameworkLogger_log;
+}
+
 #ifdef _WIN32
     #define handle_t HMODULE
     #define fw_openLibrary(path) LoadLibrary(path)
@@ -179,8 +186,7 @@ celix_status_t framework_create(framework_pt *framework, properties_pt config) {
 
     logger = hashMap_get(config, "logger");
     if (logger == NULL) {
-        logger = malloc(sizeof(*logger));
-        logger->logFunction = frameworkLogger_log;
+        celixThread_once(&loggerInit, framework_loggerInit);
     }
 
     *framework = (framework_pt) malloc(sizeof(**framework));

http://git-wip-us.apache.org/repos/asf/celix/blob/a40693f5/utils/private/src/celix_threads.c
----------------------------------------------------------------------
diff --git a/utils/private/src/celix_threads.c b/utils/private/src/celix_threads.c
index bec374b..64bdf5b 100644
--- a/utils/private/src/celix_threads.c
+++ b/utils/private/src/celix_threads.c
@@ -178,3 +178,7 @@ celix_status_t celixThreadRwlockAttr_create(celix_thread_rwlockattr_t *attr) {
 celix_status_t celixThreadRwlockAttr_destroy(celix_thread_rwlockattr_t *attr) {
 	return pthread_rwlockattr_destroy(attr);
 }
+
+celix_status_t celixThread_once(celix_thread_once_t *once_control, void (*init_routine)(void)) {
+	return pthread_once(once_control, init_routine);
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/celix/blob/a40693f5/utils/public/include/celix_threads.h
----------------------------------------------------------------------
diff --git a/utils/public/include/celix_threads.h b/utils/public/include/celix_threads.h
index 1e7a7ad..8fc043e 100644
--- a/utils/public/include/celix_threads.h
+++ b/utils/public/include/celix_threads.h
@@ -38,6 +38,8 @@ struct celix_thread {
 	pthread_t thread;
 };
 
+typedef pthread_once_t celix_thread_once_t;
+#define CELIX_THREAD_ONCE_INIT PTHREAD_ONCE_INIT
 
 typedef struct celix_thread celix_thread_t;
 typedef pthread_attr_t celix_thread_attr_t;
@@ -101,5 +103,6 @@ celix_status_t celixThreadCondition_wait(celix_thread_cond_t *cond, celix_thread
 celix_status_t celixThreadCondition_broadcast(celix_thread_cond_t *cond);
 celix_status_t celixThreadCondition_signal(celix_thread_cond_t *cond);
 
+celix_status_t celixThread_once(celix_thread_once_t *once_control, void (*init_routine)(void));
 
 #endif /* CELIX_THREADS_H_ */


[21/38] celix git commit: CELIX-272: Add callback structure for serv reg/ref instead of dependency to serv registry. Fix in serviceRegistry_destroy

Posted by pn...@apache.org.
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(&registry->lock);
+    celixThreadRwlock_writeLock(&registry->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(&registry->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(&registry->lock);
             hash_map_pt refsMap = hashMap_get(registry->serviceReferences, bundle);
             hashMap_remove(refsMap, reg);
-            hashMap_put(registry->deletedServiceReferences, reference, (void *)true);
-            celixThreadRwlock_unlock(&registry->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(&registry->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(&registry->lock);
-    if (hashMap_containsKey(registry->deletedServiceReferences, ref)) {
-        bool deleted = (bool) hashMap_get(registry->deletedServiceReferences, ref);
-        refStatus = deleted ? REF_DELETED : REF_ACTIVE;
-    }
-    celixThreadRwlock_unlock(&registry->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(&registry->lock);
+    serviceRegistry_checkReference(registry, reference, &refStatus);
     if (refStatus == REF_ACTIVE) {
-        celixThreadRwlock_readLock(&registry->lock);
         serviceReference_getServiceRegistration(reference, &registration);
 
         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(&registry->lock);
     } else {
         serviceRegistry_logIllegalReference(registry, reference, refStatus);
         status = CELIX_BUNDLE_EXCEPTION;
     }
+    celixThreadRwlock_unlock(&registry->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(&registry->lock);
     serviceRegistry_checkReference(registry, reference, &refStatus);
+    celixThreadRwlock_unlock(&registry->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_ */


[11/38] celix git commit: CELIX-288: Fix issue inspecting if file is a dir. Using stats instead of dirent.type

Posted by pn...@apache.org.
CELIX-288: Fix issue inspecting if file is a dir. Using stats instead of dirent.type


Project: http://git-wip-us.apache.org/repos/asf/celix/repo
Commit: http://git-wip-us.apache.org/repos/asf/celix/commit/bffb8eaa
Tree: http://git-wip-us.apache.org/repos/asf/celix/tree/bffb8eaa
Diff: http://git-wip-us.apache.org/repos/asf/celix/diff/bffb8eaa

Branch: refs/heads/develop
Commit: bffb8eaaf01bb5536f3855f82b355cab07d5a771
Parents: 0133d04
Author: Pepijn Noltes <pe...@gmail.com>
Authored: Thu Nov 12 09:06:26 2015 +0100
Committer: Pepijn Noltes <pe...@gmail.com>
Committed: Thu Nov 12 17:40:17 2015 +0100

----------------------------------------------------------------------
 framework/private/src/bundle_archive.c | 49 +++++++++++++++++------------
 framework/private/src/bundle_cache.c   | 43 ++++++++++++++-----------
 2 files changed, 54 insertions(+), 38 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/celix/blob/bffb8eaa/framework/private/src/bundle_archive.c
----------------------------------------------------------------------
diff --git a/framework/private/src/bundle_archive.c b/framework/private/src/bundle_archive.c
index b126617..f7add7e 100644
--- a/framework/private/src/bundle_archive.c
+++ b/framework/private/src/bundle_archive.c
@@ -193,14 +193,20 @@ celix_status_t bundleArchive_recreate(char * archiveRoot, bundle_archive_pt *bun
 
 			struct dirent dent;
 			struct dirent *result;
+            struct stat st;
 			int rc;
 
 			rc = readdir_r(archive->archiveRootDir, &dent, &result);
-
 			while (rc == 0 && result != NULL) {
-				if (dent.d_type == DT_DIR && (strncmp(dent.d_name, "version", 7) == 0)) {
+                char subdir[512];
+                snprintf(subdir, 512, "%s/%s", archiveRoot, dent.d_name);
+                stat(subdir, &st);
+				if (S_ISDIR(st.st_mode) && (strncmp(dent.d_name, "version", 7) == 0)) {
 					sscanf(dent.d_name, "version%*d.%ld", &idx);
-				}
+				} else {
+                    status = CELIX_FILE_IO_EXCEPTION;
+                    break;
+                }
 				rc = readdir_r(archive->archiveRootDir, &dent, &result);
 			}
 
@@ -720,23 +726,26 @@ static celix_status_t bundleArchive_deleteTree(bundle_archive_pt archive, char *
 		struct dirent *result = NULL;
 		int rc = 0;
 
-		rc = readdir_r(dir, &dp, &result);
-		while (rc == 0 && result != NULL) {
-			if ((strcmp((dp.d_name), ".") != 0) && (strcmp((dp.d_name), "..") != 0)) {
-				char subdir[512];
-				snprintf(subdir, sizeof(subdir), "%s/%s", directory, dp.d_name);
-
-				if (dp.d_type == DT_DIR) {
-					status = bundleArchive_deleteTree(archive, subdir);
-				} else {
-					if (remove(subdir) != 0) {
-						status = CELIX_FILE_IO_EXCEPTION;
-						break;
-					}
-				}
-			}
-			rc = readdir_r(dir, &dp, &result);
-		}
+        rc = readdir_r(dir, &dp, &result);
+        while (rc == 0 && result != NULL) {
+            if ((strcmp((dp.d_name), ".") != 0) && (strcmp((dp.d_name), "..") != 0)) {
+                char subdir[512];
+                snprintf(subdir, 512, "%s/%s", directory, dp.d_name);
+
+                struct stat st;
+                if (stat(subdir, &st) == 0) {
+                    if (S_ISDIR (st.st_mode)) {
+                        status = bundleArchive_deleteTree(archive, subdir);
+                    } else {
+                        if (remove(subdir) != 0) {
+                            status = CELIX_FILE_IO_EXCEPTION;
+                            break;
+                        }
+                    }
+                }
+            }
+            rc = readdir_r(dir, &dp, &result);
+        }
 
 		if (closedir(dir) != 0) {
 			status = CELIX_FILE_IO_EXCEPTION;

http://git-wip-us.apache.org/repos/asf/celix/blob/bffb8eaa/framework/private/src/bundle_cache.c
----------------------------------------------------------------------
diff --git a/framework/private/src/bundle_cache.c b/framework/private/src/bundle_cache.c
index efe4f01..46a43e4 100644
--- a/framework/private/src/bundle_cache.c
+++ b/framework/private/src/bundle_cache.c
@@ -74,14 +74,15 @@ celix_status_t bundleCache_destroy(bundle_cache_pt *cache) {
 }
 
 celix_status_t bundleCache_delete(bundle_cache_pt cache) {
-    printf("DELETING CACHE DIR: %s\n", cache->cacheDir);
     return bundleCache_deleteTree(cache, cache->cacheDir);
 }
 
 celix_status_t bundleCache_getArchives(bundle_cache_pt cache, array_list_pt *archives) {
-	celix_status_t status;
+	celix_status_t status = CELIX_SUCCESS;
 
 	DIR *dir;
+    struct stat st;
+
 	dir = opendir(cache->cacheDir);
 
 	if (dir == NULL && errno == ENOENT) {
@@ -103,16 +104,18 @@ celix_status_t bundleCache_getArchives(bundle_cache_pt cache, array_list_pt *arc
 
             snprintf(archiveRoot, sizeof(archiveRoot), "%s/%s", cache->cacheDir, dp.d_name);
 
-            if (dp.d_type == DT_DIR
-                && (strcmp((dp.d_name), ".") != 0)
-                && (strcmp((dp.d_name), "..") != 0)
-                && (strncmp(dp.d_name, "bundle", 6) == 0)
-                && (strcmp(dp.d_name, "bundle0") != 0)) {
-
-                bundle_archive_pt archive = NULL;
-                status = bundleArchive_recreate(strdup(archiveRoot), &archive);
-                if (status == CELIX_SUCCESS) {
-                    arrayList_add(list, archive);
+            if (stat (archiveRoot, &st) == 0) {
+                if (S_ISDIR (st.st_mode)
+                    && (strcmp((dp.d_name), ".") != 0)
+                    && (strcmp((dp.d_name), "..") != 0)
+                    && (strncmp(dp.d_name, "bundle", 6) == 0)
+                    && (strcmp(dp.d_name, "bundle0") != 0)) {
+
+                    bundle_archive_pt archive = NULL;
+                    status = bundleArchive_recreate(strdup(archiveRoot), &archive);
+                    if (status == CELIX_SUCCESS) {
+                        arrayList_add(list, archive);
+                    }
                 }
             }
 
@@ -158,6 +161,8 @@ celix_status_t bundleCache_createArchive(bundle_cache_pt cache, long id, char *
 static celix_status_t bundleCache_deleteTree(bundle_cache_pt cache, char * directory) {
     DIR *dir;
     celix_status_t status = CELIX_SUCCESS;
+    struct stat st;
+
     dir = opendir(directory);
     if (dir == NULL) {
         status = CELIX_FILE_IO_EXCEPTION;
@@ -171,12 +176,14 @@ static celix_status_t bundleCache_deleteTree(bundle_cache_pt cache, char * direc
                 char subdir[512];
                 snprintf(subdir, sizeof(subdir), "%s/%s", directory, dp.d_name);
 
-                if (dp.d_type == DT_DIR) {
-                    status = bundleCache_deleteTree(cache, subdir);
-                } else {
-                    if (remove(subdir) != 0) {
-                        status = CELIX_FILE_IO_EXCEPTION;
-                        break;
+                if (stat(subdir, &st) == 0) {
+                    if (S_ISDIR (st.st_mode)) {
+                        status = bundleCache_deleteTree(cache, subdir);
+                    } else {
+                        if (remove(subdir) != 0) {
+                            status = CELIX_FILE_IO_EXCEPTION;
+                            break;
+                        }
                     }
                 }
             }


[26/38] celix git commit: CELIX-272: Remove WITH_APR defines from framwork .. again

Posted by pn...@apache.org.
CELIX-272: Remove WITH_APR defines from framwork .. again


Project: http://git-wip-us.apache.org/repos/asf/celix/repo
Commit: http://git-wip-us.apache.org/repos/asf/celix/commit/c34e595b
Tree: http://git-wip-us.apache.org/repos/asf/celix/tree/c34e595b
Diff: http://git-wip-us.apache.org/repos/asf/celix/diff/c34e595b

Branch: refs/heads/develop
Commit: c34e595bad77e222db94e0bac05090695c560ca7
Parents: a9edf1f
Author: Pepijn Noltes <pe...@gmail.com>
Authored: Mon Nov 16 20:17:17 2015 +0100
Committer: Pepijn Noltes <pe...@gmail.com>
Committed: Mon Nov 16 20:17:17 2015 +0100

----------------------------------------------------------------------
 framework/private/src/framework.c | 19 -------------------
 1 file changed, 19 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/celix/blob/c34e595b/framework/private/src/framework.c
----------------------------------------------------------------------
diff --git a/framework/private/src/framework.c b/framework/private/src/framework.c
index 25e2442..c3bc147 100644
--- a/framework/private/src/framework.c
+++ b/framework/private/src/framework.c
@@ -188,11 +188,7 @@ framework_logger_pt logger;
     #define fw_getLastError() dlerror()
 #endif
 
-#ifdef WITH_APR
-celix_status_t framework_create(framework_pt *framework, apr_pool_t *pool, properties_pt config) {
-#else
 celix_status_t framework_create(framework_pt *framework, properties_pt config) {
-#endif
     celix_status_t status = CELIX_SUCCESS;
 
     logger = hashMap_get(config, "logger");
@@ -212,9 +208,6 @@ celix_status_t framework_create(framework_pt *framework, properties_pt config) {
         status = CELIX_DO_IF(status, celixThreadMutex_create(&(*framework)->bundleListenerLock, NULL));
         status = CELIX_DO_IF(status, celixThreadCondition_init(&(*framework)->dispatcher, NULL));
         if (status == CELIX_SUCCESS) {
-#ifdef WITH_APR
-            (*framework)->pool = pool;
-#endif
             (*framework)->bundle = NULL;
             (*framework)->installedBundleMap = NULL;
             (*framework)->registry = NULL;
@@ -439,13 +432,7 @@ celix_status_t fw_init(framework_pt framework) {
     status = CELIX_DO_IF(status, celixThreadCondition_init(&framework->shutdownGate, NULL));
 
     bundle_context_pt context = NULL;
-#ifdef WITH_APR
-    apr_pool_t *bundlePool = NULL;
-    apr_pool_create(&bundlePool, framework->pool);
-    status = CELIX_DO_IF(status, bundleContext_create(bundlePool, framework, framework->logger, framework->bundle, &context));
-#else
     status = CELIX_DO_IF(status, bundleContext_create(framework, framework->logger, framework->bundle, &context));
-#endif
     status = CELIX_DO_IF(status, bundle_setContext(framework->bundle, context));
     if (status == CELIX_SUCCESS) {
         activator_pt activator = NULL;
@@ -699,13 +686,7 @@ celix_status_t fw_startBundle(framework_pt framework, bundle_pt bundle, int opti
                 name = NULL;
                 bundle_getCurrentModule(bundle, &module);
                 module_getSymbolicName(module, &name);
-#ifdef WITH_APR
-                apr_pool_t *bundlePool = NULL;
-                apr_pool_create(&bundlePool, framework->pool);
-                status = CELIX_DO_IF(status, bundleContext_create(bundlePool, framework, framework->logger, bundle, &context));
-#else
                 status = CELIX_DO_IF(status, bundleContext_create(framework, framework->logger, bundle, &context));
-#endif
                 status = CELIX_DO_IF(status, bundle_setContext(bundle, context));
 
                 if (status == CELIX_SUCCESS) {


[07/38] celix git commit: Merge branch 'develop' into feature/CELIX-272_synchronization_service_registry

Posted by pn...@apache.org.
Merge branch 'develop' into feature/CELIX-272_synchronization_service_registry


Project: http://git-wip-us.apache.org/repos/asf/celix/repo
Commit: http://git-wip-us.apache.org/repos/asf/celix/commit/df56860d
Tree: http://git-wip-us.apache.org/repos/asf/celix/tree/df56860d
Diff: http://git-wip-us.apache.org/repos/asf/celix/diff/df56860d

Branch: refs/heads/develop
Commit: df56860df72beddcbfeb147ca8bfb220c6b5668d
Parents: f0778a7 b307757
Author: Pepijn Noltes <pe...@gmail.com>
Authored: Wed Nov 11 13:57:35 2015 +0100
Committer: Pepijn Noltes <pe...@gmail.com>
Committed: Wed Nov 11 13:57:35 2015 +0100

----------------------------------------------------------------------
 .travis.yml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------



[24/38] celix git commit: CELIX-272: Remove incorrect ungetService from service tracker

Posted by pn...@apache.org.
CELIX-272: Remove incorrect ungetService from service tracker


Project: http://git-wip-us.apache.org/repos/asf/celix/repo
Commit: http://git-wip-us.apache.org/repos/asf/celix/commit/a9d379f6
Tree: http://git-wip-us.apache.org/repos/asf/celix/tree/a9d379f6
Diff: http://git-wip-us.apache.org/repos/asf/celix/diff/a9d379f6

Branch: refs/heads/develop
Commit: a9d379f6abe705c3dc6ebed33c5f9914124bbf10
Parents: 7199e5c
Author: Pepijn Noltes <pe...@gmail.com>
Authored: Mon Nov 16 18:16:58 2015 +0100
Committer: Pepijn Noltes <pe...@gmail.com>
Committed: Mon Nov 16 18:16:58 2015 +0100

----------------------------------------------------------------------
 framework/private/src/service_tracker.c | 1 -
 1 file changed, 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/celix/blob/a9d379f6/framework/private/src/service_tracker.c
----------------------------------------------------------------------
diff --git a/framework/private/src/service_tracker.c b/framework/private/src/service_tracker.c
index 23db0aa..8234cce 100644
--- a/framework/private/src/service_tracker.c
+++ b/framework/private/src/service_tracker.c
@@ -346,7 +346,6 @@ static celix_status_t serviceTracker_untrack(service_tracker_pt tracker, service
 		if (equals) {
 			arrayList_remove(tracker->tracked, i);
             serviceTracker_invokeRemovingService(tracker, tracked->reference, tracked->service);
-            bundleContext_ungetService(tracker->context, tracked->reference, NULL);
 			free(tracked);
             break;
 		}


[15/38] celix git commit: CELIX-289: partly revert of aec12cd9014aa0677599d01fd9e611d81eb563a9

Posted by pn...@apache.org.
CELIX-289: partly revert of aec12cd9014aa0677599d01fd9e611d81eb563a9


Project: http://git-wip-us.apache.org/repos/asf/celix/repo
Commit: http://git-wip-us.apache.org/repos/asf/celix/commit/f4aabbe0
Tree: http://git-wip-us.apache.org/repos/asf/celix/tree/f4aabbe0
Diff: http://git-wip-us.apache.org/repos/asf/celix/diff/f4aabbe0

Branch: refs/heads/develop
Commit: f4aabbe0f73469f5a4509f34d59ecad8e80e44c4
Parents: 1df04d8
Author: Bjoern Petri <bp...@apache.org>
Authored: Wed Nov 11 22:09:35 2015 +0100
Committer: Pepijn Noltes <pe...@gmail.com>
Committed: Thu Nov 12 17:40:27 2015 +0100

----------------------------------------------------------------------
 deployment_admin/private/src/deployment_admin_activator.c |  2 +-
 deployment_admin/private/src/log.c                        |  2 +-
 log_service/private/src/log.c                             | 10 +++++-----
 log_service/public/src/log_helper.c                       |  4 ++--
 .../discovery/private/src/endpoint_discovery_poller.c     |  2 +-
 .../topology_manager/private/src/topology_manager.c       |  3 ---
 6 files changed, 10 insertions(+), 13 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/celix/blob/f4aabbe0/deployment_admin/private/src/deployment_admin_activator.c
----------------------------------------------------------------------
diff --git a/deployment_admin/private/src/deployment_admin_activator.c b/deployment_admin/private/src/deployment_admin_activator.c
index 9a3ce5f..93fd6b5 100644
--- a/deployment_admin/private/src/deployment_admin_activator.c
+++ b/deployment_admin/private/src/deployment_admin_activator.c
@@ -64,7 +64,7 @@ celix_status_t bundleActivator_stop(void * userData, bundle_context_pt context)
 }
 
 celix_status_t bundleActivator_destroy(void * userData, bundle_context_pt context) {
-	celix_status_t status = CELIX_SUCCESS;
+	celix_status_t status;
 
 	bundle_activator_pt activator = (bundle_activator_pt) userData;
 

http://git-wip-us.apache.org/repos/asf/celix/blob/f4aabbe0/deployment_admin/private/src/log.c
----------------------------------------------------------------------
diff --git a/deployment_admin/private/src/log.c b/deployment_admin/private/src/log.c
index a5227ca..98e757d 100644
--- a/deployment_admin/private/src/log.c
+++ b/deployment_admin/private/src/log.c
@@ -55,7 +55,7 @@ celix_status_t log_destroy(log_pt *log) {
 }
 
 celix_status_t log_log(log_pt log, unsigned int type, properties_pt properties) {
-	celix_status_t status = CELIX_SUCCESS;
+	celix_status_t status;
 
 	log_event_pt event = NULL;
 

http://git-wip-us.apache.org/repos/asf/celix/blob/f4aabbe0/log_service/private/src/log.c
----------------------------------------------------------------------
diff --git a/log_service/private/src/log.c b/log_service/private/src/log.c
index 201c29d..a6c3887 100644
--- a/log_service/private/src/log.c
+++ b/log_service/private/src/log.c
@@ -222,7 +222,7 @@ celix_status_t log_bundleChanged(void *listener, bundle_event_pt event) {
 }
 
 celix_status_t log_frameworkEvent(void *listener, framework_event_pt event) {
-	celix_status_t status = CELIX_SUCCESS;
+	celix_status_t status;
 	log_pt logger = ((framework_listener_pt) listener)->handle;
 	log_entry_pt entry = NULL;
 
@@ -235,7 +235,7 @@ celix_status_t log_frameworkEvent(void *listener, framework_event_pt event) {
 }
 
 celix_status_t log_addLogListener(log_pt logger, log_listener_pt listener) {
-	celix_status_t status = CELIX_SUCCESS;
+	celix_status_t status;
 
 	status = celixThreadMutex_lock(&logger->listenerLock);
 
@@ -280,7 +280,7 @@ celix_status_t log_removeLogListener(log_pt logger, log_listener_pt listener) {
 }
 
 celix_status_t log_removeAllLogListener(log_pt logger) {
-	celix_status_t status = CELIX_SUCCESS;
+	celix_status_t status;
 
 	status = celixThreadMutex_lock(&logger->listenerLock);
 
@@ -294,7 +294,7 @@ celix_status_t log_removeAllLogListener(log_pt logger) {
 }
 
 static celix_status_t log_startListenerThread(log_pt logger) {
-	celix_status_t status = CELIX_SUCCESS;
+	celix_status_t status;
 
 	logger->running = true;
     logger->running = true;
@@ -304,7 +304,7 @@ static celix_status_t log_startListenerThread(log_pt logger) {
 }
 
 static celix_status_t log_stopListenerThread(log_pt logger) {
-	celix_status_t status = CELIX_SUCCESS;
+	celix_status_t status;
 
 	logger->running = false;
 

http://git-wip-us.apache.org/repos/asf/celix/blob/f4aabbe0/log_service/public/src/log_helper.c
----------------------------------------------------------------------
diff --git a/log_service/public/src/log_helper.c b/log_service/public/src/log_helper.c
index 0b17a36..69ea3eb 100644
--- a/log_service/public/src/log_helper.c
+++ b/log_service/public/src/log_helper.c
@@ -84,7 +84,7 @@ celix_status_t logHelper_create(bundle_context_pt context, log_helper_pt* loghel
 
 celix_status_t logHelper_start(log_helper_pt loghelper)
 {
-	celix_status_t status = CELIX_SUCCESS;
+	celix_status_t status;
 	service_tracker_customizer_pt logTrackerCustomizer = NULL;
 
 	status = serviceTrackerCustomizer_create(loghelper, NULL, logHelper_logServiceAdded, NULL, logHelper_logServiceRemoved, &logTrackerCustomizer);
@@ -126,7 +126,7 @@ celix_status_t logHelper_logServiceRemoved(void *handle, service_reference_pt re
 
 
 celix_status_t logHelper_stop(log_helper_pt loghelper) {
-	celix_status_t status = CELIX_SUCCESS;
+	celix_status_t status;
 
     status = serviceTracker_close(loghelper->logServiceTracker);
 

http://git-wip-us.apache.org/repos/asf/celix/blob/f4aabbe0/remote_services/discovery/private/src/endpoint_discovery_poller.c
----------------------------------------------------------------------
diff --git a/remote_services/discovery/private/src/endpoint_discovery_poller.c b/remote_services/discovery/private/src/endpoint_discovery_poller.c
index 60a9236..ec0a1b3 100644
--- a/remote_services/discovery/private/src/endpoint_discovery_poller.c
+++ b/remote_services/discovery/private/src/endpoint_discovery_poller.c
@@ -242,7 +242,7 @@ celix_status_t endpointDiscoveryPoller_removeDiscoveryEndpoint(endpoint_discover
 
 
 celix_status_t endpointDiscoveryPoller_poll(endpoint_discovery_poller_pt poller, char *url, array_list_pt currentEndpoints) {
-	celix_status_t status = NULL;
+	celix_status_t status;
 	array_list_pt updatedEndpoints = NULL;
 
 	// create an arraylist with a custom equality test to ensure we can find endpoints properly...

http://git-wip-us.apache.org/repos/asf/celix/blob/f4aabbe0/remote_services/topology_manager/private/src/topology_manager.c
----------------------------------------------------------------------
diff --git a/remote_services/topology_manager/private/src/topology_manager.c b/remote_services/topology_manager/private/src/topology_manager.c
index 7711d53..acc6941 100644
--- a/remote_services/topology_manager/private/src/topology_manager.c
+++ b/remote_services/topology_manager/private/src/topology_manager.c
@@ -287,9 +287,6 @@ celix_status_t topologyManager_rsaRemoved(void * handle, service_reference_pt re
                 topologyManager_notifyListenersEndpointRemoved(manager, rsa, export);
                 rsa->exportRegistration_close(export);
             }
-
-            arrayList_destroy(exports_list);
-            exports_list = NULL;
         }
 
         hashMap_remove(exports, rsa);


[25/38] celix git commit: CELIX-272: Add rpath to dfi test setup.

Posted by pn...@apache.org.
CELIX-272: Add rpath to dfi test setup.


Project: http://git-wip-us.apache.org/repos/asf/celix/repo
Commit: http://git-wip-us.apache.org/repos/asf/celix/commit/a9edf1f2
Tree: http://git-wip-us.apache.org/repos/asf/celix/tree/a9edf1f2
Diff: http://git-wip-us.apache.org/repos/asf/celix/diff/a9edf1f2

Branch: refs/heads/develop
Commit: a9edf1f2f25a89f60dde6423f88e0dfcf6f56313
Parents: a9d379f
Author: Pepijn Noltes <pe...@gmail.com>
Authored: Mon Nov 16 18:17:20 2015 +0100
Committer: Pepijn Noltes <pe...@gmail.com>
Committed: Mon Nov 16 18:17:20 2015 +0100

----------------------------------------------------------------------
 .../dynamic_function_interface_tst/CMakeLists.txt               | 5 +++++
 1 file changed, 5 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/celix/blob/a9edf1f2/remote_services/remote_service_admin_dfi/dynamic_function_interface_tst/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_dfi/dynamic_function_interface_tst/CMakeLists.txt b/remote_services/remote_service_admin_dfi/dynamic_function_interface_tst/CMakeLists.txt
index 3c8a800..d42b606 100644
--- a/remote_services/remote_service_admin_dfi/dynamic_function_interface_tst/CMakeLists.txt
+++ b/remote_services/remote_service_admin_dfi/dynamic_function_interface_tst/CMakeLists.txt
@@ -19,6 +19,11 @@ include_directories(
 	../dynamic_function_interface
 )
 
+SET(CMAKE_SKIP_BUILD_RPATH  FALSE) #TODO needed?
+SET(CMAKE_BUILD_WITH_INSTALL_RPATH TRUE) #TODO needed?
+SET(CMAKE_INSTALL_RPATH "${PROJECT_BINARY_DIR}/remote_services/remote_service_admin_dfi/dynamic_function_interface")
+
+
 add_executable(test_dfi
 	dyn_type_tests.cpp
 	dyn_function_tests.cpp


[03/38] celix git commit: CELIX-272: Add celix rw lock thread support

Posted by pn...@apache.org.
CELIX-272: Add celix rw lock thread support


Project: http://git-wip-us.apache.org/repos/asf/celix/repo
Commit: http://git-wip-us.apache.org/repos/asf/celix/commit/a0926beb
Tree: http://git-wip-us.apache.org/repos/asf/celix/tree/a0926beb
Diff: http://git-wip-us.apache.org/repos/asf/celix/diff/a0926beb

Branch: refs/heads/develop
Commit: a0926beb0b8c9af2ce9256537702fbecd8be3d4e
Parents: e0231e5
Author: Pepijn Noltes <pe...@gmail.com>
Authored: Wed Nov 11 13:21:06 2015 +0100
Committer: Pepijn Noltes <pe...@gmail.com>
Committed: Wed Nov 11 13:21:06 2015 +0100

----------------------------------------------------------------------
 utils/private/src/celix_threads.c    | 28 ++++++++++++++++++++++++++++
 utils/public/include/celix_threads.h | 17 ++++++++++++++++-
 2 files changed, 44 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/celix/blob/a0926beb/utils/private/src/celix_threads.c
----------------------------------------------------------------------
diff --git a/utils/private/src/celix_threads.c b/utils/private/src/celix_threads.c
index d460dd7..bec374b 100644
--- a/utils/private/src/celix_threads.c
+++ b/utils/private/src/celix_threads.c
@@ -150,3 +150,31 @@ celix_status_t celixThreadCondition_broadcast(celix_thread_cond_t *cond) {
 celix_status_t celixThreadCondition_signal(celix_thread_cond_t *cond) {
     return pthread_cond_signal(cond);
 }
+
+celix_status_t celixThreadRwlock_create(celix_thread_rwlock_t *lock, celix_thread_rwlockattr_t *attr) {
+	return pthread_rwlock_init(lock, attr);
+}
+
+celix_status_t celixThreadRwlock_destroy(celix_thread_rwlock_t *lock) {
+	return pthread_rwlock_destroy(lock);
+}
+
+celix_status_t celixThreadRwlock_readLock(celix_thread_rwlock_t *lock) {
+	return pthread_rwlock_rdlock(lock);
+}
+
+celix_status_t celixThreadRwlock_writeLock(celix_thread_rwlock_t *lock) {
+	return pthread_rwlock_wrlock(lock);
+}
+
+celix_status_t celixThreadRwlock_unlock(celix_thread_rwlock_t *lock) {
+	return pthread_rwlock_unlock(lock);
+}
+
+celix_status_t celixThreadRwlockAttr_create(celix_thread_rwlockattr_t *attr) {
+	return pthread_rwlockattr_init(attr);
+}
+
+celix_status_t celixThreadRwlockAttr_destroy(celix_thread_rwlockattr_t *attr) {
+	return pthread_rwlockattr_destroy(attr);
+}

http://git-wip-us.apache.org/repos/asf/celix/blob/a0926beb/utils/public/include/celix_threads.h
----------------------------------------------------------------------
diff --git a/utils/public/include/celix_threads.h b/utils/public/include/celix_threads.h
index c59edef..1e7a7ad 100644
--- a/utils/public/include/celix_threads.h
+++ b/utils/public/include/celix_threads.h
@@ -46,7 +46,6 @@ typedef void *(*celix_thread_start_t)(void*);
 
 static const celix_thread_t celix_thread_default = { 0, 0 };
 
-
 celix_status_t celixThread_create(celix_thread_t *new_thread, celix_thread_attr_t *attr, celix_thread_start_t func, void *data);
 void celixThread_exit(void *exitStatus);
 celix_status_t celixThread_detach(celix_thread_t thread);
@@ -78,6 +77,21 @@ celix_status_t celixThreadMutexAttr_create(celix_thread_mutexattr_t *attr);
 celix_status_t celixThreadMutexAttr_destroy(celix_thread_mutexattr_t *attr);
 celix_status_t celixThreadMutexAttr_settype(celix_thread_mutexattr_t *attr, int type);
 
+typedef pthread_rwlock_t celix_thread_rwlock_t;
+typedef pthread_rwlockattr_t celix_thread_rwlockattr_t;
+
+celix_status_t celixThreadRwlock_create(celix_thread_rwlock_t *lock, celix_thread_rwlockattr_t *attr);
+
+celix_status_t celixThreadRwlock_destroy(celix_thread_rwlock_t *lock);
+celix_status_t celixThreadRwlock_readLock(celix_thread_rwlock_t *lock);
+celix_status_t celixThreadRwlock_writeLock(celix_thread_rwlock_t *lock);
+celix_status_t celixThreadRwlock_unlock(celix_thread_rwlock_t *lock);
+
+celix_status_t celixThreadRwlockAttr_create(celix_thread_rwlockattr_t *attr);
+celix_status_t celixThreadRwlockAttr_destroy(celix_thread_rwlockattr_t *attr);
+//NOTE: No support yet for setting specific rw lock attributes
+
+
 typedef pthread_cond_t celix_thread_cond_t;
 typedef pthread_condattr_t celix_thread_condattr_t;
 
@@ -87,4 +101,5 @@ celix_status_t celixThreadCondition_wait(celix_thread_cond_t *cond, celix_thread
 celix_status_t celixThreadCondition_broadcast(celix_thread_cond_t *cond);
 celix_status_t celixThreadCondition_signal(celix_thread_cond_t *cond);
 
+
 #endif /* CELIX_THREADS_H_ */


[33/38] celix git commit: CELIX-272: Remove secure_getenv usage for BSD/APPLE

Posted by pn...@apache.org.
CELIX-272: Remove secure_getenv usage for BSD/APPLE


Project: http://git-wip-us.apache.org/repos/asf/celix/repo
Commit: http://git-wip-us.apache.org/repos/asf/celix/commit/cf7acae8
Tree: http://git-wip-us.apache.org/repos/asf/celix/tree/cf7acae8
Diff: http://git-wip-us.apache.org/repos/asf/celix/diff/cf7acae8

Branch: refs/heads/develop
Commit: cf7acae85a859ca39c7ebccc9e9b16004742dc4c
Parents: 03da4ec
Author: Pepijn Noltes <pe...@gmail.com>
Authored: Tue Nov 17 10:14:26 2015 +0100
Committer: Pepijn Noltes <pe...@gmail.com>
Committed: Tue Nov 17 10:14:26 2015 +0100

----------------------------------------------------------------------
 dependency_manager/private/src/dm_shell_list_command.c | 4 ++++
 1 file changed, 4 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/celix/blob/cf7acae8/dependency_manager/private/src/dm_shell_list_command.c
----------------------------------------------------------------------
diff --git a/dependency_manager/private/src/dm_shell_list_command.c b/dependency_manager/private/src/dm_shell_list_command.c
index ed2c5f0..e174061 100644
--- a/dependency_manager/private/src/dm_shell_list_command.c
+++ b/dependency_manager/private/src/dm_shell_list_command.c
@@ -43,7 +43,11 @@ void dmListCommand_execute(bundle_context_pt context, char * line, FILE *out, FI
     array_list_pt servRefs = NULL;
     int i;
     bundleContext_getServiceReferences(context, DM_INFO_SERVICE_NAME ,NULL, &servRefs);
+#if defined(BSD) || defined(__APPLE__)
+    char *term = getenv("TERM");
+#else
     char *term = secure_getenv("TERM");
+#endif
     bool colors = false;
     if (strcmp("xterm-256color", term) == 0) {
         colors = true;


[13/38] celix git commit: CELIX-291: replace setenv/getenv w/ properties_set call

Posted by pn...@apache.org.
CELIX-291: replace setenv/getenv w/ properties_set call


Project: http://git-wip-us.apache.org/repos/asf/celix/repo
Commit: http://git-wip-us.apache.org/repos/asf/celix/commit/e651c8a6
Tree: http://git-wip-us.apache.org/repos/asf/celix/tree/e651c8a6
Diff: http://git-wip-us.apache.org/repos/asf/celix/diff/e651c8a6

Branch: refs/heads/develop
Commit: e651c8a63f1856db0efd16c10b3d6f77c00b921c
Parents: 37720bd
Author: Bjoern Petri <bp...@apache.org>
Authored: Thu Nov 12 08:22:20 2015 +0100
Committer: Pepijn Noltes <pe...@gmail.com>
Committed: Thu Nov 12 17:40:27 2015 +0100

----------------------------------------------------------------------
 framework/private/src/framework.c | 9 ++++-----
 1 file changed, 4 insertions(+), 5 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/celix/blob/e651c8a6/framework/private/src/framework.c
----------------------------------------------------------------------
diff --git a/framework/private/src/framework.c b/framework/private/src/framework.c
index 7e66dbe..d603207 100644
--- a/framework/private/src/framework.c
+++ b/framework/private/src/framework.c
@@ -329,8 +329,6 @@ celix_status_t framework_destroy(framework_pt framework) {
 
 	bundleCache_destroy(&framework->cache);
 
-	unsetenv(OSGI_FRAMEWORK_FRAMEWORK_UUID);
-
 	celixThreadCondition_destroy(&framework->dispatcher);
 	celixThreadMutex_destroy(&framework->bundleListenerLock);
 	celixThreadMutex_destroy(&framework->dispatcherLock);
@@ -359,7 +357,6 @@ celix_status_t fw_init(framework_pt framework) {
 	linked_list_pt wires = NULL;
 	array_list_pt archives = NULL;
 	bundle_archive_pt archive = NULL;
-	char uuid[37];
 
 	celix_status_t status = CELIX_SUCCESS;
 	status = CELIX_DO_IF(status, framework_acquireBundleLock(framework, framework->bundle, OSGI_FRAMEWORK_BUNDLE_INSTALLED|OSGI_FRAMEWORK_BUNDLE_RESOLVED|OSGI_FRAMEWORK_BUNDLE_STARTING|OSGI_FRAMEWORK_BUNDLE_ACTIVE));
@@ -387,11 +384,13 @@ celix_status_t fw_init(framework_pt framework) {
 
 	if (status == CELIX_SUCCESS) {
         /*create and store framework uuid*/
+        char uuid[37];
+
 	    uuid_t uid;
         uuid_generate(uid);
         uuid_unparse(uid, uuid);
-        // #TODO setenv has a memory leak
-        setenv(OSGI_FRAMEWORK_FRAMEWORK_UUID, uuid, true);
+
+        properties_set(framework->configurationMap, (char*) OSGI_FRAMEWORK_FRAMEWORK_UUID, uuid);
 
         framework->installedBundleMap = hashMap_create(utils_stringHash, NULL, utils_stringEquals, NULL);
 	}


[16/38] celix git commit: CELIX-290: fixed cmake warning in framework/CMakelist.txt (removed brackets from [COPYONLY] at line 351/353), fixed build warning in framework bundle_cache_test.cpp (mktemp depricated, used mkstemp instead), fixed a dev note acc

Posted by pn...@apache.org.
CELIX-290: fixed cmake warning in framework/CMakelist.txt (removed brackets from [COPYONLY] at line 351/353),
fixed build warning in framework bundle_cache_test.cpp (mktemp depricated, used mkstemp instead),
fixed a dev note accidentaly left in framework service_registry_test.cpp (used preprocessor symbol as dev note, will not do again),
fixed a lot of the framework mocks, used to not assign any of the output parameters, resulting in undefined behaviour,
updated most framework tests to accommodate for the mock changes,
expanded framework resolver test (WIP)


Project: http://git-wip-us.apache.org/repos/asf/celix/repo
Commit: http://git-wip-us.apache.org/repos/asf/celix/commit/1df04d81
Tree: http://git-wip-us.apache.org/repos/asf/celix/tree/1df04d81
Diff: http://git-wip-us.apache.org/repos/asf/celix/diff/1df04d81

Branch: refs/heads/develop
Commit: 1df04d81e08f734b13ef9b46926fca3cbecaa445
Parents: bffb8ea
Author: Bjoern Petri <bp...@apache.org>
Authored: Wed Nov 11 21:55:47 2015 +0100
Committer: Pepijn Noltes <pe...@gmail.com>
Committed: Thu Nov 12 17:40:27 2015 +0100

----------------------------------------------------------------------
 framework/CMakeLists.txt                        |  10 +-
 framework/private/mock/bundle_archive_mock.c    |  38 +++-
 framework/private/mock/bundle_cache_mock.c      |  15 +-
 framework/private/mock/bundle_context_mock.c    |  28 ++-
 framework/private/mock/bundle_mock.c            |  48 +++--
 framework/private/mock/bundle_revision_mock.c   |  19 +-
 framework/private/mock/capability_mock.c        |   9 +-
 framework/private/mock/filter_mock.c            |  15 +-
 framework/private/mock/framework_mock.c         |  11 +-
 framework/private/mock/manifest_mock.c          |   4 +-
 framework/private/mock/manifest_parser_mock.c   |  12 +-
 framework/private/mock/requirement_mock.c       |   1 -
 framework/private/mock/service_reference_mock.c |  12 +-
 framework/private/mock/service_registry_mock.c  |  53 +++++-
 .../mock/service_tracker_customizer_mock.c      |   8 +-
 framework/private/resources-test/properties.txt |   4 +-
 framework/private/src/resolver.c                |   4 +-
 framework/private/test/bundle_cache_test.cpp    |   4 +-
 framework/private/test/bundle_test.cpp          |  10 +-
 framework/private/test/capability_test.cpp      |  10 +-
 framework/private/test/framework_test.cpp       |   2 +-
 framework/private/test/module_test.cpp          | 175 +++++++++++------
 framework/private/test/requirement_test.cpp     |  10 +-
 framework/private/test/resolver_test.cpp        | 189 ++++++++++++++-----
 .../private/test/service_reference_test.cpp     |   1 -
 .../private/test/service_registration_test.cpp  |   4 +-
 .../private/test/service_registry_test.cpp      |   5 +-
 framework/private/test/service_tracker_test.cpp |  32 ++--
 framework/private/test/version_range_test.cpp   |  40 +++-
 framework/tst/CMakeLists.txt                    |   2 +-
 utils/private/test/celix_threads_test.cpp       |   2 +-
 31 files changed, 557 insertions(+), 220 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/celix/blob/1df04d81/framework/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/framework/CMakeLists.txt b/framework/CMakeLists.txt
index bf60b9e..7b447d3 100644
--- a/framework/CMakeLists.txt
+++ b/framework/CMakeLists.txt
@@ -259,8 +259,8 @@ if (FRAMEWORK)
             private/mock/requirement_mock.c
             private/mock/capability_mock.c
             private/mock/manifest_parser_mock.c
-            private/mock/wire_mock.c
             private/mock/version_mock.c
+            private/src/wire.c
             private/src/module.c
             private/src/resolver.c
             private/src/celix_errorcodes.c
@@ -348,9 +348,9 @@ if (FRAMEWORK)
 	        private/test/wire_test.cpp) 
 		target_link_libraries(wire_test ${CPPUTEST_LIBRARY} ${CPPUTEST_EXT_LIBRARY})
 		
-		configure_file(private/resources-test/manifest_sections.txt ${CMAKE_BINARY_DIR}/framework/resources-test/manifest_sections.txt [COPYONLY])
-		configure_file(private/resources-test/manifest.txt ${CMAKE_BINARY_DIR}/framework/resources-test/manifest.txt [COPYONLY])
-		configure_file(private/resources-test/properties.txt ${CMAKE_BINARY_DIR}/framework/resources-test/properties.txt [COPYONLY])
+		configure_file(private/resources-test/manifest_sections.txt ${CMAKE_BINARY_DIR}/framework/resources-test/manifest_sections.txt COPYONLY)
+		configure_file(private/resources-test/manifest.txt ${CMAKE_BINARY_DIR}/framework/resources-test/manifest.txt COPYONLY)
+		configure_file(private/resources-test/properties.txt ${CMAKE_BINARY_DIR}/framework/resources-test/properties.txt COPYONLY)
 				
 		#set_target_properties(wire_test PROPERTIES COMPILE_FLAGS "-include ${CPPUTEST_INCLUDE_DIR}/CppUTest/MemoryLeakDetectorMallocMacros.h -include ${CPPUTEST_INCLUDE_DIR}/CppUTest/MemoryLeakDetectorNewMacros.h")
 			
@@ -381,7 +381,7 @@ if (FRAMEWORK)
 	     add_test(NAME wire_test COMMAND wire_test)
 	    
 	     SETUP_TARGET_FOR_COVERAGE(attribute_test attribute_test ${CMAKE_BINARY_DIR}/coverage/attribute_test/attribute_test)
-        SETUP_TARGET_FOR_COVERAGE(bundle_archive_test bundle_archive_test ${CMAKE_BINARY_DIR}/coverage/bundle_archive/bundle_archive_test)
+        SETUP_TARGET_FOR_COVERAGE(bundle_archive_test bundle_archive_test ${CMAKE_BINARY_DIR}/coverage/bundle_archive_test/bundle_archive_test)
         SETUP_TARGET_FOR_COVERAGE(bundle_cache_test bundle_cache_test ${CMAKE_BINARY_DIR}/coverage/bundle_cache_test/bundle_cache_test)
         SETUP_TARGET_FOR_COVERAGE(bundle_context_test bundle_context_test ${CMAKE_BINARY_DIR}/coverage/bundle_context_test/bundle_context_test)
         SETUP_TARGET_FOR_COVERAGE(bundle_revision_test bundle_revision_test ${CMAKE_BINARY_DIR}/coverage/bundle_revision_test/bundle_revision_test)

http://git-wip-us.apache.org/repos/asf/celix/blob/1df04d81/framework/private/mock/bundle_archive_mock.c
----------------------------------------------------------------------
diff --git a/framework/private/mock/bundle_archive_mock.c b/framework/private/mock/bundle_archive_mock.c
index d9b416c..6493c79 100644
--- a/framework/private/mock/bundle_archive_mock.c
+++ b/framework/private/mock/bundle_archive_mock.c
@@ -63,27 +63,39 @@ celix_status_t bundleArchive_getId(bundle_archive_pt archive, long *id) {
 }
 
 celix_status_t bundleArchive_getLocation(bundle_archive_pt archive, char **location) {
-	mock_c()->actualCall("bundleArchive_getLocation");
+	mock_c()->actualCall("bundleArchive_getLocation")
+			->withPointerParameters("archive", archive)
+			->withOutputParameter("location", location);
 	return mock_c()->returnValue().value.intValue;
 }
 
 celix_status_t bundleArchive_getArchiveRoot(bundle_archive_pt archive, char **archiveRoot) {
-	mock_c()->actualCall("bundleArchive_getArchiveRoot");
+	mock_c()->actualCall("bundleArchive_getArchiveRoot")
+			->withPointerParameters("archive", archive)
+			->withOutputParameter("archiveRoot", archiveRoot);
 	return mock_c()->returnValue().value.intValue;
 }
 
 celix_status_t bundleArchive_revise(bundle_archive_pt archive, char * location, char *inputFile) {
-	mock_c()->actualCall("bundleArchive_revise");
+	mock_c()->actualCall("bundleArchive_revise")
+			->withPointerParameters("archive", archive)
+			->withStringParameters("location", location)
+			->withStringParameters("inputFile", inputFile);
 	return mock_c()->returnValue().value.intValue;
 }
 
 celix_status_t bundleArchive_rollbackRevise(bundle_archive_pt archive, bool *rolledback) {
-	mock_c()->actualCall("bundleArchive_rollbackRevise");
+	mock_c()->actualCall("bundleArchive_rollbackRevise")
+			->withPointerParameters("archive", archive)
+			->withOutputParameter("rolledback", rolledback);
 	return mock_c()->returnValue().value.intValue;
 }
 
 celix_status_t bundleArchive_getRevision(bundle_archive_pt archive, long revNr, bundle_revision_pt *revision) {
-	mock_c()->actualCall("bundleArchive_getRevision");
+	mock_c()->actualCall("bundleArchive_getRevision")
+			->withPointerParameters("archive", archive)
+			->withLongIntParameters("revNr", revNr)
+			->withOutputParameter("revision", revision);
 	return mock_c()->returnValue().value.intValue;
 }
 
@@ -95,12 +107,16 @@ celix_status_t bundleArchive_getCurrentRevision(bundle_archive_pt archive, bundl
 }
 
 celix_status_t bundleArchive_getCurrentRevisionNumber(bundle_archive_pt archive, long *revisionNumber) {
-	mock_c()->actualCall("bundleArchive_getCurrentRevisionNumber");
+	mock_c()->actualCall("bundleArchive_getCurrentRevisionNumber")
+			->withPointerParameters("archive", archive)
+			->withOutputParameter("revisionNumber", revisionNumber);
 	return mock_c()->returnValue().value.intValue;
 }
 
 celix_status_t bundleArchive_getRefreshCount(bundle_archive_pt archive, long *refreshCount) {
-	mock_c()->actualCall("bundleArchive_getRefreshCount");
+	mock_c()->actualCall("bundleArchive_getRefreshCount")
+			->withPointerParameters("archive", archive)
+			->withOutputParameter("refreshCount", refreshCount);
 	return mock_c()->returnValue().value.intValue;
 }
 
@@ -126,7 +142,9 @@ celix_status_t bundleArchive_setLastModified(bundle_archive_pt archive, time_t l
 }
 
 celix_status_t bundleArchive_getLastModified(bundle_archive_pt archive, time_t *lastModified) {
-	mock_c()->actualCall("bundleArchive_getLastModified");
+	mock_c()->actualCall("bundleArchive_getLastModified")
+			->withPointerParameters("archive", archive)
+			->withOutputParameter("lastModified", lastModified);
 	return mock_c()->returnValue().value.intValue;
 }
 
@@ -138,7 +156,9 @@ celix_status_t bundleArchive_setPersistentState(bundle_archive_pt archive, bundl
 }
 
 celix_status_t bundleArchive_getPersistentState(bundle_archive_pt archive, bundle_state_e *state) {
-	mock_c()->actualCall("bundleArchive_getPersistentState");
+	mock_c()->actualCall("bundleArchive_getPersistentState")
+			->withPointerParameters("archive", archive)
+			->withOutputParameter("state", state);
 	return mock_c()->returnValue().value.intValue;
 }
 

http://git-wip-us.apache.org/repos/asf/celix/blob/1df04d81/framework/private/mock/bundle_cache_mock.c
----------------------------------------------------------------------
diff --git a/framework/private/mock/bundle_cache_mock.c b/framework/private/mock/bundle_cache_mock.c
index 925245d..ac9f61c 100644
--- a/framework/private/mock/bundle_cache_mock.c
+++ b/framework/private/mock/bundle_cache_mock.c
@@ -28,7 +28,9 @@
 #include "bundle_cache.h"
 
 celix_status_t bundleCache_create(properties_pt configurationMap, bundle_cache_pt *bundle_cache) {
-	mock_c()->actualCall("bundleCache_create");
+	mock_c()->actualCall("bundleCache_create")
+		->withPointerParameters("configurationMap", configurationMap)
+		->withOutputParameter("bundle_cache", bundle_cache);
 	return mock_c()->returnValue().value.intValue;
 }
 
@@ -38,12 +40,19 @@ celix_status_t bundleCache_destroy(bundle_cache_pt *cache) {
 }
 
 celix_status_t bundleCache_getArchives(bundle_cache_pt cache, array_list_pt *archives) {
-	mock_c()->actualCall("bundleCache_getArchives");
+	mock_c()->actualCall("bundleCache_getArchives")
+			->withPointerParameters("cache", cache)
+			->withOutputParameter("archives", archives);
 	return mock_c()->returnValue().value.intValue;
 }
 
 celix_status_t bundleCache_createArchive(bundle_cache_pt cache, long id, char * location, char *inputFile, bundle_archive_pt *archive) {
-	mock_c()->actualCall("bundleCache_createArchive");
+	mock_c()->actualCall("bundleCache_createArchive")
+			->withPointerParameters("cache", cache)
+			->withLongIntParameters("id", id)
+			->withStringParameters("location", location)
+			->withStringParameters("inputFile", inputFile)
+			->withOutputParameter("archive", archive);
 	return mock_c()->returnValue().value.intValue;
 }
 

http://git-wip-us.apache.org/repos/asf/celix/blob/1df04d81/framework/private/mock/bundle_context_mock.c
----------------------------------------------------------------------
diff --git a/framework/private/mock/bundle_context_mock.c b/framework/private/mock/bundle_context_mock.c
index 9d3d79a..0e5ea6d 100644
--- a/framework/private/mock/bundle_context_mock.c
+++ b/framework/private/mock/bundle_context_mock.c
@@ -28,10 +28,10 @@
 #include "bundle_context.h"
 
 celix_status_t bundleContext_create(framework_pt framework, framework_logger_pt logger, bundle_pt bundle, bundle_context_pt *bundle_context) {
-        mock_c()->actualCall("bundleContext_create")
-                        ->withPointerParameters("framework", framework)
-                        ->withPointerParameters("logger", logger)
-                        ->withPointerParameters("bundle", bundle)
+	mock_c()->actualCall("bundleContext_create")
+			->withPointerParameters("framework", framework)
+			->withPointerParameters("logger", logger)
+			->withPointerParameters("bundle", bundle)
 			->withOutputParameter("bundle_context", (void **) bundle_context);
 	return mock_c()->returnValue().value.intValue;
 }
@@ -50,12 +50,12 @@ celix_status_t bundleContext_getFramework(bundle_context_pt context, framework_p
 	mock_c()->actualCall("bundleContext_getFramework")
 			->withPointerParameters("context", context)
 			->withOutputParameter("framework", (void **) framework);
-        return mock_c()->returnValue().value.intValue;
+	return mock_c()->returnValue().value.intValue;
 }
 
 celix_status_t bundleContext_installBundle(bundle_context_pt context, char * location, bundle_pt *bundle) {
-        mock_c()->actualCall("bundleContext_installBundle")
-                        ->withPointerParameters("context", context)
+	mock_c()->actualCall("bundleContext_installBundle")
+			->withPointerParameters("context", context)
 			->withStringParameters("location", location)
 			->withOutputParameter("bundle", (void **) bundle);
 	return mock_c()->returnValue().value.intValue;
@@ -136,12 +136,17 @@ celix_status_t bundleContext_ungetService(bundle_context_pt context, service_ref
 
 
 celix_status_t bundleContext_getBundles(bundle_context_pt context, array_list_pt *bundles) {
-	mock_c()->actualCall("bundleContext_getBundles");
+	mock_c()->actualCall("bundleContext_getBundles")
+			->withPointerParameters("context", context)
+			->withOutputParameter("bundles", bundles);
 	return mock_c()->returnValue().value.intValue;
 }
 
 celix_status_t bundleContext_getBundleById(bundle_context_pt context, long id, bundle_pt *bundle) {
-	mock_c()->actualCall("bundleContext_getBundleById");
+	mock_c()->actualCall("bundleContext_getBundleById")
+			->withPointerParameters("context", context)
+			->withLongIntParameters("id", id)
+			->withOutputParameter("bundle", bundle);
 	return mock_c()->returnValue().value.intValue;
 }
 
@@ -174,6 +179,9 @@ celix_status_t bundleContext_removeBundleListener(bundle_context_pt context, bun
 
 
 celix_status_t bundleContext_getProperty(bundle_context_pt context, const char *name, char **value) {
-	mock_c()->actualCall("bundleContext_getProperty");
+	mock_c()->actualCall("bundleContext_getProperty")
+			->withPointerParameters("context", context)
+			->withStringParameters("name", name)
+			->withOutputParameter("value", value);
 	return mock_c()->returnValue().value.intValue;
 }

http://git-wip-us.apache.org/repos/asf/celix/blob/1df04d81/framework/private/mock/bundle_mock.c
----------------------------------------------------------------------
diff --git a/framework/private/mock/bundle_mock.c b/framework/private/mock/bundle_mock.c
index 9802f51..a394d0f 100644
--- a/framework/private/mock/bundle_mock.c
+++ b/framework/private/mock/bundle_mock.c
@@ -28,7 +28,8 @@
 #include "bundle_private.h"
 
 celix_status_t bundle_create(bundle_pt * bundle) {
-	mock_c()->actualCall("bundle_create");
+	mock_c()->actualCall("bundle_create")
+			->withOutputParameter("bundle", bundle);
 	return mock_c()->returnValue().value.intValue;
 }
 
@@ -90,7 +91,9 @@ celix_status_t bundle_setActivator(bundle_pt bundle, activator_pt activator) {
 }
 
 celix_status_t bundle_getContext(bundle_pt bundle, bundle_context_pt *context) {
-	mock_c()->actualCall("bundle_getContext");
+	mock_c()->actualCall("bundle_getContext")
+			->withPointerParameters("bundle", bundle)
+			->withOutputParameter("context", context);
 	return mock_c()->returnValue().value.intValue;
 }
 
@@ -100,7 +103,10 @@ celix_status_t bundle_setContext(bundle_pt bundle, bundle_context_pt context) {
 }
 
 celix_status_t bundle_getEntry(bundle_pt bundle, char * name, char **entry) {
-	mock_c()->actualCall("bundle_getEntry");
+	mock_c()->actualCall("bundle_getEntry")
+			->withPointerParameters("bundle", bundle)
+			->withStringParameters("name", name)
+			->withOutputParameter("entry", entry);
 	return mock_c()->returnValue().value.intValue;
 }
 
@@ -186,27 +192,37 @@ int compareTo(service_reference_pt a, service_reference_pt b) {
 
 
 celix_status_t bundle_getState(bundle_pt bundle, bundle_state_e *state) {
-	mock_c()->actualCall("bundle_getState");
+	mock_c()->actualCall("bundle_getState")
+			->withPointerParameters("bundle", bundle)
+			->withOutputParameter("state", state);
 	return mock_c()->returnValue().value.intValue;
 }
 
 celix_status_t bundle_isLockable(bundle_pt bundle, bool *lockable) {
-	mock_c()->actualCall("bundle_isLockable");
+	mock_c()->actualCall("bundle_isLockable")
+			->withPointerParameters("bundle", bundle)
+			->withOutputParameter("lockable", lockable);
 	return mock_c()->returnValue().value.intValue;
 }
 
 celix_status_t bundle_getLockingThread(bundle_pt bundle, celix_thread_t *thread) {
-	mock_c()->actualCall("bundle_getLockingThread");
+	mock_c()->actualCall("bundle_getLockingThread")
+			->withPointerParameters("bundle", bundle)
+			->withOutputParameter("thread", thread);
 	return mock_c()->returnValue().value.intValue;
 }
 
 celix_status_t bundle_lock(bundle_pt bundle, bool *locked) {
-	mock_c()->actualCall("bundle_lock");
+	mock_c()->actualCall("bundle_lock")
+			->withPointerParameters("bundle", bundle)
+			->withOutputParameter("locked", locked);
 	return mock_c()->returnValue().value.intValue;
 }
 
 celix_status_t bundle_unlock(bundle_pt bundle, bool *unlocked) {
-	mock_c()->actualCall("bundle_unlock");
+	mock_c()->actualCall("bundle_unlock")
+			->withPointerParameters("bundle", bundle)
+			->withOutputParameter("unlocked", unlocked);
 	return mock_c()->returnValue().value.intValue;
 }
 
@@ -228,18 +244,24 @@ celix_status_t bundle_refresh(bundle_pt bundle) {
 }
 
 celix_status_t bundle_getBundleId(bundle_pt bundle, long *id) {
-	mock_c()->actualCall("bundle_getBundleId");
+	mock_c()->actualCall("bundle_getBundleId")
+			->withPointerParameters("bundle", bundle)
+			->withOutputParameter("id", id);
 	return mock_c()->returnValue().value.intValue;
 }
 
 
 celix_status_t bundle_getRegisteredServices(bundle_pt bundle, array_list_pt *list) {
-	mock_c()->actualCall("bundle_getRegisteredServices");
+	mock_c()->actualCall("bundle_getRegisteredServices")
+			->withPointerParameters("bundle", bundle)
+			->withOutputParameter("list", list);
 	return mock_c()->returnValue().value.intValue;
 }
 
 celix_status_t bundle_getServicesInUse(bundle_pt bundle, array_list_pt *list) {
-	mock_c()->actualCall("bundle_getServicesInUse");
+	mock_c()->actualCall("bundle_getServicesInUse")
+			->withPointerParameters("bundle", bundle)
+			->withOutputParameter("list", list);
 	return mock_c()->returnValue().value.intValue;
 }
 
@@ -249,7 +271,9 @@ celix_status_t bundle_setFramework(bundle_pt bundle, framework_pt framework) {
 }
 
 celix_status_t bundle_getFramework(bundle_pt bundle, framework_pt *framework) {
-	mock_c()->actualCall("bundle_getFramework");
+	mock_c()->actualCall("bundle_getFramework")
+			->withPointerParameters("bundle", bundle)
+			->withOutputParameter("framework", framework);
 	return mock_c()->returnValue().value.intValue;
 }
 

http://git-wip-us.apache.org/repos/asf/celix/blob/1df04d81/framework/private/mock/bundle_revision_mock.c
----------------------------------------------------------------------
diff --git a/framework/private/mock/bundle_revision_mock.c b/framework/private/mock/bundle_revision_mock.c
index 847467c..0e24be5 100644
--- a/framework/private/mock/bundle_revision_mock.c
+++ b/framework/private/mock/bundle_revision_mock.c
@@ -28,7 +28,12 @@
 #include "bundle_revision.h"
 
 celix_status_t bundleRevision_create(char *root, char *location, long revisionNr, char *inputFile, bundle_revision_pt *bundle_revision) {
-	mock_c()->actualCall("bundleRevision_create");
+	mock_c()->actualCall("bundleRevision_create")
+			->withStringParameters("root", root)
+			->withStringParameters("location", location)
+			->withLongIntParameters("revisionNr", revisionNr)
+			->withStringParameters("inputFile", inputFile)
+			->withOutputParameter("bundle_revision", bundle_revision);
 	return mock_c()->returnValue().value.intValue;
 }
 
@@ -38,17 +43,23 @@ celix_status_t bundleRevision_destroy(bundle_revision_pt revision) {
 }
 
 celix_status_t bundleRevision_getNumber(bundle_revision_pt revision, long *revisionNr) {
-	mock_c()->actualCall("bundleRevision_getNumber");
+	mock_c()->actualCall("bundleRevision_getNumber")
+			->withPointerParameters("revision", revision)
+			->withOutputParameter("revisionNr", revisionNr);
 	return mock_c()->returnValue().value.intValue;
 }
 
 celix_status_t bundleRevision_getLocation(bundle_revision_pt revision, char **location) {
-	mock_c()->actualCall("bundleRevision_getLocation");
+	mock_c()->actualCall("bundleRevision_getLocation")
+			->withPointerParameters("revision", revision)
+			->withOutputParameter("location", location);
 	return mock_c()->returnValue().value.intValue;
 }
 
 celix_status_t bundleRevision_getRoot(bundle_revision_pt revision, char **root) {
-	mock_c()->actualCall("bundleRevision_getRoot");
+	mock_c()->actualCall("bundleRevision_getRoot")
+			->withPointerParameters("revision", revision)
+			->withOutputParameter("root", root);
 	return mock_c()->returnValue().value.intValue;
 }
 

http://git-wip-us.apache.org/repos/asf/celix/blob/1df04d81/framework/private/mock/capability_mock.c
----------------------------------------------------------------------
diff --git a/framework/private/mock/capability_mock.c b/framework/private/mock/capability_mock.c
index 83bd39b..324e8d0 100644
--- a/framework/private/mock/capability_mock.c
+++ b/framework/private/mock/capability_mock.c
@@ -28,12 +28,17 @@
 #include "capability.h"
 
 celix_status_t capability_create(module_pt module, hash_map_pt directives, hash_map_pt attributes, capability_pt *capability) {
-	mock_c()->actualCall("capability_create");
+	mock_c()->actualCall("capability_create")
+			->withPointerParameters("module", module)
+			->withPointerParameters("directives", directives)
+			->withPointerParameters("attributes", attributes)
+			->withOutputParameter("capability", capability);
 	return mock_c()->returnValue().value.intValue;
 }
 
 celix_status_t capability_destroy(capability_pt capability) {
-	mock_c()->actualCall("capability_destroy");
+	mock_c()->actualCall("capability_destroy")
+			->withPointerParameters("capability", capability);
 	return mock_c()->returnValue().value.intValue;
 }
 

http://git-wip-us.apache.org/repos/asf/celix/blob/1df04d81/framework/private/mock/filter_mock.c
----------------------------------------------------------------------
diff --git a/framework/private/mock/filter_mock.c b/framework/private/mock/filter_mock.c
index 8242b99..ba2b9c1 100644
--- a/framework/private/mock/filter_mock.c
+++ b/framework/private/mock/filter_mock.c
@@ -28,20 +28,27 @@
 #include "filter.h"
 
 filter_pt filter_create(char * filterString) {
-	mock_c()->actualCall("filter_create");
+	mock_c()->actualCall("filter_create")
+			->withStringParameters("filterString", filterString);
 	return mock_c()->returnValue().value.pointerValue;
 }
 
 void filter_destroy(filter_pt filter) {
-	mock_c()->actualCall("filter_destroy");
+	mock_c()->actualCall("filter_destroy")
+			->withPointerParameters("filter", filter);
 }
 
 celix_status_t filter_match(filter_pt filter, properties_pt properties, bool *result) {
-	mock_c()->actualCall("filter_match");
+	mock_c()->actualCall("filter_match")
+			->withPointerParameters("filter", filter)
+			->withPointerParameters("properties", properties)
+			->withOutputParameter("result", result);
 	return mock_c()->returnValue().value.intValue;
 }
 
 celix_status_t filter_getString(filter_pt filter, char **filterStr) {
-	mock_c()->actualCall("filter_getString");
+	mock_c()->actualCall("filter_getString")
+			->withPointerParameters("filter", filter)
+			->withOutputParameter("filterStr", filterStr);
 	return mock_c()->returnValue().value.intValue;
 }

http://git-wip-us.apache.org/repos/asf/celix/blob/1df04d81/framework/private/mock/framework_mock.c
----------------------------------------------------------------------
diff --git a/framework/private/mock/framework_mock.c b/framework/private/mock/framework_mock.c
index c6fb2e9..cf941d4 100644
--- a/framework/private/mock/framework_mock.c
+++ b/framework/private/mock/framework_mock.c
@@ -273,7 +273,8 @@ service_registration_pt findRegistration(service_reference_pt reference) {
 
 
 service_reference_pt listToArray(array_list_pt list) {
-	mock_c()->actualCall("listToArray");
+	mock_c()->actualCall("listToArray")
+			->withPointerParameters("list", list);
 		return mock_c()->returnValue().value.pointerValue;
 }
 
@@ -296,7 +297,9 @@ array_list_pt framework_getBundles(framework_pt framework) {
 }
 
 bundle_pt framework_getBundle(framework_pt framework, char * location) {
-	mock_c()->actualCall("framework_getBundle");
+	mock_c()->actualCall("framework_getBundle")
+			->withPointerParameters("framework", framework)
+			->withStringParameters("location", location);
 		return mock_c()->returnValue().value.pointerValue;
 }
 
@@ -308,7 +311,9 @@ bundle_pt framework_getBundleById(framework_pt framework, long id) {
 }
 
 celix_status_t framework_getFrameworkBundle(framework_pt framework, bundle_pt *bundle) {
-	mock_c()->actualCall("framework_getFrameworkBundle");
+	mock_c()->actualCall("framework_getFrameworkBundle")
+			->withPointerParameters("framework", framework)
+			->withOutputParameter("bundle", bundle);
 	return mock_c()->returnValue().value.intValue;
 }
 

http://git-wip-us.apache.org/repos/asf/celix/blob/1df04d81/framework/private/mock/manifest_mock.c
----------------------------------------------------------------------
diff --git a/framework/private/mock/manifest_mock.c b/framework/private/mock/manifest_mock.c
index a74601c..53e688c 100644
--- a/framework/private/mock/manifest_mock.c
+++ b/framework/private/mock/manifest_mock.c
@@ -55,7 +55,9 @@ properties_pt manifest_getMainAttributes(manifest_pt manifest) {
 }
 
 celix_status_t manifest_getEntries(manifest_pt manifest, hash_map_pt *map) {
-	mock_c()->actualCall("manifest_getEntries");
+	mock_c()->actualCall("manifest_getEntries")
+			->withPointerParameters("manifest", manifest)
+			->withOutputParameter("map", map);
 	return mock_c()->returnValue().value.intValue;
 }
 

http://git-wip-us.apache.org/repos/asf/celix/blob/1df04d81/framework/private/mock/manifest_parser_mock.c
----------------------------------------------------------------------
diff --git a/framework/private/mock/manifest_parser_mock.c b/framework/private/mock/manifest_parser_mock.c
index dd55020..34b02fa 100644
--- a/framework/private/mock/manifest_parser_mock.c
+++ b/framework/private/mock/manifest_parser_mock.c
@@ -28,35 +28,43 @@
 #include "manifest_parser.h"
 
 celix_status_t manifestParser_create(module_pt owner, manifest_pt manifest, manifest_parser_pt *manifest_parser) {
-	mock_c()->actualCall("manifestParser_create");
+	mock_c()->actualCall("manifestParser_create")
+			->withPointerParameters("owner", owner)
+			->withPointerParameters("manifest", manifest)
+			->withOutputParameter("manifest_parser", manifest_parser);
 	return mock_c()->returnValue().value.intValue;
 }
 
 celix_status_t manifestParser_destroy(manifest_parser_pt manifest_parser) {
-    mock_c()->actualCall("manifestParser_destroy");
+    mock_c()->actualCall("manifestParser_destroy")
+    		->withPointerParameters("manifest_parser", manifest_parser);
     return mock_c()->returnValue().value.intValue;
 }
 
 celix_status_t manifestParser_getSymbolicName(manifest_parser_pt parser, char **symbolicName) {
 	mock_c()->actualCall("manifestParser_getSymbolicName")
+			->withPointerParameters("parser", parser)
 			->withOutputParameter("symbolicName", (void**) symbolicName);
 	return mock_c()->returnValue().value.intValue;
 }
 
 celix_status_t manifestParser_getBundleVersion(manifest_parser_pt parser, version_pt *version) {
 	mock_c()->actualCall("manifestParser_getBundleVersion")
+			->withPointerParameters("parser", parser)
 			->withOutputParameter("version", (void**) version);
 	return mock_c()->returnValue().value.intValue;
 }
 
 celix_status_t manifestParser_getCapabilities(manifest_parser_pt parser, linked_list_pt *capabilities) {
 	mock_c()->actualCall("manifestParser_getCapabilities")
+			->withPointerParameters("parser", parser)
 			->withOutputParameter("capabilities", (void**) capabilities);
 	return mock_c()->returnValue().value.intValue;
 }
 
 celix_status_t manifestParser_getRequirements(manifest_parser_pt parser, linked_list_pt *requirements) {
 	mock_c()->actualCall("manifestParser_getCurrentRequirements")
+			->withPointerParameters("parser", parser)
 			->withOutputParameter("requirements", (void**) requirements);
 	return mock_c()->returnValue().value.intValue;
 }

http://git-wip-us.apache.org/repos/asf/celix/blob/1df04d81/framework/private/mock/requirement_mock.c
----------------------------------------------------------------------
diff --git a/framework/private/mock/requirement_mock.c b/framework/private/mock/requirement_mock.c
index 38de079..6282e7d 100644
--- a/framework/private/mock/requirement_mock.c
+++ b/framework/private/mock/requirement_mock.c
@@ -32,7 +32,6 @@ celix_status_t requirement_create(hash_map_pt directives, hash_map_pt attributes
 			->withPointerParameters("directives", directives)
 			->withPointerParameters("attributes", attributes)
 			->withOutputParameter("requirement", (void **) requirement);
-//			->_andPointerOutputParameters("requirement", (void **) requirement);
 	return mock_c()->returnValue().value.intValue;
 }
 

http://git-wip-us.apache.org/repos/asf/celix/blob/1df04d81/framework/private/mock/service_reference_mock.c
----------------------------------------------------------------------
diff --git a/framework/private/mock/service_reference_mock.c b/framework/private/mock/service_reference_mock.c
index b60fb66..da4eede 100644
--- a/framework/private/mock/service_reference_mock.c
+++ b/framework/private/mock/service_reference_mock.c
@@ -63,7 +63,9 @@ celix_status_t serviceReference_getServiceRegistration(service_reference_pt refe
 }
 
 celix_status_t serviceReference_getBundle(service_reference_pt reference, bundle_pt *bundle) {
-	mock_c()->actualCall("serviceReference_getBundle");
+	mock_c()->actualCall("serviceReference_getBundle")
+		->withPointerParameters("reference", reference)
+		->withOutputParameter("bundle", bundle);
 	return mock_c()->returnValue().value.intValue;
 }
 
@@ -73,7 +75,9 @@ bool serviceReference_isAssignableTo(service_reference_pt reference, bundle_pt r
 }
 
 celix_status_t serviceReference_getUsingBundles(service_reference_pt reference, array_list_pt *bundles) {
-	mock_c()->actualCall("serviceReference_getUsingBundles");
+	mock_c()->actualCall("serviceReference_getUsingBundles")
+		->withPointerParameters("reference", reference)
+		->withOutputParameter("bundles", bundles);
 	return mock_c()->returnValue().value.intValue;
 }
 
@@ -91,7 +95,9 @@ unsigned int serviceReference_hashCode(void *referenceP) {
 }
 
 int serviceReference_equals2(void *reference1, void *reference2) {
-	mock_c()->actualCall("serviceReference_equals2");
+	mock_c()->actualCall("serviceReference_equals2")
+			->withPointerParameters("reference1", reference1)
+			->withPointerParameters("reference2", reference2);
 	return mock_c()->returnValue().value.intValue;
 }
 

http://git-wip-us.apache.org/repos/asf/celix/blob/1df04d81/framework/private/mock/service_registry_mock.c
----------------------------------------------------------------------
diff --git a/framework/private/mock/service_registry_mock.c b/framework/private/mock/service_registry_mock.c
index c72e427..f5e726e 100644
--- a/framework/private/mock/service_registry_mock.c
+++ b/framework/private/mock/service_registry_mock.c
@@ -28,7 +28,10 @@
 #include "service_registry.h"
 
 celix_status_t serviceRegistry_create(framework_pt framework, serviceChanged_function_pt serviceChanged, service_registry_pt *registry) {
-	mock_c()->actualCall("serviceRegistry_create");
+	mock_c()->actualCall("serviceRegistry_create")
+			->withPointerParameters("framework", framework)
+			->withPointerParameters("serviceChanged", serviceChanged)
+			->withOutputParameter("registry", registry);
 	return mock_c()->returnValue().value.intValue;
 }
 
@@ -38,22 +41,40 @@ 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) {
-	mock_c()->actualCall("serviceRegistry_getRegisteredServices");
+	mock_c()->actualCall("serviceRegistry_getRegisteredServices")
+			->withPointerParameters("registry", registry)
+			->withPointerParameters("bundle", bundle)
+			->withOutputParameter("services", services);
 	return mock_c()->returnValue().value.intValue;
 }
 
 celix_status_t serviceRegistry_getServicesInUse(service_registry_pt registry, bundle_pt bundle, array_list_pt *services) {
-	mock_c()->actualCall("serviceRegistry_getServicesInUse");
+	mock_c()->actualCall("serviceRegistry_getServicesInUse")
+			->withPointerParameters("registry", registry)
+			->withPointerParameters("bundle", bundle)
+			->withOutputParameter("services", services);
 	return mock_c()->returnValue().value.intValue;
 }
 
 celix_status_t serviceRegistry_registerService(service_registry_pt registry, bundle_pt bundle, char * serviceName, void * serviceObject, properties_pt dictionary, service_registration_pt *registration) {
-	mock_c()->actualCall("serviceRegistry_registerService");
+	mock_c()->actualCall("serviceRegistry_registerService")
+			->withPointerParameters("registry", registry)
+			->withPointerParameters("bundle", bundle)
+			->withStringParameters("serviceName", serviceName)
+			->withPointerParameters("serviceObject", serviceObject)
+			->withPointerParameters("dictionary", dictionary)
+			->withOutputParameter("registration", registration);
 	return mock_c()->returnValue().value.intValue;
 }
 
 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) {
-	mock_c()->actualCall("serviceRegistry_registerServiceFactory");
+	mock_c()->actualCall("serviceRegistry_registerServiceFactory")
+		->withPointerParameters("registry", registry)
+		->withPointerParameters("bundle", bundle)
+		->withStringParameters("serviceName", serviceName)
+		->withPointerParameters("factory", factory)
+		->withPointerParameters("dictionary", dictionary)
+		->withOutputParameter("registration", registration);
 	return mock_c()->returnValue().value.intValue;
 }
 
@@ -91,12 +112,19 @@ celix_status_t serviceRegistry_ungetServiceReferences(service_registry_pt regist
 }
 
 celix_status_t serviceRegistry_getService(service_registry_pt registry, bundle_pt bundle, service_reference_pt reference, void **service) {
-	mock_c()->actualCall("serviceRegistry_getService");
+	mock_c()->actualCall("serviceRegistry_getService")
+		->withPointerParameters("registry", registry)
+		->withPointerParameters("bundle", bundle)
+		->withPointerParameters("reference", reference)
+		->withOutputParameter("service", service);
 	return mock_c()->returnValue().value.intValue;
 }
 
 celix_status_t serviceRegistry_ungetService(service_registry_pt registry, bundle_pt bundle, service_reference_pt reference, bool *result) {
-	mock_c()->actualCall("serviceRegistry_ungetService");
+	mock_c()->actualCall("serviceRegistry_ungetService")
+		->withPointerParameters("registry", registry)
+		->withPointerParameters("bundle", bundle)
+		->withOutputParameter("result", result);
 	return mock_c()->returnValue().value.intValue;
 }
 
@@ -117,7 +145,11 @@ service_registration_pt serviceRegistry_findRegistration(service_registry_pt reg
 }
 
 celix_status_t serviceRegistry_createServiceReference(service_registry_pt registry, bundle_pt bundle, service_registration_pt registration, service_reference_pt *reference) {
-	mock_c()->actualCall("serviceRegistry_createServiceReference");
+	mock_c()->actualCall("serviceRegistry_createServiceReference")
+		->withPointerParameters("registry", registry)
+		->withPointerParameters("bundle", bundle)
+		->withPointerParameters("registration", registration)
+		->withOutputParameter("reference", reference);
 	return mock_c()->returnValue().value.intValue;
 }
 
@@ -130,7 +162,10 @@ celix_status_t serviceRegistry_getServiceReferencesForRegistration(service_regis
 }
 
 celix_status_t serviceRegistry_getListenerHooks(service_registry_pt registry, bundle_pt bundle, array_list_pt *hooks) {
-	mock_c()->actualCall("serviceRegistry_getListenerHooks");
+	mock_c()->actualCall("serviceRegistry_getListenerHooks")
+		->withPointerParameters("registry", registry)
+		->withPointerParameters("bundle", bundle)
+		->withOutputParameter("hooks", hooks);
 	return mock_c()->returnValue().value.intValue;
 }
 

http://git-wip-us.apache.org/repos/asf/celix/blob/1df04d81/framework/private/mock/service_tracker_customizer_mock.c
----------------------------------------------------------------------
diff --git a/framework/private/mock/service_tracker_customizer_mock.c b/framework/private/mock/service_tracker_customizer_mock.c
index 18ce3f9..9a9aae6 100644
--- a/framework/private/mock/service_tracker_customizer_mock.c
+++ b/framework/private/mock/service_tracker_customizer_mock.c
@@ -31,7 +31,13 @@ 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) {
-	mock_c()->actualCall("serviceTrackerCustomizer_create");
+	mock_c()->actualCall("serviceTrackerCustomizer_create")
+			->withPointerParameters("handle", handle)
+			->withPointerParameters("addingFunction", addingFunction)
+			->withPointerParameters("addedFunction", addedFunction)
+			->withPointerParameters("modifiedFunction", modifiedFunction)
+			->withPointerParameters("removedFunction", removedFunction)
+			->withOutputParameter("customizer", customizer);
 	return mock_c()->returnValue().value.intValue;
 }
 

http://git-wip-us.apache.org/repos/asf/celix/blob/1df04d81/framework/private/resources-test/properties.txt
----------------------------------------------------------------------
diff --git a/framework/private/resources-test/properties.txt b/framework/private/resources-test/properties.txt
index bc5cd15..30f3c79 100644
--- a/framework/private/resources-test/properties.txt
+++ b/framework/private/resources-test/properties.txt
@@ -15,4 +15,6 @@
 # specific language governing permissions and limitations
 # under the License.
 a=b
-b=c
\ No newline at end of file
+b=c
+ // == \\ # 5 \0 \=
+ #line to check possible special characters
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/celix/blob/1df04d81/framework/private/src/resolver.c
----------------------------------------------------------------------
diff --git a/framework/private/src/resolver.c b/framework/private/src/resolver.c
index 63b44a7..69d2557 100644
--- a/framework/private/src/resolver.c
+++ b/framework/private/src/resolver.c
@@ -459,9 +459,7 @@ linked_list_pt resolver_populateWireMap(hash_map_pt candidates, module_pt import
                                 linkedList_addElement(serviceWires, wire);
                             }
 
-                            wireMap = resolver_populateWireMap(candidates,
-                                    module,
-                                    wireMap);
+                            wireMap = resolver_populateWireMap(candidates,module,wireMap);
                         }
 
                         importerWires->wires = serviceWires;

http://git-wip-us.apache.org/repos/asf/celix/blob/1df04d81/framework/private/test/bundle_cache_test.cpp
----------------------------------------------------------------------
diff --git a/framework/private/test/bundle_cache_test.cpp b/framework/private/test/bundle_cache_test.cpp
index 71174fe..93794ce 100644
--- a/framework/private/test/bundle_cache_test.cpp
+++ b/framework/private/test/bundle_cache_test.cpp
@@ -95,7 +95,9 @@ TEST(bundle_cache, deleteTree) {
 
 	mkdir(cacheDir, S_IRWXU);
 	mkdir(cacheDir2, S_IRWXU);
-	mktemp(cacheFile);
+	//mkstemp opens the file for safety, but bundlecache_delete needs to reopen the file
+	close(mkstemp(cacheFile));
+
 
 	LONGS_EQUAL(CELIX_SUCCESS, bundleCache_delete(cache));
 }

http://git-wip-us.apache.org/repos/asf/celix/blob/1df04d81/framework/private/test/bundle_test.cpp
----------------------------------------------------------------------
diff --git a/framework/private/test/bundle_test.cpp b/framework/private/test/bundle_test.cpp
index 29fe5e8..bf17991 100644
--- a/framework/private/test/bundle_test.cpp
+++ b/framework/private/test/bundle_test.cpp
@@ -643,7 +643,10 @@ TEST(bundle, revise) {
 	char location[] = "location";
 	char inputFile[] = "inputFile";
 
-	mock().expectNCalls(2, "bundleArchive_revise");
+	mock().expectNCalls(2, "bundleArchive_revise")
+			.withParameter("archive", actual_archive)
+			.withParameter("location", location)
+			.withParameter("inputFile", inputFile);
 
 	mock().expectNCalls(2, "bundleArchive_getCurrentRevision")
 			.withParameter("archive", bundle->archive)
@@ -682,7 +685,10 @@ TEST(bundle, revise) {
 			.withOutputParameterReturning("symbolicName", &symbolic_name,sizeof(symbolic_name))
 			.andReturnValue(CELIX_ILLEGAL_ARGUMENT);
 
-	mock().expectOneCall("bundleArchive_rollbackRevise");
+	bool rolledBack = true;
+	mock().expectOneCall("bundleArchive_rollbackRevise")
+			.withParameter("archive", actual_archive)
+			.withOutputParameterReturning("rolledback", &rolledBack, sizeof(rolledBack));
 
 	mock().expectOneCall("framework_logCode")
 			.withParameter("code", CELIX_ILLEGAL_ARGUMENT);

http://git-wip-us.apache.org/repos/asf/celix/blob/1df04d81/framework/private/test/capability_test.cpp
----------------------------------------------------------------------
diff --git a/framework/private/test/capability_test.cpp b/framework/private/test/capability_test.cpp
index 4d9f2eb..146f1f9 100644
--- a/framework/private/test/capability_test.cpp
+++ b/framework/private/test/capability_test.cpp
@@ -90,8 +90,14 @@ TEST(capability, create) {
 	capability_pt capability = NULL;
 	celix_status_t status = capability_create(module, directives, attributes, &capability);
 
-	mock().expectNCalls(2, "attribute_destroy");
-	mock().expectOneCall("version_destroy");
+	mock().expectOneCall("attribute_destroy")
+			.withParameter("attribute", serviceAttribute);
+	mock().expectOneCall("attribute_destroy")
+			.withParameter("attribute", versionAttribute);
+
+	mock().expectOneCall("version_destroy")
+			.withParameter("version", emptyVersion);
+
 	capability_destroy(capability);
 }
 

http://git-wip-us.apache.org/repos/asf/celix/blob/1df04d81/framework/private/test/framework_test.cpp
----------------------------------------------------------------------
diff --git a/framework/private/test/framework_test.cpp b/framework/private/test/framework_test.cpp
index 81dabf5..586b400 100644
--- a/framework/private/test/framework_test.cpp
+++ b/framework/private/test/framework_test.cpp
@@ -55,7 +55,7 @@ TEST_GROUP(framework) {
 TEST(framework, create){
 	framework_pt framework = NULL;
 
-	mock().expectOneCall("bundle_create");
+	mock().expectOneCall("bundle_create").ignoreOtherParameters();
 
 	framework_create(&framework, properties);
 

http://git-wip-us.apache.org/repos/asf/celix/blob/1df04d81/framework/private/test/module_test.cpp
----------------------------------------------------------------------
diff --git a/framework/private/test/module_test.cpp b/framework/private/test/module_test.cpp
index 7936d96..7b56f2c 100644
--- a/framework/private/test/module_test.cpp
+++ b/framework/private/test/module_test.cpp
@@ -34,6 +34,8 @@
 
 extern "C" {
 #include "module.h"
+
+#include "manifest_parser.h"
 }
 
 int main(int argc, char** argv) {
@@ -70,8 +72,9 @@ TEST_GROUP(module) {
 TEST(module, create){
 	module_pt module = NULL;
 	manifest_pt actual_manifest = (manifest_pt) 0x01;
-	bundle_pt actual_bundle = (bundle_pt) 0x02;
-	version_pt actual_version = (version_pt) 0x03;
+	manifest_parser_pt parser = (manifest_parser_pt) 0x02;
+	bundle_pt actual_bundle = (bundle_pt) 0x03;
+	version_pt actual_version = (version_pt) 0x04;
 	linked_list_pt actual_capabilities = NULL;
 	linked_list_pt actual_requirements= NULL;
 	char * actual_name = my_strdup("module");
@@ -79,21 +82,30 @@ TEST(module, create){
 
 	linkedList_create(&actual_capabilities);
 	linkedList_create(&actual_requirements);
-	mock().expectOneCall("manifestParser_create");
+	mock().expectOneCall("manifestParser_create")
+			.withParameter("manifest", actual_manifest)
+			.withOutputParameterReturning("manifest_parser", &parser, sizeof(parser))
+			.ignoreOtherParameters();
 	mock().expectOneCall("manifestParser_getSymbolicName")
-					.withOutputParameterReturning("symbolicName", &actual_name, sizeof(actual_name) );
+			.withParameter("parser", parser)
+			.withOutputParameterReturning("symbolicName", &actual_name, sizeof(actual_name) );
 	mock().expectOneCall("manifestParser_getBundleVersion")
-					.withOutputParameterReturning("version", &actual_version, sizeof(version_pt) );
+			.withParameter("parser", parser)
+			.withOutputParameterReturning("version", &actual_version, sizeof(actual_version) );
 	mock().expectOneCall("manifestParser_getCapabilities")
-					.withOutputParameterReturning("capabilities", &actual_capabilities, sizeof(linked_list_pt) );
+			.withParameter("parser", parser)
+			.withOutputParameterReturning("capabilities", &actual_capabilities, sizeof(actual_capabilities) );
 	mock().expectOneCall("manifestParser_getCurrentRequirements")
-					.withOutputParameterReturning("requirements", &actual_requirements, sizeof(linked_list_pt) );
-	mock().expectOneCall("manifestParser_destroy");
+			.withParameter("parser", parser)
+			.withOutputParameterReturning("requirements", &actual_requirements, sizeof(actual_requirements) );
+	mock().expectOneCall("manifestParser_destroy")
+			.withParameter("manifest_parser", parser);
 
 	module = module_create(actual_manifest, actual_id, actual_bundle);
 	CHECK(module != NULL);
 
-	mock().expectOneCall("version_destroy");
+	mock().expectOneCall("version_destroy")
+			.withParameter("version", actual_version);
 	module_destroy(module);
 
 	free(actual_id);
@@ -102,14 +114,21 @@ TEST(module, create){
 TEST(module, createFrameworkModule){
 	module_pt module = NULL;
 	bundle_pt actual_bundle = (bundle_pt) 0x01;
+	version_pt actual_version = (version_pt) 0x02;
 
-	mock().expectOneCall("version_createVersion");
+	mock().expectOneCall("version_createVersion")
+			.withParameter("major", 1)
+			.withParameter("minor", 0)
+			.withParameter("micro", 0)
+			.withParameter("qualifier", "")
+			.withOutputParameterReturning("version", &actual_version, sizeof(actual_version));
 
 	module = module_createFrameworkModule(actual_bundle);
 
 	CHECK(module != NULL);
 
-	mock().expectOneCall("version_destroy");
+	mock().expectOneCall("version_destroy")
+			.withParameter("version", actual_version);
 
 	module_destroy(module);
 }
@@ -117,8 +136,9 @@ TEST(module, createFrameworkModule){
 TEST(module, resolved){
 	module_pt module = NULL;
 	manifest_pt actual_manifest = (manifest_pt) 0x01;
-	bundle_pt actual_bundle = (bundle_pt) 0x02;
-	version_pt actual_version = (version_pt) 0x03;
+	manifest_parser_pt parser = (manifest_parser_pt) 0x02;
+	bundle_pt actual_bundle = (bundle_pt) 0x03;
+	version_pt actual_version = (version_pt) 0x04;
 	linked_list_pt actual_capabilities = NULL;
 	linked_list_pt actual_requirements= NULL;
 	char * actual_name = my_strdup("module");
@@ -126,23 +146,32 @@ TEST(module, resolved){
 
 	linkedList_create(&actual_capabilities);
 	linkedList_create(&actual_requirements);
-	mock().expectOneCall("manifestParser_create");
+	mock().expectOneCall("manifestParser_create")
+			.withParameter("manifest", actual_manifest)
+			.withOutputParameterReturning("manifest_parser", &parser, sizeof(parser))
+			.ignoreOtherParameters();
 	mock().expectOneCall("manifestParser_getSymbolicName")
-					.withOutputParameterReturning("symbolicName", &actual_name, sizeof(actual_name) );
+			.withParameter("parser", parser)
+			.withOutputParameterReturning("symbolicName", &actual_name, sizeof(actual_name) );
 	mock().expectOneCall("manifestParser_getBundleVersion")
-					.withOutputParameterReturning("version", &actual_version, sizeof(version_pt) );
+			.withParameter("parser", parser)
+			.withOutputParameterReturning("version", &actual_version, sizeof(actual_version) );
 	mock().expectOneCall("manifestParser_getCapabilities")
-					.withOutputParameterReturning("capabilities", &actual_capabilities, sizeof(linked_list_pt) );
+			.withParameter("parser", parser)
+			.withOutputParameterReturning("capabilities", &actual_capabilities, sizeof(actual_capabilities) );
 	mock().expectOneCall("manifestParser_getCurrentRequirements")
-					.withOutputParameterReturning("requirements", &actual_requirements, sizeof(linked_list_pt) );
-	mock().expectOneCall("manifestParser_destroy");
+			.withParameter("parser", parser)
+			.withOutputParameterReturning("requirements", &actual_requirements, sizeof(actual_requirements) );
+	mock().expectOneCall("manifestParser_destroy")
+			.withParameter("manifest_parser", parser);
 	module = module_create(actual_manifest, actual_id, actual_bundle);
 
 	CHECK_FALSE(module_isResolved(module));
 	module_setResolved(module);
 	CHECK(module_isResolved(module));
 
-	mock().expectOneCall("version_destroy");
+	mock().expectOneCall("version_destroy")
+			.withParameter("version", actual_version);
 	module_destroy(module);
 
 	free(actual_id);
@@ -150,12 +179,13 @@ TEST(module, resolved){
 
 TEST(module, wires){
 	manifest_pt manifest = (manifest_pt) 0x01;
-	bundle_pt bundle = (bundle_pt) 0x02;
-	version_pt version = (version_pt) 0x03;
-	wire_pt wire = (wire_pt) 0x04;
-	wire_pt wire_new = (wire_pt) 0x05;
-	capability_pt cap = (capability_pt) 0x06;
-	requirement_pt req = (requirement_pt) 0x07;
+	manifest_parser_pt parser = (manifest_parser_pt) 0x02;
+	bundle_pt bundle = (bundle_pt) 0x03;
+	version_pt version = (version_pt) 0x04;
+	wire_pt wire = (wire_pt) 0x05;
+	wire_pt wire_new = (wire_pt) 0x06;
+	capability_pt cap = (capability_pt) 0x07;
+	requirement_pt req = (requirement_pt) 0x08;
 	char * service_name = my_strdup("foobar");
 
 	//test var declarations
@@ -186,16 +216,24 @@ TEST(module, wires){
 	linkedList_addElement(requirements, req);
 	linkedList_addElement(wires, wire);
 
-	mock().expectOneCall("manifestParser_create");
+	mock().expectOneCall("manifestParser_create")
+			.withParameter("manifest", manifest)
+			.withOutputParameterReturning("manifest_parser", &parser, sizeof(parser))
+			.ignoreOtherParameters();
 	mock().expectOneCall("manifestParser_getSymbolicName")
-						.withOutputParameterReturning("symbolicName", &name, sizeof(name));
+			.withParameter("parser", parser)
+			.withOutputParameterReturning("symbolicName", &name, sizeof(name) );
 	mock().expectOneCall("manifestParser_getBundleVersion")
-						.withOutputParameterReturning("version", &version, sizeof(version));
+			.withParameter("parser", parser)
+			.withOutputParameterReturning("version", &version, sizeof(version) );
 	mock().expectOneCall("manifestParser_getCapabilities")
-						.withOutputParameterReturning("capabilities", &capabilities, sizeof(capabilities));
+			.withParameter("parser", parser)
+			.withOutputParameterReturning("capabilities", &capabilities, sizeof(capabilities) );
 	mock().expectOneCall("manifestParser_getCurrentRequirements")
-						.withOutputParameterReturning("requirements", &requirements, sizeof(requirements));
-	mock().expectOneCall("manifestParser_destroy");
+			.withParameter("parser", parser)
+			.withOutputParameterReturning("requirements", &requirements, sizeof(requirements) );
+	mock().expectOneCall("manifestParser_destroy")
+			.withParameter("manifest_parser", parser);
 	module = module_create(manifest, id, bundle);
 
 	//create module2
@@ -203,17 +241,26 @@ TEST(module, wires){
 	linkedList_create(&requirements2);
 	linkedList_create(&wires_new);
 	linkedList_addElement(wires_new, wire_new);
-	mock().expectOneCall("manifestParser_create");
+
+	mock().expectOneCall("manifestParser_create")
+			.withParameter("manifest", manifest)
+			.withOutputParameterReturning("manifest_parser", &parser, sizeof(parser))
+			.ignoreOtherParameters();
 	mock().expectOneCall("manifestParser_getSymbolicName")
-						.withOutputParameterReturning("symbolicName", &name2, sizeof(name2));
+			.withParameter("parser", parser)
+			.withOutputParameterReturning("symbolicName", &name2, sizeof(name2) );
 	mock().expectOneCall("manifestParser_getBundleVersion")
-						.withOutputParameterReturning("version", &version, sizeof(version));
+			.withParameter("parser", parser)
+			.withOutputParameterReturning("version", &version, sizeof(version) );
 	mock().expectOneCall("manifestParser_getCapabilities")
-						.withOutputParameterReturning("capabilities", &capabilities2, sizeof(capabilities2));
+			.withParameter("parser", parser)
+			.withOutputParameterReturning("capabilities", &capabilities2, sizeof(capabilities2) );
 	mock().expectOneCall("manifestParser_getCurrentRequirements")
-						.withOutputParameterReturning("requirements", &requirements2, sizeof(requirements2));
-	mock().expectOneCall("manifestParser_destroy");
-	module2 = module_create(manifest, id, bundle);
+			.withParameter("parser", parser)
+			.withOutputParameterReturning("requirements", &requirements2, sizeof(requirements2) );
+	mock().expectOneCall("manifestParser_destroy")
+			.withParameter("manifest_parser", parser);
+	module2 = module_create(manifest, id2, bundle);
 
 	//test empty wires handling
 	POINTERS_EQUAL(NULL, module_getWire(module, service_name));
@@ -248,7 +295,8 @@ TEST(module, wires){
 					.withParameter("wire", wire)
 					.withOutputParameterReturning("exporter", &module2, sizeof(module2));
 
-	mock().expectOneCall("wire_destroy");
+	mock().expectOneCall("wire_destroy")
+			.withParameter("wire", wire);
 
 	mock().expectOneCall("wire_getExporter")
 					.withParameter("wire", wire_new)
@@ -269,10 +317,17 @@ TEST(module, wires){
 	module_removeDependentRequirer(module, module2);
 
 	//clean up
-	mock().expectNCalls(2, "version_destroy");
-	mock().expectOneCall("wire_destroy");
-	mock().expectOneCall("capability_destroy");
-	mock().expectOneCall("requirement_destroy");
+	mock().expectNCalls(2, "version_destroy")
+			.withParameter("version", version);
+
+	mock().expectOneCall("wire_destroy")
+			.withParameter("wire", wire_new);
+
+	mock().expectOneCall("capability_destroy")
+			.withParameter("capability", cap);
+
+	mock().expectOneCall("requirement_destroy")
+			.withParameter("requirement", req);
 	module_destroy(module);
 	module_destroy(module2);
 
@@ -285,8 +340,9 @@ TEST(module, wires){
 TEST(module, get){
 	module_pt module = NULL;
 	manifest_pt actual_manifest = (manifest_pt) 0x01;
-	bundle_pt actual_bundle = (bundle_pt) 0x02;
-	version_pt actual_version = (version_pt) 0x03;
+	manifest_parser_pt parser = (manifest_parser_pt) 0x02;
+	bundle_pt actual_bundle = (bundle_pt) 0x03;
+	version_pt actual_version = (version_pt) 0x04;
 	linked_list_pt actual_capabilities = NULL;
 	linked_list_pt actual_requirements= NULL;
 	char * actual_name = my_strdup("module");
@@ -296,20 +352,24 @@ TEST(module, get){
 	linkedList_create(&actual_capabilities);
 	linkedList_create(&actual_requirements);
 
-	mock().expectOneCall("manifestParser_create");
+	mock().expectOneCall("manifestParser_create")
+			.withParameter("manifest", actual_manifest)
+			.withOutputParameterReturning("manifest_parser", &parser, sizeof(parser))
+			.ignoreOtherParameters();
 	mock().expectOneCall("manifestParser_getSymbolicName")
-					.withOutputParameterReturning("symbolicName", &actual_name, sizeof(actual_name) );
-
+			.withParameter("parser", parser)
+			.withOutputParameterReturning("symbolicName", &actual_name, sizeof(actual_name) );
 	mock().expectOneCall("manifestParser_getBundleVersion")
-					.withOutputParameterReturning("version", &actual_version, sizeof(version_pt) );
-
+			.withParameter("parser", parser)
+			.withOutputParameterReturning("version", &actual_version, sizeof(actual_version) );
 	mock().expectOneCall("manifestParser_getCapabilities")
-					.withOutputParameterReturning("capabilities", &actual_capabilities, sizeof(linked_list_pt) );
-
+			.withParameter("parser", parser)
+			.withOutputParameterReturning("capabilities", &actual_capabilities, sizeof(actual_capabilities) );
 	mock().expectOneCall("manifestParser_getCurrentRequirements")
-					.withOutputParameterReturning("requirements", &actual_requirements, sizeof(linked_list_pt) );
-
-	mock().expectOneCall("manifestParser_destroy");
+			.withParameter("parser", parser)
+			.withOutputParameterReturning("requirements", &actual_requirements, sizeof(actual_requirements) );
+	mock().expectOneCall("manifestParser_destroy")
+			.withParameter("manifest_parser", parser);
 
 
 	module = module_create(actual_manifest, actual_id, actual_bundle);
@@ -328,7 +388,8 @@ TEST(module, get){
 
 	LONGS_EQUAL(CELIX_ILLEGAL_ARGUMENT, module_getSymbolicName(NULL, &get));
 
-	mock().expectOneCall("version_destroy");
+	mock().expectOneCall("version_destroy")
+			.withParameter("version", actual_version);
 
 	module_destroy(module);
 

http://git-wip-us.apache.org/repos/asf/celix/blob/1df04d81/framework/private/test/requirement_test.cpp
----------------------------------------------------------------------
diff --git a/framework/private/test/requirement_test.cpp b/framework/private/test/requirement_test.cpp
index b45f844..70114c5 100644
--- a/framework/private/test/requirement_test.cpp
+++ b/framework/private/test/requirement_test.cpp
@@ -88,8 +88,14 @@ TEST(requirement, create) {
 	requirement_pt requirement = NULL;
 	requirement_create(directives, attributes, &requirement);
 
-	mock().expectNCalls(2, "attribute_destroy");
-	mock().expectOneCall("versionRange_destroy");
+	mock().expectOneCall("attribute_destroy")
+			.withParameter("attribute", versionAttribute);
+
+	mock().expectOneCall("attribute_destroy")
+			.withParameter("attribute", serviceAttribute);
+
+	mock().expectOneCall("versionRange_destroy")
+			.withParameter("range", parsedRange);
 
 	requirement_destroy(requirement);
 }

http://git-wip-us.apache.org/repos/asf/celix/blob/1df04d81/framework/private/test/resolver_test.cpp
----------------------------------------------------------------------
diff --git a/framework/private/test/resolver_test.cpp b/framework/private/test/resolver_test.cpp
index df8e608..753acf5 100644
--- a/framework/private/test/resolver_test.cpp
+++ b/framework/private/test/resolver_test.cpp
@@ -35,6 +35,10 @@
 extern "C" {
 #include "resolver.h"
 #include "celix_log.h"
+#include "manifest_parser.h"
+#include "requirement_private.h"
+#include "capability_private.h"
+#include "version_private.h"
 
 framework_logger_pt logger = (framework_logger_pt) 0x42;
 }
@@ -73,62 +77,101 @@ TEST_GROUP(resolver) {
 TEST(resolver, resolve){
 	module_pt module;
 	module_pt module2;
-	manifest_pt actual_manifest = (manifest_pt) 0x01;
-	bundle_pt actual_bundle = (bundle_pt) 0x02;
-	version_pt actual_version = (version_pt) 0x03;
-	linked_list_pt actual_capabilities = NULL;
-	linked_list_pt actual_requirements= NULL;
-	char * actual_name = my_strdup("module");
-	char * actual_id = my_strdup("42");
-	char * actual_service_name = my_strdup("test_service_foo");
-	char * actual_service_name2 = my_strdup("test_service_bar");
-	requirement_pt req = (requirement_pt) 0x04;
-	requirement_pt req2= (requirement_pt) 0x05;
-	capability_pt cap = (capability_pt) 0x06;
-	capability_pt cap2= (capability_pt) 0x07;
-	linked_list_pt get;
+	manifest_pt manifest = (manifest_pt) 0x01;
+	manifest_pt manifest2 = (manifest_pt) 0x02;
+	manifest_parser_pt parser = (manifest_parser_pt) 0x03;
+	manifest_parser_pt parser2 = (manifest_parser_pt) 0x04;
+	bundle_pt bundle = (bundle_pt) 0x05;
+	version_pt version = (version_pt) malloc(sizeof(*version));
+	linked_list_pt capabilities = NULL;
+	linked_list_pt requirements = NULL;
+	linked_list_pt empty_capabilities = NULL;
+	linked_list_pt empty_requirements = NULL;
+	char * name = my_strdup("module_one");
+	char * name2 = my_strdup("module_two");
+	char * id = my_strdup("42");
+	char * id2 = my_strdup("43");
+	char * service_name = my_strdup("test_service_foo");
+	char * service_name2 = my_strdup("test_service_bar");
+	requirement_pt req = (requirement_pt) 0x06;
+	requirement_pt req2= (requirement_pt) 0x07;
+	capability_pt cap = (capability_pt) 0x08;
+	capability_pt cap2= (capability_pt) 0x09;
+	wire_pt get_wire;
+	importer_wires_pt get_importer_wires;
+	linked_list_pt get_wire_map;
 
 	//creating module
-	linkedList_create(&actual_capabilities);
-	linkedList_create(&actual_requirements);
-
-	linkedList_addElement(actual_requirements, req);
-	linkedList_addElement(actual_requirements, req2);
-	linkedList_addElement(actual_capabilities, cap);
-	linkedList_addElement(actual_capabilities, cap2);
-
-
-	mock().expectNCalls(2, "manifestParser_create");
-	mock().expectNCalls(2,"manifestParser_getSymbolicName")
-					.withOutputParameterReturning("symbolicName", &actual_name, sizeof(actual_name) );
-	mock().expectNCalls(2, "manifestParser_getBundleVersion")
-					.withOutputParameterReturning("version", &actual_version, sizeof(version_pt) );
-	mock().expectNCalls(2, "manifestParser_getCapabilities")
-					.withOutputParameterReturning("capabilities", &actual_capabilities, sizeof(linked_list_pt) );
-	mock().expectNCalls(2, "manifestParser_getCurrentRequirements")
-					.withOutputParameterReturning("requirements", &actual_requirements, sizeof(linked_list_pt) );
-	mock().expectNCalls(2, "manifestParser_destroy");
-
-	module = module_create(actual_manifest, actual_id, actual_bundle);
-	module2 = module_create(actual_manifest, actual_id, actual_bundle);
+	linkedList_create(&capabilities);
+	linkedList_create(&empty_capabilities);
+	linkedList_create(&requirements);
+	linkedList_create(&empty_requirements);
+
+	linkedList_addElement(requirements, req);
+	linkedList_addElement(requirements, req2);
+	linkedList_addElement(capabilities, cap);
+	linkedList_addElement(capabilities, cap2);
+
+
+	mock().expectOneCall("manifestParser_create")
+			.withParameter("manifest", manifest)
+			.withOutputParameterReturning("manifest_parser", &parser, sizeof(parser))
+			.ignoreOtherParameters();
+	mock().expectOneCall("manifestParser_getSymbolicName")
+			.withParameter("parser", parser)
+			.withOutputParameterReturning("symbolicName", &name, sizeof(name));
+	mock().expectOneCall("manifestParser_getBundleVersion")
+			.withParameter("parser", parser)
+			.withOutputParameterReturning("version", &version, sizeof(version_pt));
+	mock().expectOneCall("manifestParser_getCapabilities")
+			.withParameter("parser", parser)
+			.withOutputParameterReturning("capabilities", &empty_capabilities, sizeof(empty_capabilities));
+	mock().expectOneCall("manifestParser_getCurrentRequirements")
+			.withParameter("parser", parser)
+			.withOutputParameterReturning("requirements", &requirements, sizeof(requirements));
+	mock().expectOneCall("manifestParser_destroy")
+			.withParameter("manifest_parser", parser);
+
+	mock().expectOneCall("manifestParser_create")
+			.withParameter("manifest", manifest2)
+			.withOutputParameterReturning("manifest_parser", &parser2, sizeof(parser2))
+			.ignoreOtherParameters();
+	mock().expectOneCall("manifestParser_getSymbolicName")
+			.withParameter("parser", parser2)
+			.withOutputParameterReturning("symbolicName", &name2, sizeof(name2));
+	mock().expectOneCall("manifestParser_getBundleVersion")
+			.withParameter("parser", parser2)
+			.withOutputParameterReturning("version", &version, sizeof(version_pt));
+	mock().expectOneCall("manifestParser_getCapabilities")
+			.withParameter("parser", parser2)
+			.withOutputParameterReturning("capabilities", &capabilities, sizeof(linked_list_pt));
+	mock().expectOneCall("manifestParser_getCurrentRequirements")
+			.withParameter("parser", parser2)
+			.withOutputParameterReturning("requirements", &empty_requirements, sizeof(linked_list_pt));
+	mock().expectOneCall("manifestParser_destroy")
+			.withParameter("manifest_parser", parser2);
+
+
+	module = module_create(manifest, id, bundle);
+	module2 = module_create(manifest2, id2, bundle);
 
 	mock().expectOneCall("capability_getServiceName")
 			.withParameter("capability", cap)
-			.withOutputParameterReturning("serviceName", &actual_service_name, sizeof(actual_service_name));
+			.withOutputParameterReturning("serviceName", &service_name, sizeof(service_name));
 
 	mock().expectOneCall("capability_getServiceName")
 			.withParameter("capability", cap2)
-			.withOutputParameterReturning("serviceName", &actual_service_name2, sizeof(actual_service_name2));
+			.withOutputParameterReturning("serviceName", &service_name2, sizeof(service_name2));
 
 	resolver_addModule(module2);
 
-	mock().expectOneCall("requirement_getTargetName")
+	mock().expectOneCall( "requirement_getTargetName")
 			.withParameter("requirement", req)
-			.withOutputParameterReturning("targetName", &actual_service_name, sizeof(actual_service_name));
+			.withOutputParameterReturning("targetName", &service_name, sizeof(service_name));
 
 	mock().expectOneCall("requirement_getTargetName")
 			.withParameter("requirement", req2)
-			.withOutputParameterReturning("targetName", &actual_service_name2, sizeof(actual_service_name2));
+			.withOutputParameterReturning("targetName", &service_name2, sizeof(service_name2));
 
 	bool out = true;
 	mock().expectOneCall("requirement_isSatisfied")
@@ -141,28 +184,70 @@ TEST(resolver, resolve){
 			.withParameter("capability", cap2)
 			.withOutputParameterReturning("inRange", &out, sizeof(out));
 
-	mock().expectOneCall("capability_getModule")
+	mock().expectNCalls(2, "capability_getModule")
 			.withParameter("capability", cap)
-			.withOutputParameterReturning("module", &module, sizeof(module));
+			.withOutputParameterReturning("module", &module2, sizeof(module2));
+
+	mock().expectNCalls(2, "capability_getModule")
+			.withParameter("capability", cap2)
+			.withOutputParameterReturning("module", &module2, sizeof(module2));
+
+	get_wire_map = resolver_resolve(module);
+
+	get_importer_wires = (importer_wires_pt) linkedList_removeLast(get_wire_map);
+	if ( get_importer_wires->importer == module ) {
+		module_setWires(module, get_importer_wires->wires);
+		get_importer_wires = (importer_wires_pt) linkedList_removeLast(get_wire_map);
+		POINTERS_EQUAL(get_importer_wires->importer, module2);
+		module_setWires(module2, get_importer_wires->wires);
+	} else {
+		POINTERS_EQUAL(get_importer_wires->importer, module2);
+		module_setWires(module2, get_importer_wires->wires);
+		get_importer_wires = (importer_wires_pt) linkedList_removeLast(get_wire_map);
+		POINTERS_EQUAL(get_importer_wires->importer, module);
+		module_setWires(module, get_importer_wires->wires);
+	}
+
+	//test resolved module checking
+	module_setResolved(module);
+	POINTERS_EQUAL(NULL, resolver_resolve(module));
 
-	/*mock().expectOneCall("capability_getModule")
+	//CLEAN UP
+	mock().expectOneCall("capability_getServiceName")
 			.withParameter("capability", cap)
-			.withOutputParameterReturning("module", &module, sizeof(module));*/
+			.withOutputParameterReturning("serviceName", &service_name, sizeof(service_name));
 
-	get = resolver_resolve(module);
-	//CHECK(linkedList_contains(get, wire));
+	mock().expectOneCall("capability_getServiceName")
+			.withParameter("capability", cap2)
+			.withOutputParameterReturning("serviceName", &service_name2, sizeof(service_name2));
 
-	//test resolved module checking
+	resolver_removeModule(module2);
 
-	POINTERS_EQUAL(NULL, resolver_resolve(module));
+	mock().expectOneCall("requirement_destroy")
+			.withParameter("requirement", req);
+
+	mock().expectOneCall("requirement_destroy")
+			.withParameter("requirement", req2);
+
+	mock().expectOneCall("capability_destroy")
+			.withParameter("capability", cap);
+
+	mock().expectOneCall("capability_destroy")
+			.withParameter("capability", cap2);
+
+	mock().expectNCalls(2, "version_destroy")
+			.withParameter("version", version);
 
-	mock().expectOneCall("version_destroy");
 	module_destroy(module);
 	module_destroy(module2);
 
+	linkedList_destroy(get_wire_map);
 
-	free(actual_id);
-	free(actual_name);
+	free(id);
+	free(id2);
+	free(service_name);
+	free(service_name2);
+	free(version);
 }
 /*
 TEST(resolver, moduleResolved){

http://git-wip-us.apache.org/repos/asf/celix/blob/1df04d81/framework/private/test/service_reference_test.cpp
----------------------------------------------------------------------
diff --git a/framework/private/test/service_reference_test.cpp b/framework/private/test/service_reference_test.cpp
index 1c383ec..5d8213a 100644
--- a/framework/private/test/service_reference_test.cpp
+++ b/framework/private/test/service_reference_test.cpp
@@ -34,7 +34,6 @@
 extern "C" {
 #include "service_reference_private.h"
 #include "celix_log.h"
-#include "utils.h"
 
 framework_logger_pt logger;
 }

http://git-wip-us.apache.org/repos/asf/celix/blob/1df04d81/framework/private/test/service_registration_test.cpp
----------------------------------------------------------------------
diff --git a/framework/private/test/service_registration_test.cpp b/framework/private/test/service_registration_test.cpp
index cec62ef..a24c804 100644
--- a/framework/private/test/service_registration_test.cpp
+++ b/framework/private/test/service_registration_test.cpp
@@ -35,7 +35,7 @@ extern "C" {
 #include "service_registration_private.h"
 #include "celix_log.h"
 
-framework_logger_pt logger;
+framework_logger_pt logger = (framework_logger_pt) 0x42;
 }
 
 int main(int argc, char** argv) {
@@ -44,8 +44,6 @@ int main(int argc, char** argv) {
 
 TEST_GROUP(service_registration) {
 	void setup(void) {
-		logger = (framework_logger_pt) malloc(sizeof(*logger));
-        logger->logFunction = frameworkLogger_log;
 	}
 
 	void teardown() {

http://git-wip-us.apache.org/repos/asf/celix/blob/1df04d81/framework/private/test/service_registry_test.cpp
----------------------------------------------------------------------
diff --git a/framework/private/test/service_registry_test.cpp b/framework/private/test/service_registry_test.cpp
index 0175f45..507bda2 100644
--- a/framework/private/test/service_registry_test.cpp
+++ b/framework/private/test/service_registry_test.cpp
@@ -273,6 +273,10 @@ TEST(service_registry, unregisterService) {
 		.withParameter("registration", registration)
 		.andReturnValue(CELIX_SUCCESS);
 
+	mock()
+		.expectOneCall("serviceRegistration_destroy")
+		.withParameter("registration", registration);
+
 	serviceRegistry_unregisterService(registry, bundle, registration);
 
 	free(registry);
@@ -310,7 +314,6 @@ TEST(service_registry, unregisterServices) {
 }
 
 TEST(service_registry, getServiceReferencesForRegistration){
-#warning implement this
 	service_registry_pt registry = (service_registry_pt) malloc(sizeof(*registry));
 	registry->inUseMap = hashMap_create(NULL, NULL, NULL, NULL);
 	celixThreadMutexAttr_create(&registry->mutexAttr);

http://git-wip-us.apache.org/repos/asf/celix/blob/1df04d81/framework/private/test/service_tracker_test.cpp
----------------------------------------------------------------------
diff --git a/framework/private/test/service_tracker_test.cpp b/framework/private/test/service_tracker_test.cpp
index 06c268e..de9e3c0 100644
--- a/framework/private/test/service_tracker_test.cpp
+++ b/framework/private/test/service_tracker_test.cpp
@@ -612,12 +612,6 @@ TEST(service_tracker, serviceChangedModified) {
 		.ignoreOtherParameters()
 		.andReturnValue(CELIX_SUCCESS);
 
-	mock()
-			.expectOneCall("bundleContext_getService")
-			.withParameter("context", ctx)
-			.withParameter("reference", ref)
-			.withOutputParameterReturning("service_instance", &entry->service, sizeof(entry->service));
-
 	serviceTracker_serviceChanged(listener, event);
 
 	free(arrayList_get(tracked, 0));
@@ -830,18 +824,14 @@ TEST(service_tracker, serviceChangedModifiedCustomizer) {
 		.ignoreOtherParameters()
 		.andReturnValue(CELIX_SUCCESS);
 	void * handle = (void*) 0x60;
+
+/*	this branch is not covered here, unlike earlier faulty tests
 	mock()
-		.expectNCalls(2, "serviceTrackerCustomizer_getHandle")
+		.expectOneCall("serviceTrackerCustomizer_getHandle")
 		.withParameter("customizer", customizer)
 		.withOutputParameterReturning("handle", &handle, sizeof(handle))
 		.andReturnValue(CELIX_SUCCESS);
-	void *function = (void *) serviceDependency_modifiedService;
-/*	mock()
-		.expectOneCall("serviceTrackerCustomizer_getModifiedFunction")
-		.withParameter("customizer", customizer)
-		.withOutputParameterReturning("function", &function, sizeof(function))
-		.andReturnValue(CELIX_SUCCESS);
-*/
+
 	mock()
 		.expectOneCall("serviceTrackerCustomizer_getAddingFunction")
 		.withParameter("customizer", customizer)
@@ -853,13 +843,25 @@ TEST(service_tracker, serviceChangedModifiedCustomizer) {
 		.withParameter("customizer", customizer)
 		.withOutputParameterReturning("function", &added_func, sizeof(added_func));
 
-
 	mock()
 		.expectOneCall("bundleContext_getService")
 		.withParameter("context", ctx)
 		.withParameter("reference", ref)
 		.withOutputParameterReturning("service_instance", &entry->service, sizeof(entry->service));
+*/
 
+	mock()
+			.expectOneCall("serviceTrackerCustomizer_getHandle")
+			.withParameter("customizer", customizer)
+			.withOutputParameterReturning("handle", &handle, sizeof(handle))
+			.andReturnValue(CELIX_SUCCESS);
+
+	void *function = (void *) serviceDependency_modifiedService;
+	mock()
+		.expectOneCall("serviceTrackerCustomizer_getModifiedFunction")
+		.withParameter("customizer", customizer)
+		.withOutputParameterReturning("function", &function, sizeof(function))
+		.andReturnValue(CELIX_SUCCESS);
 
 	serviceTracker_serviceChanged(listener, event);
 

http://git-wip-us.apache.org/repos/asf/celix/blob/1df04d81/framework/private/test/version_range_test.cpp
----------------------------------------------------------------------
diff --git a/framework/private/test/version_range_test.cpp b/framework/private/test/version_range_test.cpp
index 95bf1b1..d16c38b 100644
--- a/framework/private/test/version_range_test.cpp
+++ b/framework/private/test/version_range_test.cpp
@@ -87,7 +87,8 @@ TEST(version_range, create) {
 	POINTERS_EQUAL(version, range->low);
 	POINTERS_EQUAL(version, range->high);
 
-	mock().expectNCalls(2, "version_destroy");
+	mock().expectNCalls(2, "version_destroy")
+			.withParameter("version", version);
 
 	versionRange_destroy(range);
 	free(version);
@@ -112,7 +113,8 @@ TEST(version_range, createInfinite) {
 	POINTERS_EQUAL(version, range->low);
 	POINTERS_EQUAL(NULL, range->high);
 
-	mock().expectOneCall("version_destroy");
+	mock().expectOneCall("version_destroy")
+			.withParameter("version", version);
 
 	versionRange_destroy(range);
 	free(version);
@@ -153,31 +155,49 @@ TEST(version_range, isInRange) {
 	versionRange_createVersionRange(low, true, high, true, &range);
 	LONGS_EQUAL(CELIX_SUCCESS, versionRange_isInRange(range, version, &result));
 	LONGS_EQUAL(true, result);
-	mock().expectNCalls(2, "version_destroy");
+
+	mock().expectOneCall("version_destroy")
+			.withParameter("version", low);
+	mock().expectOneCall("version_destroy")
+			.withParameter("version", high);
 	versionRange_destroy(range);
 
 	versionRange_createVersionRange(low, true, NULL, true, &range);
 	LONGS_EQUAL(CELIX_SUCCESS, versionRange_isInRange(range, version, &result));
 	LONGS_EQUAL(true, result);
-	mock().expectOneCall("version_destroy");
+
+	mock().expectOneCall("version_destroy")
+			.withParameter("version", low);
 	versionRange_destroy(range);
 
 	versionRange_createVersionRange(low, false, high, true, &range);
 	LONGS_EQUAL(CELIX_SUCCESS, versionRange_isInRange(range, version, &result));
 	LONGS_EQUAL(true, result);
-	mock().expectNCalls(2, "version_destroy");
+
+	mock().expectOneCall("version_destroy")
+			.withParameter("version", low);
+	mock().expectOneCall("version_destroy")
+			.withParameter("version", high);
 	versionRange_destroy(range);
 
 	versionRange_createVersionRange(low, true, high, false, &range);
 	LONGS_EQUAL(CELIX_SUCCESS, versionRange_isInRange(range, version, &result));
 	LONGS_EQUAL(true, result);
-	mock().expectNCalls(2, "version_destroy");
+
+	mock().expectOneCall("version_destroy")
+			.withParameter("version", low);
+	mock().expectOneCall("version_destroy")
+			.withParameter("version", high);
 	versionRange_destroy(range);
 
 	versionRange_createVersionRange(low, false, high, false, &range);
 	LONGS_EQUAL(CELIX_SUCCESS, versionRange_isInRange(range, version, &result));
 	LONGS_EQUAL(true, result);
-	mock().expectNCalls(2, "version_destroy");
+
+	mock().expectOneCall("version_destroy")
+			.withParameter("version", low);
+	mock().expectOneCall("version_destroy")
+			.withParameter("version", high);
 	versionRange_destroy(range);
 
 	free(version);
@@ -199,7 +219,11 @@ TEST(version_range, parse) {
 	high->minor = 8;
 	high->micro = 9;
 
-	mock().expectNCalls(3, "version_destroy");
+	mock().expectOneCall("version_destroy")
+			.withParameter("version", high);
+
+	mock().expectNCalls(2, "version_destroy")
+			.withParameter("version", low);
 
 	mock().expectOneCall("version_createVersionFromString")
 		   .withParameter("versionStr", "1.2.3")

http://git-wip-us.apache.org/repos/asf/celix/blob/1df04d81/framework/tst/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/framework/tst/CMakeLists.txt b/framework/tst/CMakeLists.txt
index 98cfb34..672fd99 100644
--- a/framework/tst/CMakeLists.txt
+++ b/framework/tst/CMakeLists.txt
@@ -38,5 +38,5 @@ configure_file(framework1.properties.in framework1.properties @ONLY)
 configure_file(framework2.properties.in framework2.properties @ONLY)
 
 add_test(NAME run_test_framework COMMAND test_framework)
-SETUP_TARGET_FOR_COVERAGE(test_framework_cov test_framework ${CMAKE_BINARY_DIR}/coverage/framework/framework)
+SETUP_TARGET_FOR_COVERAGE(test_framework_cov test_framework ${CMAKE_BINARY_DIR}/coverage/test_framework/test_framework)
 

http://git-wip-us.apache.org/repos/asf/celix/blob/1df04d81/utils/private/test/celix_threads_test.cpp
----------------------------------------------------------------------
diff --git a/utils/private/test/celix_threads_test.cpp b/utils/private/test/celix_threads_test.cpp
index 6d62bad..29e4475 100644
--- a/utils/private/test/celix_threads_test.cpp
+++ b/utils/private/test/celix_threads_test.cpp
@@ -287,7 +287,7 @@ static void * thread_test_func_exit(void *) {
 	int *pi = (int*) calloc(1, sizeof(int));
 	*pi = 666;
 
-	return pi;
+	celixThread_exit(pi);
 }
 
 static void * thread_test_func_detach(void *) {


[19/38] celix git commit: CELIX-272: Disable locking_example. Still needs some work

Posted by pn...@apache.org.
CELIX-272: Disable locking_example. Still needs some work


Project: http://git-wip-us.apache.org/repos/asf/celix/repo
Commit: http://git-wip-us.apache.org/repos/asf/celix/commit/53ff9da7
Tree: http://git-wip-us.apache.org/repos/asf/celix/tree/53ff9da7
Diff: http://git-wip-us.apache.org/repos/asf/celix/diff/53ff9da7

Branch: refs/heads/develop
Commit: 53ff9da7ede00f0ea51827a59f5d81981684a84a
Parents: a6213e4
Author: Pepijn Noltes <pe...@gmail.com>
Authored: Mon Nov 16 12:21:01 2015 +0100
Committer: Pepijn Noltes <pe...@gmail.com>
Committed: Mon Nov 16 12:21:01 2015 +0100

----------------------------------------------------------------------
 examples/CMakeLists.txt | 2 +-
 examples/deploy.cmake   | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/celix/blob/53ff9da7/examples/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt
index 55468a4..5751609 100644
--- a/examples/CMakeLists.txt
+++ b/examples/CMakeLists.txt
@@ -32,7 +32,7 @@ if (EXAMPLES)
     add_subdirectory(osgi-in-action/chapter04-correct-listener)
     add_subdirectory(osgi-in-action/chapter01-greeting-example)
     #add_subdirectory(osgi-in-action/chapter04-paint-example) chapter4 example is still based on APR
-    add_subdirectory(locking)
+    #add_subdirectory(locking) still under construction
     
     #add_subdirectory(embedding) embedding is still baed on APR
 endif(EXAMPLES)

http://git-wip-us.apache.org/repos/asf/celix/blob/53ff9da7/examples/deploy.cmake
----------------------------------------------------------------------
diff --git a/examples/deploy.cmake b/examples/deploy.cmake
index 234f90b..cd7debd 100644
--- a/examples/deploy.cmake
+++ b/examples/deploy.cmake
@@ -29,6 +29,6 @@ if (EXAMPLES)
 		deploy("mongoose" BUNDLES shell shell_tui log_service apache_celix_examples_mongoose)
 	endif ()
 
-    deploy("locking_example" BUNDLES benchmark_runner reference_benchmark start_stop_benchmark mutex_benchmark math_provider shell shell_tui log_service log_writer)
+    #deploy("locking_example" BUNDLES benchmark_runner reference_benchmark start_stop_benchmark mutex_benchmark math_provider shell shell_tui log_service log_writer)
 
 endif (EXAMPLES)


[20/38] celix git commit: CELIX-272: Refactor service registry from mutiple (nested) mutexes to single read/write lock

Posted by pn...@apache.org.
CELIX-272: Refactor service registry from mutiple (nested) mutexes to single read/write lock


Project: http://git-wip-us.apache.org/repos/asf/celix/repo
Commit: http://git-wip-us.apache.org/repos/asf/celix/commit/5e302091
Tree: http://git-wip-us.apache.org/repos/asf/celix/tree/5e302091
Diff: http://git-wip-us.apache.org/repos/asf/celix/diff/5e302091

Branch: refs/heads/develop
Commit: 5e3020914d634f49e9f826d231181e4e55bfdf7a
Parents: 53ff9da
Author: Pepijn Noltes <pe...@gmail.com>
Authored: Mon Nov 16 12:21:32 2015 +0100
Committer: Pepijn Noltes <pe...@gmail.com>
Committed: Mon Nov 16 12:21:32 2015 +0100

----------------------------------------------------------------------
 .../include/service_registration_private.h      |  16 +-
 .../private/include/service_registry_private.h  |  19 +-
 framework/private/src/service_reference.c       |  42 +--
 framework/private/src/service_registration.c    |  64 ++--
 framework/private/src/service_registry.c        | 375 +++++++++++--------
 5 files changed, 297 insertions(+), 219 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/celix/blob/5e302091/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 1b48887..2b1bf6c 100644
--- a/framework/private/include/service_registration_private.h
+++ b/framework/private/include/service_registration_private.h
@@ -30,13 +30,15 @@
 
 #include "service_registration.h"
 
-struct service {
-	char *name;
-	void *serviceStruct;
-};
+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 {
-	service_registry_pt registry;
+    registry_callback_t callback;
+
 	char * className;
 	bundle_pt bundle;
 	properties_pt properties;
@@ -56,8 +58,8 @@ struct serviceRegistration {
 	celix_thread_rwlock_t lock;
 };
 
-service_registration_pt serviceRegistration_create(service_registry_pt registry, bundle_pt bundle, char * serviceName, long serviceId, void * serviceObject, properties_pt dictionary);
-service_registration_pt serviceRegistration_createServiceFactory(service_registry_pt registry, bundle_pt bundle, char * serviceName, long serviceId, void * serviceObject, properties_pt dictionary);
+service_registration_pt serviceRegistration_create(registry_callback_t callback, bundle_pt bundle, char * serviceName, long serviceId, void * serviceObject, properties_pt dictionary);
+service_registration_pt serviceRegistration_createServiceFactory(registry_callback_t callback, bundle_pt bundle, char * serviceName, long serviceId, void * serviceObject, properties_pt dictionary);
 
 void serviceRegistration_retain(service_registration_pt registration);
 void serviceRegistration_release(service_registration_pt registration);

http://git-wip-us.apache.org/repos/asf/celix/blob/5e302091/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 c5a731c..f3edd17 100644
--- a/framework/private/include/service_registry_private.h
+++ b/framework/private/include/service_registry_private.h
@@ -32,20 +32,27 @@
 
 struct serviceRegistry {
 	framework_pt framework;
-	hash_map_pt serviceRegistrations;
+
+	hash_map_pt serviceRegistrations; //key = bundle (reg owner), value = registration
 	hash_map_pt serviceReferences; //key = bundle, value = map (key = registration, value = reference)
+
+	bool checkDeletedReferences; //If enabled. check if provided service references are still valid
+	hash_map_pt deletedServiceReferences; //key = ref pointer, value = bool
+
 	serviceChanged_function_pt serviceChanged;
 	long currentServiceId;
 
 	array_list_pt listenerHooks;
 
-	celix_thread_mutex_t mutex;
-	celix_thread_mutexattr_t mutexAttr;
-
-	celix_thread_mutex_t referencesMapMutex;
-
+	celix_thread_rwlock_t lock;
 };
 
+typedef enum reference_status_enum {
+	REF_ACTIVE,
+	REF_DELETED,
+	REF_UNKNOWN
+} reference_status_t;
+
 struct usageCount {
 	unsigned int count;
 	service_reference_pt reference;

http://git-wip-us.apache.org/repos/asf/celix/blob/5e302091/framework/private/src/service_reference.c
----------------------------------------------------------------------
diff --git a/framework/private/src/service_reference.c b/framework/private/src/service_reference.c
index 333339e..2f829c2 100644
--- a/framework/private/src/service_reference.c
+++ b/framework/private/src/service_reference.c
@@ -32,13 +32,8 @@
 
 #include "service_reference.h"
 
-#include "service_registry.h"
 #include "service_reference_private.h"
 #include "service_registration_private.h"
-#include "module.h"
-#include "wire.h"
-#include "bundle.h"
-#include "celix_log.h"
 
 static void serviceReference_destroy(service_reference_pt);
 static void serviceReference_logWarningUsageCountBelowZero(service_reference_pt ref);
@@ -58,6 +53,8 @@ celix_status_t serviceReference_create(bundle_pt referenceOwner, service_registr
 		celixThreadRwlock_create(&ref->lock, NULL);
 		ref->refCount = 1;
         ref->usageCount = 0;
+
+        serviceRegistration_retain(ref->registration);
 	}
 
 	if (status == CELIX_SUCCESS) {
@@ -77,28 +74,14 @@ celix_status_t serviceReference_retain(service_reference_pt ref) {
 }
 
 celix_status_t serviceReference_release(service_reference_pt ref, bool *out) {
-    celixThreadRwlock_writeLock(&ref->lock);
-    if (ref->refCount > 0) {
-        ref->refCount -= 1;
-    } else {
-        fw_log(logger, OSGI_FRAMEWORK_LOG_ERROR, "serviceReference_release error serv reference count already at 0\n");
-    }
-
-    if (out) {
-        *out = ref->refCount == 0;
-    }
-
-    celixThreadRwlock_unlock(&ref->lock);
-    return CELIX_SUCCESS;
-}
-
-/* TODO enable, for now use a leak version to prevent to much errors
-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);
+        }
         serviceReference_destroy(ref);
         destroyed = true;
     } else {
@@ -109,9 +92,10 @@ celix_status_t serviceReference_release(service_reference_pt ref, bool *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;
@@ -142,7 +126,7 @@ celix_status_t serviceReference_decreaseUsage(service_reference_pt ref, size_t *
     return status;
 }
 
-static void serviceReference_logWarningUsageCountBelowZero(service_reference_pt ref) {
+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");
 }
 
@@ -228,7 +212,7 @@ FRAMEWORK_EXPORT celix_status_t serviceReference_getPropertyKeys(service_referen
     hash_map_iterator_pt it;
     int i = 0;
     int vsize = hashMap_size(props);
-    *size = vsize;
+    *size = (unsigned int)vsize;
     *keys = malloc(vsize * sizeof(*keys));
     it = hashMapIterator_create(props);
     while (hashMapIterator_hasNext(it)) {
@@ -262,7 +246,7 @@ celix_status_t serviceReference_isValid(service_reference_pt ref, bool *result)
     return CELIX_SUCCESS;
 }
 
-bool serviceReference_isAssignableTo(service_reference_pt reference, bundle_pt requester, char * serviceName) {
+bool serviceReference_isAssignableTo(service_reference_pt reference __attribute__((unused)), bundle_pt requester __attribute__((unused)), 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.
@@ -292,7 +276,7 @@ celix_status_t serviceReference_compareTo(service_reference_pt reference, servic
 	long id, other_id;
 	char *id_str, *other_id_str;
 	serviceReference_getProperty(reference, (char *) OSGI_FRAMEWORK_SERVICE_ID, &id_str);
-	serviceReference_getProperty(reference, (char *) OSGI_FRAMEWORK_SERVICE_ID, &other_id_str);
+	serviceReference_getProperty(compareTo, (char *) OSGI_FRAMEWORK_SERVICE_ID, &other_id_str);
 
 	id = atol(id_str);
 	other_id = atol(other_id_str);
@@ -301,12 +285,12 @@ celix_status_t serviceReference_compareTo(service_reference_pt reference, servic
 	long rank, other_rank;
 	char *rank_str, *other_rank_str;
 	serviceReference_getProperty(reference, (char *) OSGI_FRAMEWORK_SERVICE_RANKING, &rank_str);
-	serviceReference_getProperty(reference, (char *) OSGI_FRAMEWORK_SERVICE_RANKING, &other_rank_str);
+	serviceReference_getProperty(compareTo, (char *) 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);
 
-	utils_compareServiceIdsAndRanking(id, rank, other_id, other_rank);
+    *compare = utils_compareServiceIdsAndRanking(id, rank, other_id, other_rank);
 
 	return status;
 }

http://git-wip-us.apache.org/repos/asf/celix/blob/5e302091/framework/private/src/service_registration.c
----------------------------------------------------------------------
diff --git a/framework/private/src/service_registration.c b/framework/private/src/service_registration.c
index f9c2ec2..dc8ae9b 100644
--- a/framework/private/src/service_registration.c
+++ b/framework/private/src/service_registration.c
@@ -30,38 +30,34 @@
 
 #include "service_registration_private.h"
 #include "constants.h"
-#include "service_factory.h"
-#include "service_reference.h"
-#include "celix_log.h"
-#include "celix_threads.h"
 
 static celix_status_t serviceRegistration_initializeProperties(service_registration_pt registration, properties_pt properties);
-static celix_status_t serviceRegistration_createInternal(service_registry_pt registry, bundle_pt bundle, char * serviceName, long serviceId,
+static celix_status_t serviceRegistration_createInternal(registry_callback_t callback, bundle_pt bundle, char * serviceName, long serviceId,
         void * serviceObject, properties_pt dictionary, bool isFactory, service_registration_pt *registration);
 static celix_status_t serviceRegistration_destroy(service_registration_pt registration);
 
-service_registration_pt serviceRegistration_create(service_registry_pt registry, bundle_pt bundle, char * serviceName, long serviceId, void * serviceObject, properties_pt dictionary) {
+service_registration_pt serviceRegistration_create(registry_callback_t callback, bundle_pt bundle, char * serviceName, long serviceId, void * serviceObject, properties_pt dictionary) {
     service_registration_pt registration = NULL;
-	serviceRegistration_createInternal(registry, bundle, serviceName, serviceId, serviceObject, dictionary, false, &registration);
+	serviceRegistration_createInternal(callback, bundle, serviceName, serviceId, serviceObject, dictionary, false, &registration);
 	return registration;
 }
 
-service_registration_pt serviceRegistration_createServiceFactory(service_registry_pt registry, bundle_pt bundle, char * serviceName, long serviceId, void * serviceObject, properties_pt dictionary) {
+service_registration_pt serviceRegistration_createServiceFactory(registry_callback_t callback, bundle_pt bundle, char * serviceName, long serviceId, void * serviceObject, properties_pt dictionary) {
     service_registration_pt registration = NULL;
-    serviceRegistration_createInternal(registry, bundle, serviceName, serviceId, serviceObject, dictionary, true, &registration);
+    serviceRegistration_createInternal(callback, bundle, serviceName, serviceId, serviceObject, dictionary, true, &registration);
     return registration;
 }
 
-static celix_status_t serviceRegistration_createInternal(service_registry_pt registry, bundle_pt bundle, char * serviceName, long serviceId,
+static celix_status_t serviceRegistration_createInternal(registry_callback_t callback, bundle_pt bundle, char * serviceName, long serviceId,
         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->registry = registry;
 		reg->className = strdup(serviceName);
 		reg->bundle = bundle;
 		reg->refCount = 1;
@@ -107,9 +103,11 @@ 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);
     free(registration->className);
 	registration->className = NULL;
-	registration->registry = NULL;
+
+    registration->callback.unregister = NULL;
 
 	properties_destroy(registration->properties);
     celixThreadRwlock_destroy(&registration->lock);
@@ -142,18 +140,22 @@ static celix_status_t serviceRegistration_initializeProperties(service_registrat
     return CELIX_SUCCESS;
 }
 
-bool serviceRegistration_isValid(service_registration_pt registration) {
-    bool result;
-    celixThreadRwlock_readLock(&registration->lock);
-    result = registration == NULL ? false : registration->svcObj != NULL;
+void serviceRegistration_invalidate(service_registration_pt registration) {
+    celixThreadRwlock_writeLock(&registration->lock);
+    registration->svcObj = NULL;
     celixThreadRwlock_unlock(&registration->lock);
-    return result;
 }
 
-void serviceRegistration_invalidate(service_registration_pt registration) {
-    celixThreadRwlock_writeLock(&registration->lock);
-	registration->svcObj = NULL;
+bool serviceRegistration_isValid(service_registration_pt registration) {
+    bool isValid;
+    celixThreadRwlock_readLock(&registration->lock);
+    if (registration != NULL) {
+        isValid = registration->svcObj != NULL;
+    } else {
+        isValid = false;
+    }
     celixThreadRwlock_unlock(&registration->lock);
+    return isValid;
 }
 
 celix_status_t serviceRegistration_unregister(service_registration_pt registration) {
@@ -164,6 +166,9 @@ celix_status_t serviceRegistration_unregister(service_registration_pt registrati
     notValidOrUnregistering = !serviceRegistration_isValid(registration) || registration->isUnregistering;
     celixThreadRwlock_unlock(&registration->lock);
 
+    registry_callback_t callback;
+    callback.unregister = NULL;
+    bundle_pt bundle = NULL;
 
     if (notValidOrUnregistering) {
 		printf("Service is already unregistered\n");
@@ -171,11 +176,13 @@ celix_status_t serviceRegistration_unregister(service_registration_pt registrati
 	} else {
         celixThreadRwlock_writeLock(&registration->lock);
         registration->isUnregistering = true;
+        bundle = registration->bundle;
+        callback = registration->callback;
         celixThreadRwlock_unlock(&registration->lock);
     }
 
-	if (status == CELIX_SUCCESS) {
-		serviceRegistry_unregisterService(registration->registry, registration->bundle, registration);
+	if (status == CELIX_SUCCESS && callback.unregister != NULL) {
+        callback.unregister(callback.handle, bundle, registration);
 	}
 
 	framework_logIfError(logger, status, NULL, "Cannot unregister service registration");
@@ -224,14 +231,21 @@ celix_status_t serviceRegistration_getProperties(service_registration_pt registr
 }
 
 celix_status_t serviceRegistration_setProperties(service_registration_pt registration, properties_pt properties) {
+    celix_status_t status = CELIX_SUCCESS;
 
+    properties_pt oldProperties = NULL;
+    registry_callback_t callback;
+    callback.modified = NULL;
 
     celixThreadRwlock_writeLock(&registration->lock);
-    properties_pt oldProps = registration->properties;
-    serviceRegistration_initializeProperties(registration, properties);
+    oldProperties = registration->properties;
+    status = serviceRegistration_initializeProperties(registration, properties);
+    callback = registration->callback;
     celixThreadRwlock_unlock(&registration->lock);
 
-	serviceRegistry_servicePropertiesModified(registration->registry, registration, oldProps);
+    if (status == CELIX_SUCCESS && callback.modified != NULL) {
+        callback.modified(callback.handle, registration, oldProperties);
+    }
 
 	return CELIX_SUCCESS;
 }

http://git-wip-us.apache.org/repos/asf/celix/blob/5e302091/framework/private/src/service_registry.c
----------------------------------------------------------------------
diff --git a/framework/private/src/service_registry.c b/framework/private/src/service_registry.c
index 6abd0cc..13fe01a 100644
--- a/framework/private/src/service_registry.c
+++ b/framework/private/src/service_registry.c
@@ -29,55 +29,55 @@
 
 #include "service_registry_private.h"
 #include "service_registration_private.h"
-#include "module.h"
-#include "bundle.h"
 #include "listener_hook_service.h"
 #include "constants.h"
 #include "service_reference_private.h"
 #include "framework_private.h"
-#include "celix_log.h"
 
 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);
+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);
 
+celix_status_t serviceRegistry_create(framework_pt framework, serviceChanged_function_pt serviceChanged, service_registry_pt *out) {
+	celix_status_t status;
 
-celix_status_t serviceRegistry_create(framework_pt framework, serviceChanged_function_pt serviceChanged, service_registry_pt *registry) {
-	celix_status_t status = CELIX_SUCCESS;
-
-	*registry = malloc(sizeof(**registry));
-	if (!*registry) {
+	service_registry_pt reg = calloc(1, sizeof(*reg));
+	if (reg == NULL) {
 		status = CELIX_ENOMEM;
 	} else {
+		reg->serviceChanged = serviceChanged;
+		reg->serviceRegistrations = hashMap_create(NULL, NULL, NULL, NULL);
+		reg->framework = framework;
+		reg->currentServiceId = 1l;
+		reg->serviceReferences = hashMap_create(NULL, NULL, NULL, NULL);
+        reg->deletedServiceReferences = hashMap_create(NULL, NULL, NULL, NULL);
 
-		(*registry)->serviceChanged = serviceChanged;
-		(*registry)->serviceRegistrations = hashMap_create(NULL, NULL, NULL, NULL);
-		(*registry)->framework = framework;
-		(*registry)->currentServiceId = 1l;
-		(*registry)->serviceReferences = hashMap_create(NULL, NULL, NULL, NULL);;
-
-		arrayList_create(&(*registry)->listenerHooks);
+		arrayList_create(&reg->listenerHooks);
 
-		status = celixThreadMutexAttr_create(&(*registry)->mutexAttr);
-		status = CELIX_DO_IF(status, celixThreadMutexAttr_settype(&(*registry)->mutexAttr, CELIX_THREAD_MUTEX_RECURSIVE));
-		status = CELIX_DO_IF(status, celixThreadMutex_create(&(*registry)->mutex, &(*registry)->mutexAttr));
-		status = CELIX_DO_IF(status, celixThreadMutex_create(&(*registry)->referencesMapMutex, NULL));
+		status = celixThreadRwlock_create(&reg->lock, NULL);
 	}
 
-	framework_logIfError(logger, status, NULL, "Cannot create service registry");
+	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(&registry->lock);
     hashMap_destroy(registry->serviceRegistrations, false, false);
     hashMap_destroy(registry->serviceReferences, false, false);
     arrayList_destroy(registry->listenerHooks);
-    celixThreadMutex_destroy(&registry->mutex);
-    celixThreadMutexAttr_destroy(&registry->mutexAttr);
-    celixThreadMutex_destroy(&registry->referencesMapMutex);
+
     registry->framework = NULL;
     registry->listenerHooks = NULL;
     registry->serviceChanged = NULL;
@@ -91,7 +91,8 @@ 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;
 
-	celixThreadMutex_lock(&registry->mutex);
+	celixThreadRwlock_readLock(&registry->lock);
+
 	array_list_pt regs = (array_list_pt) hashMap_get(registry->serviceRegistrations, bundle);
 	if (regs != NULL) {
 		unsigned int i;
@@ -108,7 +109,8 @@ celix_status_t serviceRegistry_getRegisteredServices(service_registry_pt registr
 			}
 		}
 	}
-	celixThreadMutex_unlock(&registry->mutex);
+
+	celixThreadRwlock_unlock(&registry->lock);
 
 	framework_logIfError(logger, status, NULL, "Cannot get registered services");
 
@@ -125,16 +127,21 @@ 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;
-	celixThreadMutex_lock(&registry->mutex);
+
+    registry_callback_t callback;
+    callback.handle = registry;
+    callback.unregister = (void *) serviceRegistry_unregisterService;
+    callback.modified = (void *) serviceRegistry_servicePropertiesModified;
 
 	if (isFactory) {
-	    *registration = serviceRegistration_createServiceFactory(registry, bundle, serviceName, ++registry->currentServiceId, serviceObject, dictionary);
+	    *registration = serviceRegistration_createServiceFactory(callback, bundle, serviceName, ++registry->currentServiceId, serviceObject, dictionary);
 	} else {
-	    *registration = serviceRegistration_create(registry, bundle, serviceName, ++registry->currentServiceId, serviceObject, dictionary);
+	    *registration = serviceRegistration_create(callback, bundle, serviceName, ++registry->currentServiceId, serviceObject, dictionary);
 	}
 
 	serviceRegistry_addHooks(registry, serviceName, serviceObject, *registration);
 
+	celixThreadRwlock_writeLock(&registry->lock);
 	regs = (array_list_pt) hashMap_get(registry->serviceRegistrations, bundle);
 	if (regs == NULL) {
 		regs = NULL;
@@ -143,15 +150,10 @@ celix_status_t serviceRegistry_registerServiceInternal(service_registry_pt regis
 	arrayList_add(regs, *registration);
 	hashMap_put(registry->serviceRegistrations, bundle, regs);
 
-	celixThreadMutex_unlock(&registry->mutex);
+	celixThreadRwlock_unlock(&registry->lock);
 
 	if (registry->serviceChanged != NULL) {
-//		service_event_pt event = (service_event_pt) malloc(sizeof(*event));
-//		event->type = REGISTERED;
-//		event->reference = (*registration)->reference;
 		registry->serviceChanged(registry->framework, OSGI_FRAMEWORK_SERVICE_EVENT_REGISTERED, *registration, NULL);
-//		free(event);
-//		event = NULL;
 	}
 
 	return CELIX_SUCCESS;
@@ -161,23 +163,22 @@ celix_status_t serviceRegistry_unregisterService(service_registry_pt registry, b
 	// array_list_t clients;
 	array_list_pt regs;
 
-	celixThreadMutex_lock(&registry->mutex);
 
 	serviceRegistry_removeHook(registry, registration);
 
+	celixThreadRwlock_writeLock(&registry->lock);
 	regs = (array_list_pt) hashMap_get(registry->serviceRegistrations, bundle);
 	if (regs != NULL) {
 		arrayList_removeElement(regs, registration);
 	}
-
-	celixThreadMutex_unlock(&registry->mutex);
+	celixThreadRwlock_unlock(&registry->lock);
 
 	if (registry->serviceChanged != NULL) {
 		registry->serviceChanged(registry->framework, OSGI_FRAMEWORK_SERVICE_EVENT_UNREGISTERING, registration, NULL);
 	}
 
-	celixThreadMutex_lock(&registry->mutex);
 
+	celixThreadRwlock_readLock(&registry->lock);
     //invalidate service references
     hash_map_iterator_pt iter = hashMapIterator_create(registry->serviceReferences);
     while (hashMapIterator_hasNext(iter)) {
@@ -188,12 +189,11 @@ celix_status_t serviceRegistry_unregisterService(service_registry_pt registry, b
         }
     }
     hashMapIterator_destroy(iter);
+	celixThreadRwlock_unlock(&registry->lock);
 
-    serviceRegistration_invalidate(registration);
+	serviceRegistration_invalidate(registration);
     serviceRegistration_release(registration);
 
-	celixThreadMutex_unlock(&registry->mutex);
-
 	return CELIX_SUCCESS;
 }
 
@@ -201,9 +201,10 @@ celix_status_t serviceRegistry_clearServiceRegistrations(service_registry_pt reg
     celix_status_t status = CELIX_SUCCESS;
     array_list_pt registrations = NULL;
 
-    celixThreadMutex_lock(&registry->mutex);
+	celixThreadRwlock_writeLock(&registry->lock);
+	registrations = hashMap_remove(registry->serviceRegistrations, bundle);
+	celixThreadRwlock_unlock(&registry->lock);
 
-    registrations = hashMap_get(registry->serviceRegistrations, bundle);
     while (registrations != NULL && arrayList_size(registrations) > 0) {
         service_registration_pt reg = arrayList_get(registrations, 0);
 
@@ -212,17 +213,12 @@ celix_status_t serviceRegistry_clearServiceRegistrations(service_registry_pt reg
         if (serviceRegistration_isValid(reg)) {
             serviceRegistration_unregister(reg);
         }
-        serviceRegistration_release(reg);
     }
-    hashMap_remove(registry->serviceRegistrations, bundle);
-
-    celixThreadMutex_unlock(&registry->mutex);
-
 
     return status;
 }
 
-static void serviceRegistry_logWarningServiceRegistration(service_registry_pt registry, service_registration_pt reg) {
+static void serviceRegistry_logWarningServiceRegistration(service_registry_pt registry __attribute__((unused)), 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);
@@ -236,59 +232,60 @@ celix_status_t serviceRegistry_getServiceReference(service_registry_pt registry,
     service_reference_pt ref = NULL;
     hash_map_pt references = NULL;
 
-    // Lock
-	celixThreadMutex_lock(&registry->referencesMapMutex);
 
-	references = hashMap_get(registry->serviceReferences, owner);
-	if (references == NULL) {
+    //LOCK
+    celixThreadRwlock_writeLock(&registry->lock);
+
+    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");
-        }
-    }
+        hashMap_put(registry->serviceReferences, owner, references);
+	}
 
+    ref = hashMap_get(references, registration);
 
-    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);
+    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);
+            hashMap_put(registry->deletedServiceReferences, ref, (void *)false);
         }
+    } else {
+        serviceReference_retain(ref);
     }
 
+    //UNLOCK
+    celixThreadRwlock_unlock(&registry->lock);
+
+
     if (status == CELIX_SUCCESS) {
         *out = ref;
     }
 
-    // Unlock
-	celixThreadMutex_unlock(&registry->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) {
-	celix_status_t status = CELIX_SUCCESS;
-	hash_map_values_pt registrations;
+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;
-	arrayList_create(references);
-
-	celixThreadMutex_lock(&registry->mutex);
-	registrations = hashMapValues_create(registry->serviceRegistrations);
-	iterator = hashMapValues_iterator(registrations);
-	while (hashMapIterator_hasNext(iterator)) {
+    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));
+
+    celixThreadRwlock_readLock(&registry->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++) {
@@ -298,7 +295,7 @@ celix_status_t serviceRegistry_getServiceReferences(service_registry_pt registry
 			status = serviceRegistration_getProperties(registration, &props);
 			if (status == CELIX_SUCCESS) {
 				bool matched = false;
-				bool matchResult = false;
+				matchResult = false;
 				if (filter != NULL) {
 					filter_match(filter, props, &matchResult);
 				}
@@ -306,7 +303,7 @@ celix_status_t serviceRegistry_getServiceReferences(service_registry_pt registry
 					matched = true;
 				} else if (serviceName != NULL) {
 					char *className = NULL;
-					bool matchResult = false;
+					matchResult = false;
 					serviceRegistration_getServiceName(registration, &className);
 					if (filter != NULL) {
 						filter_match(filter, props, &matchResult);
@@ -317,45 +314,97 @@ celix_status_t serviceRegistry_getServiceReferences(service_registry_pt registry
 				}
 				if (matched) {
 					if (serviceRegistration_isValid(registration)) {
-						service_reference_pt reference = NULL;
-                        serviceRegistry_getServiceReference(registry, owner, registration, &reference);
-						arrayList_add(*references, reference);
+                        arrayList_add(matchingRegistrations, registration);
 					}
 				}
 			}
 		}
 	}
+    celixThreadRwlock_unlock(&registry->lock);
 	hashMapIterator_destroy(iterator);
-	hashMapValues_destroy(registrations);
-	celixThreadMutex_unlock(&registry->mutex);
 
-	framework_logIfError(logger, status, NULL, "Cannot get service references");
+    if (status == CELIX_SUCCESS) {
+        size = arrayList_size(matchingRegistrations);
+        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) {
+                arrayList_add(references, reference);
+            } else {
+                break;
+            }
+        }
+        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_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;
+    reference_status_t refStatus;
 
-    celixThreadMutex_lock(&registry->mutex);
-    serviceReference_getUsageCount(reference, &count);
-    serviceReference_getServiceRegistration(reference, &reg);
-    serviceReference_release(reference, &destroyed);
-    if (destroyed) {
-        if (count > 0) {
-            serviceRegistry_logWarningServiceReferenceUsageCount(registry, 0, count);
+    serviceRegistry_checkReference(registry, reference, &refStatus);
+    if (refStatus == REF_ACTIVE) {
+        serviceReference_getUsageCount(reference, &count);
+        serviceReference_getServiceRegistration(reference, &reg);
+        serviceReference_release(reference, &destroyed);
+        if (destroyed) {
+            if (count > 0) {
+                serviceRegistry_logWarningServiceReferenceUsageCount(registry, 0, count);
+            }
+
+
+            celixThreadRwlock_writeLock(&registry->lock);
+            hash_map_pt refsMap = hashMap_get(registry->serviceReferences, bundle);
+            hashMap_remove(refsMap, reg);
+            hashMap_put(registry->deletedServiceReferences, reference, (void *)true);
+            celixThreadRwlock_unlock(&registry->lock);
         }
-        hash_map_pt refsMap = hashMap_get(registry->serviceReferences, bundle);
-        hashMap_remove(refsMap, reg);
+    } else {
+        serviceRegistry_logIllegalReference(registry, reference, refStatus);
     }
-    celixThreadMutex_unlock(&registry->mutex);
+
     return status;
 }
 
-void serviceRegistry_logWarningServiceReferenceUsageCount(service_registry_pt registry, size_t usageCount, size_t refCount) {
+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 has ref status %i", reference, refStatus);
+}
+
+celix_status_t serviceRegistry_checkReference(service_registry_pt registry, service_reference_pt ref,
+                                              reference_status_t *out) {
+    celix_status_t status = CELIX_SUCCESS;
+    reference_status_t refStatus = REF_UNKNOWN;
+
+    celixThreadRwlock_readLock(&registry->lock);
+    if (hashMap_containsKey(registry->deletedServiceReferences, ref)) {
+        bool deleted = (bool) hashMap_get(registry->deletedServiceReferences, ref);
+        refStatus = deleted ? REF_DELETED : REF_ACTIVE;
+    }
+    celixThreadRwlock_unlock(&registry->lock);
+
+    *out = refStatus;
+
+    return status;
+}
+
+void serviceRegistry_logWarningServiceReferenceUsageCount(service_registry_pt registry __attribute__((unused)), 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);
     }
@@ -368,10 +417,9 @@ void serviceRegistry_logWarningServiceReferenceUsageCount(service_registry_pt re
 celix_status_t serviceRegistry_clearReferencesFor(service_registry_pt registry, bundle_pt bundle) {
     celix_status_t status = CELIX_SUCCESS;
 
-    celixThreadMutex_lock(&registry->mutex);
-    hash_map_pt refsMap = hashMap_remove(registry->serviceReferences, bundle);
-    celixThreadMutex_unlock(&registry->mutex);
+    celixThreadRwlock_writeLock(&registry->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)) {
@@ -392,11 +440,14 @@ celix_status_t serviceRegistry_clearReferencesFor(service_registry_pt registry,
             while (!destroyed) {
                 serviceReference_release(ref, &destroyed);
             }
+            hashMap_put(registry->deletedServiceReferences, ref, (void *)true);
 
         }
         hashMapIterator_destroy(iter);
     }
 
+    celixThreadRwlock_unlock(&registry->lock);
+
     return status;
 }
 
@@ -407,7 +458,7 @@ celix_status_t serviceRegistry_getServicesInUse(service_registry_pt registry, bu
     arrayList_create(&result);
 
     //LOCK
-    celixThreadMutex_lock(&registry->mutex);
+    celixThreadRwlock_readLock(&registry->lock);
 
     hash_map_pt refsMap = hashMap_get(registry->serviceReferences, bundle);
 
@@ -419,7 +470,7 @@ celix_status_t serviceRegistry_getServicesInUse(service_registry_pt registry, bu
     hashMapIterator_destroy(iter);
 
     //UNLOCK
-	celixThreadMutex_unlock(&registry->mutex);
+    celixThreadRwlock_unlock(&registry->lock);
 
     *out = result;
 
@@ -431,26 +482,31 @@ celix_status_t serviceRegistry_getService(service_registry_pt registry, bundle_p
 	service_registration_pt registration = NULL;
     size_t count = 0;
     void *service = NULL;
+    reference_status_t refStatus;
 
-	serviceReference_getServiceRegistration(reference, &registration);
-	celixThreadMutex_lock(&registry->mutex);
+    serviceRegistry_checkReference(registry, reference, &refStatus);
 
+    if (refStatus == REF_ACTIVE) {
+        celixThreadRwlock_readLock(&registry->lock);
+        serviceReference_getServiceRegistration(reference, &registration);
 
-	if (serviceRegistration_isValid(registration)) {
-        serviceReference_increaseUsage(reference, &count);
-        if (count == 1) {
-            serviceRegistration_getService(registration, bundle, &service);
-            serviceReference_setService(reference, service);
-        }
+        if (serviceRegistration_isValid(registration)) {
+            serviceReference_increaseUsage(reference, &count);
+            if (count == 1) {
+                serviceRegistration_getService(registration, bundle, &service);
+                serviceReference_setService(reference, service);
+            }
 
-        serviceReference_getService(reference, out);
-	} else {
-        *out = NULL; //invalid service registration
+            serviceReference_getService(reference, out);
+        } else {
+            *out = NULL; //invalid service registration
+        }
+        celixThreadRwlock_unlock(&registry->lock);
+    } else {
+        serviceRegistry_logIllegalReference(registry, reference, refStatus);
+        status = CELIX_BUNDLE_EXCEPTION;
     }
 
-	celixThreadMutex_unlock(&registry->mutex);
-
-
 	return status;
 }
 
@@ -459,29 +515,38 @@ celix_status_t serviceRegistry_ungetService(service_registry_pt registry, bundle
     service_registration_pt reg = NULL;
     void *service = NULL;
     size_t count = 0;
+    celix_status_t subStatus = CELIX_SUCCESS;
+    reference_status_t refStatus;
 
-    celix_status_t subStatus = serviceReference_decreaseUsage(reference, &count);
+    serviceRegistry_checkReference(registry, reference, &refStatus);
 
-    if (count == 0) {
-        serviceReference_getService(reference, &service);
-        serviceReference_getServiceRegistration(reference, &reg);
-        serviceRegistration_ungetService(reg, bundle, &service);
+    if (refStatus == REF_ACTIVE) {
+        subStatus = serviceReference_decreaseUsage(reference, &count);
+        if (count == 0) {
+            serviceReference_getService(reference, &service);
+            serviceReference_getServiceRegistration(reference, &reg);
+            serviceRegistration_ungetService(reg, bundle, &service);
+        }
+    } else {
+        serviceRegistry_logIllegalReference(registry, reference, refStatus);
+        status = CELIX_BUNDLE_EXCEPTION;
     }
 
     if (result) {
         *result = (subStatus == CELIX_SUCCESS);
     }
 
+
 	return status;
 }
 
-celix_status_t serviceRegistry_addHooks(service_registry_pt registry, char *serviceName, void *serviceObject, service_registration_pt registration) {
+celix_status_t serviceRegistry_addHooks(service_registry_pt registry, char *serviceName, void *serviceObject __attribute__((unused)), service_registration_pt registration) {
 	celix_status_t status = CELIX_SUCCESS;
 
 	if (strcmp(OSGI_FRAMEWORK_LISTENER_HOOK_SERVICE_NAME, serviceName) == 0) {
-	    celixThreadMutex_lock(&registry->mutex);
+        celixThreadRwlock_writeLock(&registry->lock);
 		arrayList_add(registry->listenerHooks, registration);
-		celixThreadMutex_unlock(&registry->mutex);
+        celixThreadRwlock_unlock(&registry->lock);
 	}
 
 	return status;
@@ -495,35 +560,42 @@ celix_status_t serviceRegistry_removeHook(service_registry_pt registry, service_
 	serviceRegistration_getProperties(registration, &props);
 	serviceName = properties_get(props, (char *) OSGI_FRAMEWORK_OBJECTCLASS);
 	if (strcmp(OSGI_FRAMEWORK_LISTENER_HOOK_SERVICE_NAME, serviceName) == 0) {
-	    celixThreadMutex_lock(&registry->mutex);
+        celixThreadRwlock_writeLock(&registry->lock);
 		arrayList_removeElement(registry->listenerHooks, registration);
-		celixThreadMutex_unlock(&registry->mutex);
+        celixThreadRwlock_unlock(&registry->lock);
 	}
 
 	return status;
 }
 
-celix_status_t serviceRegistry_getListenerHooks(service_registry_pt registry, bundle_pt owner, array_list_pt *hooks) {
-	celix_status_t status = CELIX_SUCCESS;
+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;
 
-	if (registry == NULL || *hooks != NULL) {
-		status = CELIX_ILLEGAL_ARGUMENT;
-	} else {
-		status = arrayList_create(hooks);
-		if (status == CELIX_SUCCESS) {
-			unsigned int i;
-			celixThreadMutex_lock(&registry->mutex);
-			for (i = 0; i < arrayList_size(registry->listenerHooks); i++) {
-				service_registration_pt registration = arrayList_get(registry->listenerHooks, i);
-				service_reference_pt reference = NULL;
-                serviceRegistry_getServiceReference(registry, owner, registration, &reference);
-				arrayList_add(*hooks, reference);
-			}
-			celixThreadMutex_unlock(&registry->mutex);
-		}
-	}
+    status = arrayList_create(&result);
+    if (status == CELIX_SUCCESS) {
+        for (i = 0; i < arrayList_size(registry->listenerHooks); i += 1) {
+            celixThreadRwlock_readLock(&registry->lock);
+            service_registration_pt registration = arrayList_get(registry->listenerHooks, i);
+            serviceRegistration_retain(registration);
+            celixThreadRwlock_unlock(&registry->lock);
+
+            service_reference_pt reference = NULL;
+            serviceRegistry_getServiceReference(registry, owner, registration, &reference);
+            arrayList_add(result, reference);
+            serviceRegistration_release(registration);
+        }
+    }
 
-	framework_logIfError(logger, status, NULL, "Cannot get listener hooks");
+    if (status == CELIX_SUCCESS) {
+        *out = result;
+    } else {
+        if (result != NULL) {
+            arrayList_destroy(result);
+        }
+        framework_logIfError(logger, status, NULL, "Cannot get listener hooks");
+    }
 
 	return status;
 }
@@ -532,6 +604,5 @@ celix_status_t serviceRegistry_servicePropertiesModified(service_registry_pt reg
 	if (registry->serviceChanged != NULL) {
 		registry->serviceChanged(registry->framework, OSGI_FRAMEWORK_SERVICE_EVENT_MODIFIED, registration, oldprops);
 	}
-
 	return CELIX_SUCCESS;
 }


[02/38] celix git commit: CELIX-272: Added locking/threading example to test synchronization solutions and isues. Introduced release/retain concept for service reference and service registration.

Posted by pn...@apache.org.
CELIX-272: Added locking/threading example to test synchronization solutions and isues. Introduced release/retain concept for service reference and service registration.


Project: http://git-wip-us.apache.org/repos/asf/celix/repo
Commit: http://git-wip-us.apache.org/repos/asf/celix/commit/e0231e51
Tree: http://git-wip-us.apache.org/repos/asf/celix/tree/e0231e51
Diff: http://git-wip-us.apache.org/repos/asf/celix/diff/e0231e51

Branch: refs/heads/develop
Commit: e0231e51e4cac30018c7a71f9469e838348f642b
Parents: e9f2baa
Author: Pepijn Noltes <pe...@gmail.com>
Authored: Mon Nov 9 18:06:18 2015 +0100
Committer: Pepijn Noltes <pe...@gmail.com>
Committed: Mon Nov 9 18:06:18 2015 +0100

----------------------------------------------------------------------
 .../private/src/dm_component_impl.c             |   5 +-
 examples/CMakeLists.txt                         |   1 +
 examples/deploy.cmake                           |   3 +
 examples/locking/CMakeLists.txt                 |  24 ++
 examples/locking/benchmark/CMakeLists.txt       |  30 ++
 .../private/src/benchmark_runner_activator.c    | 255 +++++++++++++
 .../benchmark/public/include/benchmark.h        |  29 ++
 .../benchmark/public/include/benchmark_result.h |  20 +
 .../public/include/benchmark_service.h          |  27 ++
 .../public/include/frequency_service.h          |  47 +++
 .../benchmark/public/include/math_service.h     |  40 ++
 .../benchmark/public/src/benchmark_activator.c  | 133 +++++++
 examples/locking/consumer.c                     | 372 +++++++++++++++++++
 examples/locking/math_provider/CMakeLists.txt   |  32 ++
 .../private/include/math_component.h            |  14 +
 .../math_provider/private/src/math_component.c  |  28 ++
 .../private/src/provider_activator.c            | 219 +++++++++++
 .../modified_bool_benchmark/CMakeLists.txt      |  32 ++
 .../private/src/modified_bool_benchmark.c       | 162 ++++++++
 examples/locking/mutex_benchmark/CMakeLists.txt |  32 ++
 .../private/src/mutex_benchmark.c               | 117 ++++++
 .../locking/reference_benchmark/CMakeLists.txt  |  32 ++
 .../private/src/reference_benchmark.c           | 116 ++++++
 .../locking/start_stop_benchmark/CMakeLists.txt |  32 ++
 .../private/src/start_stop_benchmark.c          | 189 ++++++++++
 .../private/include/service_reference_private.h |   9 +-
 .../include/service_registration_private.h      |   6 +-
 .../private/include/service_registry_private.h  |   1 +
 framework/private/src/properties.c              |  22 ++
 framework/private/src/service_reference.c       |  71 ++--
 framework/private/src/service_registration.c    |  71 ++--
 framework/private/src/service_registry.c        |  26 +-
 framework/public/include/properties.h           |   3 +
 33 files changed, 2130 insertions(+), 70 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/celix/blob/e0231e51/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 d08bc28..aa34389 100644
--- a/dependency_manager/private/src/dm_component_impl.c
+++ b/dependency_manager/private/src/dm_component_impl.c
@@ -1097,8 +1097,9 @@ celix_status_t component_registerServices(dm_component_pt component) {
 
 	for (i = 0; i < arrayList_size(component->dm_interfaces); i++) {
 	    dm_interface_t *interface = arrayList_get(component->dm_interfaces, i);
-
-            bundleContext_registerService(component->context, interface->serviceName, interface->service, interface->properties, &interface->registration);
+            properties_pt regProps = NULL;
+            properties_copy(interface->properties, &regProps);
+            bundleContext_registerService(component->context, interface->serviceName, interface->service, regProps, &interface->registration);
 	}
     }
 

http://git-wip-us.apache.org/repos/asf/celix/blob/e0231e51/examples/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt
index 677a6aa..55468a4 100644
--- a/examples/CMakeLists.txt
+++ b/examples/CMakeLists.txt
@@ -32,6 +32,7 @@ if (EXAMPLES)
     add_subdirectory(osgi-in-action/chapter04-correct-listener)
     add_subdirectory(osgi-in-action/chapter01-greeting-example)
     #add_subdirectory(osgi-in-action/chapter04-paint-example) chapter4 example is still based on APR
+    add_subdirectory(locking)
     
     #add_subdirectory(embedding) embedding is still baed on APR
 endif(EXAMPLES)

http://git-wip-us.apache.org/repos/asf/celix/blob/e0231e51/examples/deploy.cmake
----------------------------------------------------------------------
diff --git a/examples/deploy.cmake b/examples/deploy.cmake
index 24c7a11..234f90b 100644
--- a/examples/deploy.cmake
+++ b/examples/deploy.cmake
@@ -28,4 +28,7 @@ if (EXAMPLES)
 	if (NOT ANDROID)
 		deploy("mongoose" BUNDLES shell shell_tui log_service apache_celix_examples_mongoose)
 	endif ()
+
+    deploy("locking_example" BUNDLES benchmark_runner reference_benchmark start_stop_benchmark mutex_benchmark math_provider shell shell_tui log_service log_writer)
+
 endif (EXAMPLES)

http://git-wip-us.apache.org/repos/asf/celix/blob/e0231e51/examples/locking/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/examples/locking/CMakeLists.txt b/examples/locking/CMakeLists.txt
new file mode 100644
index 0000000..e6c80ab
--- /dev/null
+++ b/examples/locking/CMakeLists.txt
@@ -0,0 +1,24 @@
+	# 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.
+
+add_subdirectory(benchmark)
+add_subdirectory(math_provider)
+
+add_subdirectory(mutex_benchmark)
+add_subdirectory(reference_benchmark)
+add_subdirectory(start_stop_benchmark)
+add_subdirectory(modified_bool_benchmark)

http://git-wip-us.apache.org/repos/asf/celix/blob/e0231e51/examples/locking/benchmark/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/examples/locking/benchmark/CMakeLists.txt b/examples/locking/benchmark/CMakeLists.txt
new file mode 100644
index 0000000..ce5db7c
--- /dev/null
+++ b/examples/locking/benchmark/CMakeLists.txt
@@ -0,0 +1,30 @@
+# 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.
+
+SET(BUNDLE_SYMBOLICNAME benchmark_runner)
+SET(BUNDLE_VERSION 0.0.0)
+
+bundle(benchmark_runner SOURCES
+	private/src/benchmark_runner_activator 
+)
+
+include_directories(private/include)
+include_directories(public/include)
+include_directories(${PROJECT_SOURCE_DIR}/framework/public/include)
+include_directories(${PROJECT_SOURCE_DIR}/utils/public/include)
+
+target_link_libraries(benchmark_runner celix_framework)

http://git-wip-us.apache.org/repos/asf/celix/blob/e0231e51/examples/locking/benchmark/private/src/benchmark_runner_activator.c
----------------------------------------------------------------------
diff --git a/examples/locking/benchmark/private/src/benchmark_runner_activator.c b/examples/locking/benchmark/private/src/benchmark_runner_activator.c
new file mode 100644
index 0000000..e06b77b
--- /dev/null
+++ b/examples/locking/benchmark/private/src/benchmark_runner_activator.c
@@ -0,0 +1,255 @@
+/**
+ *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.
+ */
+/*
+ * benchmark_activator.c
+ *
+ *  \date       Feb 12, 2014
+ *  \author    	<a href="mailto:celix-dev@incubator.apache.org">Apache Celix Project Team</a>
+ *  \copyright	Apache License, Version 2.0
+ */
+
+
+
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/time.h>
+#include <sys/queue.h>
+
+#include <pthread.h>
+
+#include "bundle_activator.h"
+#include "bundle_context.h"
+#include "service_registration.h"
+#include "service_tracker.h"
+
+#include "benchmark_service.h"
+#include "frequency_service.h"
+
+static celix_status_t benchmarkRunner_addingService(void * handle, service_reference_pt reference, void **service);
+static celix_status_t benchmarkRunner_addedService(void * handle, service_reference_pt reference, void * service);
+static celix_status_t benchmarkRunner_modifiedService(void * handle, service_reference_pt reference, void * service);
+static celix_status_t benchmarkRunner_removedService(void * handle, service_reference_pt reference, void * service);
+
+static void benchmarkRunner_runBenchmark(struct activator *activator);
+static void benchmarkRunner_printHeader(char *name, unsigned int nrOfSamples);
+static void benchmarkRunner_printResult(benchmark_result_t result, double updateFreq, unsigned long elapsedTime);
+static void benchmarkRunner_printFooter(char *name);
+
+struct benchmark_entry {
+	benchmark_service_pt benchmark;
+	LIST_ENTRY(benchmark_entry) entries;
+};
+
+struct activator {
+	bundle_context_pt context;
+	service_tracker_customizer_pt customizer;
+	service_tracker_pt tracker;
+	pthread_t thread;
+
+	pthread_mutex_t mutex;
+	array_list_pt benchmarks;
+	LIST_HEAD(benchmark_entries, entries) benchmarkEntries;
+	frequency_service_pt freqService;
+};
+
+celix_status_t bundleActivator_create(bundle_context_pt context, void **userData) {
+	struct activator * activator = malloc(sizeof(*activator));
+	activator->context=context;
+	activator->customizer = NULL;
+	activator->tracker= NULL;
+	activator->benchmarks = NULL;
+	activator->freqService = NULL;
+
+	LIST_INIT(&activator->benchmarkEntries);
+
+	*userData = activator;
+
+	return CELIX_SUCCESS;
+}
+
+celix_status_t bundleActivator_start(void * userData, bundle_context_pt context) {
+	celix_status_t status = CELIX_SUCCESS;
+	struct activator * activator = userData;
+
+	pthread_mutex_init(&activator->mutex, NULL);
+
+	arrayList_create(&activator->benchmarks);
+
+	serviceTrackerCustomizer_create(activator, benchmarkRunner_addingService, benchmarkRunner_addedService, benchmarkRunner_modifiedService, benchmarkRunner_removedService, &activator->customizer);
+
+	char filter[128];
+	sprintf(filter, "(|(%s=%s)(%s=%s))", "objectClass", BENCHMARK_SERVICE_NAME, "objectClass", FREQUENCY_SERVICE_NAME);
+	serviceTracker_createWithFilter(context, filter, activator->customizer, &activator->tracker);
+	serviceTracker_open(activator->tracker);
+
+	pthread_create(&activator->thread, NULL, (void *)benchmarkRunner_runBenchmark, activator);
+
+	return status;
+}
+
+
+celix_status_t bundleActivator_stop(void * userData, bundle_context_pt context) {
+	struct activator * activator = userData;
+
+	pthread_join(activator->thread, NULL);
+
+	serviceTracker_close(activator->tracker);
+
+	return CELIX_SUCCESS;
+}
+
+celix_status_t bundleActivator_destroy(void * userData, bundle_context_pt context) {
+	struct activator * activator = userData;
+
+	return CELIX_SUCCESS;
+}
+
+static celix_status_t benchmarkRunner_addingService(void * handle, service_reference_pt reference, void **service) {
+	celix_status_t status = CELIX_SUCCESS;
+	struct activator * activator = handle;
+	status = bundleContext_getService(activator->context, reference, service);
+	return status;
+
+}
+static celix_status_t benchmarkRunner_addedService(void * handle, service_reference_pt reference, void * service) {
+	celix_status_t status = CELIX_SUCCESS;
+	struct activator * activator = handle;
+
+	service_registration_pt registration = NULL;
+	properties_pt properties = NULL;
+	char *serviceName = NULL;
+	serviceReference_getServiceRegistration(reference, &registration);
+	serviceRegistration_getProperties(registration, &properties);
+	serviceName = properties_get(properties, "objectClass");
+	if (strcmp(serviceName, BENCHMARK_SERVICE_NAME) == 0) {
+		pthread_mutex_lock(&activator->mutex);
+		arrayList_add(activator->benchmarks, service);
+		pthread_mutex_unlock(&activator->mutex);
+	} else if (strcmp(serviceName, FREQUENCY_SERVICE_NAME) == 0 ) {
+		pthread_mutex_lock(&activator->mutex);
+		activator->freqService = service;
+		pthread_mutex_unlock(&activator->mutex);
+	}
+
+	return status;
+}
+static celix_status_t benchmarkRunner_modifiedService(void * handle, service_reference_pt reference, void * service) {
+	celix_status_t status = CELIX_SUCCESS;
+	struct activator * activator = handle;
+	return status;
+}
+
+static celix_status_t benchmarkRunner_removedService(void * handle, service_reference_pt reference, void * service) {
+	celix_status_t status = CELIX_SUCCESS;
+	struct activator * activator = handle;
+
+	service_registration_pt registration = NULL;
+		properties_pt properties = NULL;
+		char *serviceName = NULL;
+		serviceReference_getServiceRegistration(reference, &registration);
+		serviceRegistration_getProperties(registration, &properties);
+		serviceName = properties_get(properties, "objectClass");
+		if (strcmp(serviceName, BENCHMARK_SERVICE_NAME) == 0) {
+			pthread_mutex_lock(&activator->mutex);
+			arrayList_removeElement(activator->benchmarks, service);
+			pthread_mutex_unlock(&activator->mutex);
+		} else if (strcmp(serviceName, FREQUENCY_SERVICE_NAME) == 0 ) {
+			pthread_mutex_lock(&activator->mutex);
+			if (activator->freqService == service) {
+				activator->freqService = NULL;
+			}
+			pthread_mutex_unlock(&activator->mutex);
+		}
+
+	return status;
+}
+
+static void benchmarkRunner_runBenchmark(struct activator *activator) {
+	int i, k;
+	int nrOfBenchmarks;
+	double updateFrequency, measuredFrequency;
+	unsigned int measuredUpdateCounter, nrOfUpdateThreads;
+	int nrOfSamples;
+	benchmark_service_pt benchmarkServ;
+	char *name;
+	benchmark_result_t result;
+	struct timeval begin,end;
+	unsigned long elapsedTime;
+	double sampleFactor;
+
+	int nrOfThreadRuns = 12;
+	int threads[] = {1,2,3,4,5,6,7,8,16,32,64,128};
+
+	nrOfSamples = 100 * 1000;
+	updateFrequency = 1000;
+	nrOfUpdateThreads = 100;
+
+	usleep(2000 * 1000); //wait 2 seconds to get needed services
+
+	pthread_mutex_lock(&activator->mutex);
+	if (activator->freqService != NULL) {
+		activator->freqService->setFrequency(activator->freqService->handle, updateFrequency);
+		activator->freqService->setNrOfThreads(activator->freqService->handle, nrOfUpdateThreads);
+	}
+	nrOfBenchmarks = arrayList_size(activator->benchmarks);
+	for (i = 0 ; i < nrOfBenchmarks ; i += 1) {
+		benchmarkServ = arrayList_get(activator->benchmarks, i);
+		name = benchmarkServ->name(benchmarkServ->handler);
+		sampleFactor = benchmarkServ->getSampleFactor(benchmarkServ->handler);
+		activator->freqService->setBenchmarkName(activator->freqService->handle, name);
+		usleep(1000);
+		benchmarkRunner_printHeader(name, nrOfSamples * sampleFactor);
+		for (k = 0 ; k < nrOfThreadRuns ; k +=1) {
+			if (activator->freqService != NULL) {
+					activator->freqService->resetCounter(activator->freqService->handle);
+
+			}
+			gettimeofday(&begin, NULL);
+			result = benchmarkServ->run(benchmarkServ->handler, threads[k], nrOfSamples * sampleFactor);
+			gettimeofday(&end, NULL);
+			elapsedTime = ((end.tv_sec - begin.tv_sec) * 1000000) + (end.tv_usec - begin.tv_usec);
+			if (activator->freqService != NULL) {
+				measuredUpdateCounter = activator->freqService->getCounter(activator->freqService->handle);
+				measuredFrequency = ((double)(measuredUpdateCounter) / elapsedTime * 1000000);
+			}
+			benchmarkRunner_printResult(result, measuredFrequency, elapsedTime);
+		}
+		benchmarkRunner_printFooter(name);
+	}
+	pthread_mutex_unlock(&activator->mutex);
+}
+
+static void benchmarkRunner_printHeader(char *name, unsigned int nrOfSamples) {
+		int i;
+		printf("---% 35s---------------------------------------------------------------------------------------\n", name);
+		printf("-------samples: %10i---------------------------------------------------------------------------------------------------\n", nrOfSamples);
+}
+
+static void benchmarkRunner_printResult(benchmark_result_t result, double updateFreq, unsigned long elapsedTime) {
+	printf("| threads %5i | ", result.nrOfThreads);
+	printf("average call time: % 10.2f nanoseconds | ", result.averageCallTimeInNanoseconds);
+	printf("frequency calls is % 10.5f MHz | ", result.callFrequencyInMhz);
+	printf("update freq ~ % 8.2f Hz | ", updateFreq);
+	printf("elapsed time is % 8.5f seconds | ", ((double)elapsedTime) / 1000000);
+	printf("\n");
+}
+
+static void benchmarkRunner_printFooter(char *name) {
+	printf("-----------------------------------------------------------------------------------------------------------------------------\n\n\n");
+}

http://git-wip-us.apache.org/repos/asf/celix/blob/e0231e51/examples/locking/benchmark/public/include/benchmark.h
----------------------------------------------------------------------
diff --git a/examples/locking/benchmark/public/include/benchmark.h b/examples/locking/benchmark/public/include/benchmark.h
new file mode 100644
index 0000000..971f111
--- /dev/null
+++ b/examples/locking/benchmark/public/include/benchmark.h
@@ -0,0 +1,29 @@
+/*
+ * consumer.h
+ *
+ *  Created on: Feb 13, 2014
+ *      Author: dl436
+ */
+
+#ifndef CONSUMER_H_
+#define CONSUMER_H_
+
+#include "celix_errno.h"
+
+#include "benchmark_result.h"
+#include "math_service.h"
+
+typedef struct benchmark *benchmark_pt; //ADT
+
+celix_status_t benchmark_create(benchmark_pt *benchmark);
+celix_status_t benchmark_destroy(benchmark_pt benchmark);
+
+benchmark_result_t benchmark_run(benchmark_pt benchmark, int nrOfThreads, int nrOfSamples);
+char * benchmark_getName(benchmark_pt benchmark);
+double benchmark_getSampleFactor(benchmark_pt benchmark);
+
+celix_status_t benchmark_addMathService(benchmark_pt benchmark, math_service_pt mathService);
+celix_status_t benchmark_removeMathService(benchmark_pt benchmark, math_service_pt mathService);
+
+
+#endif /* CONSUMER_H_ */

http://git-wip-us.apache.org/repos/asf/celix/blob/e0231e51/examples/locking/benchmark/public/include/benchmark_result.h
----------------------------------------------------------------------
diff --git a/examples/locking/benchmark/public/include/benchmark_result.h b/examples/locking/benchmark/public/include/benchmark_result.h
new file mode 100644
index 0000000..e0750a8
--- /dev/null
+++ b/examples/locking/benchmark/public/include/benchmark_result.h
@@ -0,0 +1,20 @@
+/*
+ * benchmark_result.h
+ *
+ *  Created on: Feb 13, 2014
+ *      Author: dl436
+ */
+
+#ifndef BENCHMARK_RESULT_H_
+#define BENCHMARK_RESULT_H_
+
+typedef struct benchmark_result {
+		unsigned int nrOfThreads;
+		unsigned int nrOfsamples;
+		unsigned int result;
+		unsigned int skips;
+		double averageCallTimeInNanoseconds;
+		double callFrequencyInMhz;
+} benchmark_result_t;
+
+#endif /* BENCHMARK_RESULT_H_ */

http://git-wip-us.apache.org/repos/asf/celix/blob/e0231e51/examples/locking/benchmark/public/include/benchmark_service.h
----------------------------------------------------------------------
diff --git a/examples/locking/benchmark/public/include/benchmark_service.h b/examples/locking/benchmark/public/include/benchmark_service.h
new file mode 100644
index 0000000..63ada04
--- /dev/null
+++ b/examples/locking/benchmark/public/include/benchmark_service.h
@@ -0,0 +1,27 @@
+/*
+ * benchmark_service.h
+ *
+ *  Created on: Feb 13, 2014
+ *      Author: dl436
+ */
+
+#ifndef BENCHMARK_SERVICE_H_
+#define BENCHMARK_SERVICE_H_
+
+#include "benchmark_result.h"
+
+typedef struct benchmark_service *benchmark_service_pt;
+
+typedef struct benchmark_handler *benchmark_handler_pt; //ADT
+
+#define BENCHMARK_SERVICE_NAME "benchmark_service"
+
+struct benchmark_service {
+	benchmark_handler_pt handler;
+
+	benchmark_result_t (*run)(benchmark_handler_pt handler, int nrOfThreads, int nrOfSamples);
+	char * (*name)(benchmark_handler_pt handler);
+	double (*getSampleFactor)(benchmark_handler_pt benchmark);
+};
+
+#endif /* BENCHMARK_SERVICE_H_ */

http://git-wip-us.apache.org/repos/asf/celix/blob/e0231e51/examples/locking/benchmark/public/include/frequency_service.h
----------------------------------------------------------------------
diff --git a/examples/locking/benchmark/public/include/frequency_service.h b/examples/locking/benchmark/public/include/frequency_service.h
new file mode 100644
index 0000000..5c022ce
--- /dev/null
+++ b/examples/locking/benchmark/public/include/frequency_service.h
@@ -0,0 +1,47 @@
+/**
+ *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.
+ */
+/*
+ * frequence_service.h
+ *
+ *  \date       Feb 4, 2014
+ *  \author    	<a href="mailto:celix-dev@incubator.apache.org">Apache Celix Project Team</a>
+ *  \copyright	Apache License, Version 2.0
+ */
+
+//TODO change to math provider service ???
+
+#ifndef FREQUENCY_SERVICE_H
+#define FREQUENCY_SERVICE_H
+
+#define FREQUENCY_SERVICE_NAME "frequency_service"
+
+typedef struct frequency_hander frequence_handler_t;
+
+struct frequency_service {
+	frequence_handler_t *handle;
+	void (*setFrequency)(frequence_handler_t *handle, int freq);
+	void (*resetCounter)(frequence_handler_t *handle);
+	uint (*getCounter)(frequence_handler_t *handle);
+	void (*setBenchmarkName)(frequence_handler_t *handle, char *name);
+	void (*setNrOfThreads)(frequence_handler_t *handle, uint nrOfThreads);
+};
+
+typedef struct frequency_service * frequency_service_pt;
+
+#endif /* FREQUENCY_SERVICE_H */

http://git-wip-us.apache.org/repos/asf/celix/blob/e0231e51/examples/locking/benchmark/public/include/math_service.h
----------------------------------------------------------------------
diff --git a/examples/locking/benchmark/public/include/math_service.h b/examples/locking/benchmark/public/include/math_service.h
new file mode 100644
index 0000000..154cc9c
--- /dev/null
+++ b/examples/locking/benchmark/public/include/math_service.h
@@ -0,0 +1,40 @@
+/**
+ *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.
+ */
+/*
+ * echo_server.h
+ *
+ *  \date       Sep 21, 2010
+ *  \author    	<a href="mailto:celix-dev@incubator.apache.org">Apache Celix Project Team</a>
+ *  \copyright	Apache License, Version 2.0
+ */
+
+#ifndef MATH_SERVICE_H 
+#define MATH_SERVICE_H 
+
+#define MATH_SERVICE_NAME "math_service"
+
+
+struct math_service {
+	void *handle;
+	int (*calc)(void *handle, int arg1, int arg2);
+};
+
+typedef struct math_service * math_service_pt;
+
+#endif /* MATH_SERVICE_H */

http://git-wip-us.apache.org/repos/asf/celix/blob/e0231e51/examples/locking/benchmark/public/src/benchmark_activator.c
----------------------------------------------------------------------
diff --git a/examples/locking/benchmark/public/src/benchmark_activator.c b/examples/locking/benchmark/public/src/benchmark_activator.c
new file mode 100644
index 0000000..a161f11
--- /dev/null
+++ b/examples/locking/benchmark/public/src/benchmark_activator.c
@@ -0,0 +1,133 @@
+/**
+ *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.
+ */
+/*
+ * echo_server_activator.c
+ *
+ *  \date       Sep 21, 2010
+ *  \author    	<a href="mailto:celix-dev@incubator.apache.org">Apache Celix Project Team</a>
+ *  \copyright	Apache License, Version 2.0
+ */
+#include <stdlib.h>
+#include <unistd.h>
+
+#include "bundle_activator.h"
+#include "bundle_context.h"
+#include "service_registration.h"
+#include "service_tracker.h"
+
+#include "math_service.h"
+#include "benchmark.h"
+#include "benchmark_service.h"
+#include "frequency_service.h"
+
+static celix_status_t addingService(void * handle, service_reference_pt reference, void **service);
+static celix_status_t addedService(void * handle, service_reference_pt reference, void * service);
+static celix_status_t modifiedService(void * handle, service_reference_pt reference, void * service);
+static celix_status_t removedService(void * handle, service_reference_pt reference, void * service);
+
+struct activator {
+	bundle_context_pt context;
+	benchmark_pt benchmark;
+	benchmark_service_pt mathService;
+	service_tracker_customizer_pt customizer;
+	service_tracker_pt tracker;
+	service_registration_pt registration;
+};
+
+celix_status_t bundleActivator_create(bundle_context_pt context, void **userData) {
+	struct activator * activator = malloc(sizeof(*activator));
+	activator->context=context;
+	activator->benchmark=NULL;
+	activator->mathService = NULL;
+	activator->customizer = NULL;
+	activator->tracker=NULL;
+	activator->registration = NULL;
+
+	*userData = activator;
+
+	return CELIX_SUCCESS;
+}
+
+celix_status_t bundleActivator_start(void * userData, bundle_context_pt context) {
+	celix_status_t status = CELIX_SUCCESS;
+	struct activator * activator = userData;
+
+	status = benchmark_create(&activator->benchmark);
+	serviceTrackerCustomizer_create(activator, addingService, addedService, modifiedService, removedService, &activator->customizer);
+
+	char filter[128];
+	sprintf(filter, "(&(objectClass=%s)(benchmark=%s))", MATH_SERVICE_NAME, benchmark_getName(activator->benchmark));
+
+	serviceTracker_createWithFilter(context, filter, activator->customizer, &activator->tracker);
+	serviceTracker_open(activator->tracker);
+
+	activator->mathService = malloc(sizeof(*activator->mathService));
+	activator->mathService->handler = (void *)activator->benchmark;
+	activator->mathService->name=(void *)benchmark_getName;
+	activator->mathService->getSampleFactor=(void *)benchmark_getSampleFactor;
+	activator->mathService->run=(void *)benchmark_run;
+
+	status = bundleContext_registerService(activator->context, BENCHMARK_SERVICE_NAME, activator->mathService, NULL, &activator->registration);
+
+	return status;
+}
+
+
+celix_status_t bundleActivator_stop(void * userData, bundle_context_pt context) {
+	struct activator * activator = userData;
+
+	serviceTracker_close(activator->tracker);
+
+	return CELIX_SUCCESS;
+}
+
+celix_status_t bundleActivator_destroy(void * userData, bundle_context_pt context) {
+	struct activator * activator = userData;
+
+	benchmark_destroy(activator->benchmark);
+	activator->benchmark=NULL;
+
+	return CELIX_SUCCESS;
+}
+
+static celix_status_t addingService(void * handle, service_reference_pt reference, void **service) {
+	celix_status_t status = CELIX_SUCCESS;
+	struct activator * activator = handle;
+	status = bundleContext_getService(activator->context, reference, service);
+	return status;
+
+}
+static celix_status_t addedService(void * handle, service_reference_pt reference, void * service) {
+	celix_status_t status = CELIX_SUCCESS;
+	struct activator * activator = handle;
+	benchmark_addMathService(activator->benchmark, service);
+	return status;
+}
+static celix_status_t modifiedService(void * handle, service_reference_pt reference, void * service) {
+	celix_status_t status = CELIX_SUCCESS;
+	struct activator * activator = handle;
+	return status;
+}
+
+static celix_status_t removedService(void * handle, service_reference_pt reference, void * service) {
+	celix_status_t status = CELIX_SUCCESS;
+	struct activator * activator = handle;
+	benchmark_removeMathService(activator->benchmark, service);
+	return status;
+}

http://git-wip-us.apache.org/repos/asf/celix/blob/e0231e51/examples/locking/consumer.c
----------------------------------------------------------------------
diff --git a/examples/locking/consumer.c b/examples/locking/consumer.c
new file mode 100644
index 0000000..b73549e
--- /dev/null
+++ b/examples/locking/consumer.c
@@ -0,0 +1,372 @@
+/**
+ *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.
+ */
+/*
+ * consumer.c
+ *
+ *  \date       Feb 3, 2014
+ *  \author    	<a href="mailto:celix-dev@incubator.apache.org">Apache Celix Project Team</a>
+ *  \copyright	Apache License, Version 2.0
+ */
+
+#include "consumer.h"
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdbool.h>
+#include <sys/time.h>
+#include <unistd.h>
+#include <pthread.h>
+
+#include <urcu.h>
+
+#include "math_service.h"
+#include "frequency_service.h"
+
+#define FREELIST_LENGTH 16
+
+typedef union service_counter service_counter_t;
+
+union service_counter {
+	volatile struct {
+		volatile u_int32_t counter; //TODO FIXME assuming little endian!!
+		volatile u_int32_t position;
+		math_service_pt math; // not accesible by raw
+	} info; //TODO rename data
+	volatile u_int64_t data; //TODO rename raw
+};
+
+struct consumer {
+	math_service_pt math;
+	frequency_service_pt frequencyService;
+	locking_type_t currentLockingType;
+	pthread_mutex_t mutex;
+	pthread_rwlock_t rw_lock;
+	service_counter_t *counters[FREELIST_LENGTH];
+	service_counter_t *current;
+};
+
+typedef struct run_info {
+	consumer_pt consumer;
+	volatile locking_type_t type;
+	int nrOfsamples;
+	int result;
+	uint skips;
+	uint updateCounter;
+	struct timeval begin;
+	struct timeval end;
+} run_info_t;
+
+static void * consumer_reference_run(run_info_t *info);
+static void * consumer_no_locking_run(run_info_t *info);
+static void * consumer_mutex_run(run_info_t *info);
+static void * consumer_rcu_run(run_info_t *info);
+static void * consumer_reference_counting_run(run_info_t *info);
+static void * consumer_rw_lock_run(run_info_t *info);
+
+static int consumer_reference_calc(int arg1, int arg2);
+
+celix_status_t consumer_create(consumer_pt *result) {
+	consumer_pt consumer = malloc(sizeof(*consumer));
+	consumer->math = NULL;
+	consumer->frequencyService = NULL;
+	consumer->currentLockingType=LOCKING_TYPE_NO_LOCKING;
+
+
+	service_counter_t *new = malloc(sizeof(service_counter_t));
+	new->info.position = 0;
+	new->info.counter = 0;
+	new->info.math = NULL;
+
+	int i;
+	for (i = 0; i < FREELIST_LENGTH; i+=1) {
+		consumer->counters[i] = NULL;
+	}
+	consumer->current = new;
+	consumer->counters[0] = new;
+
+	pthread_mutex_init(&consumer->mutex, NULL);
+	pthread_rwlock_init(&consumer->rw_lock, NULL);
+
+	rcu_init();
+
+	(*result) = consumer;
+	return CELIX_SUCCESS;
+}
+
+celix_status_t consumer_destroy(consumer_pt consumer) {
+	pthread_mutex_destroy(&consumer->mutex);
+	pthread_rwlock_destroy(&consumer->rw_lock);
+	free(consumer);
+	return CELIX_SUCCESS;
+}
+
+void consumer_setFrequencyService(consumer_pt consumer, frequency_service_pt freqServ) {
+	consumer->frequencyService=freqServ;
+}
+
+void consumer_runBenchmark(consumer_pt consumer, locking_type_t type, int nrOfThreads, int nrOfSamples) {
+	pthread_t threads[nrOfThreads];
+	run_info_t info[nrOfThreads];
+	int elapsedTime, skips, counter;
+	double callTime, callFreq, updateFreq;
+	int i;
+
+	consumer->currentLockingType=type;
+	usleep(1000);
+
+	//init
+	for (i = 0; i< nrOfThreads; i += 1) {
+		info[i].consumer = consumer;
+		info[i].nrOfsamples=nrOfSamples;
+		info[i].result = rand();
+		info[i].skips = 0;
+		info[i].updateCounter = 0;
+	}
+	elapsedTime = 0;
+	skips = 0;
+
+	//start threads
+	info->consumer->frequencyService->resetCounter(info->consumer->frequencyService->handler);
+	for (i = 0; i < nrOfThreads; i += 1) {
+		if (type == LOCKING_TYPE_NO_LOCKING) {
+			pthread_create(&threads[i], NULL, (void *)consumer_no_locking_run, &info[i]);
+		} else if (type == LOCKING_TYPE_MUTEX) {
+			pthread_create(&threads[i], NULL, (void *)consumer_mutex_run, &info[i]);
+		} else if (type == LOCKING_TYPE_REFERENCE) {
+			pthread_create(&threads[i], NULL, (void *)consumer_reference_run, &info[i]);
+		} else if (type == LOCKING_TYPE_RCU) {
+			pthread_create(&threads[i], NULL, (void *)consumer_rcu_run, &info[i]);
+		} else if (type == LOCKING_TYPE_REFERENCE_COUNTER) {
+			pthread_create(&threads[i], NULL, (void *)consumer_reference_counting_run, &info[i]);
+		} else if (type == LOCKING_TYPE_RW_LOCK) {
+			pthread_create(&threads[i], NULL, (void *)consumer_rw_lock_run, &info[i]);
+		} else {
+			printf ("unknown type\n");
+			return;
+		}
+	}
+
+	//join and print result
+
+	for (i = 0; i < nrOfThreads; i +=1 ) {
+		pthread_join(threads[i], NULL);
+		elapsedTime += ((info[i].end.tv_sec - info[i].begin.tv_sec) * 1000000) + (info[i].end.tv_usec - info[i].begin.tv_usec);
+		skips += info[i].skips;
+		counter += info[i].updateCounter;
+	}
+	counter = info->consumer->frequencyService->getCounter(info->consumer->frequencyService->handler);
+	callTime = ((double)elapsedTime * 1000) / (nrOfSamples * nrOfThreads);
+	callFreq = ((double)(nrOfSamples * nrOfThreads) / elapsedTime);
+	updateFreq = ((double)counter * 1000000) / elapsedTime;
+	printf("| threads %5i | ", nrOfThreads);
+	printf("average call time: % 10.2f nanoseconds | ", callTime);
+	printf("frequency calls is % 10.5f MHz | ", callFreq);
+	printf("update freq ~ % 8.2f Hz | ", updateFreq);
+	printf("\n");
+
+	if (skips > 0) {
+		printf("WARNING skips is %i\n", skips);
+	}
+}
+
+celix_status_t consumer_addMathService(consumer_pt consumer, math_service_pt mathService) {
+	if (consumer->currentLockingType == LOCKING_TYPE_MUTEX) {
+		pthread_mutex_lock(&consumer->mutex);
+		consumer->math = mathService;
+		pthread_mutex_unlock(&consumer->mutex);
+	} else if (consumer->currentLockingType == LOCKING_TYPE_RCU) {
+		consumer->math = mathService;
+		synchronize_rcu();
+	} else if (consumer->currentLockingType == LOCKING_TYPE_RW_LOCK) {
+		pthread_rwlock_wrlock(&consumer->rw_lock);
+		consumer->math = mathService;
+		pthread_rwlock_unlock(&consumer->rw_lock);
+	} else { //no locking
+		consumer->math = mathService;
+	}
+
+	//always update for reference counter
+//	service_counter_t *new = malloc(sizeof(service_counter_t));
+//	new->info.position = 0;
+//	new->info.counter = 0;
+//	new->info.math = mathService;
+//	int found = false;
+//	int pos;
+//	for (pos = 0; !found && pos < FREELIST_LENGTH; pos += 1) {
+//		found = __sync_bool_compare_and_swap(&(consumer->counters[pos]), NULL, new);
+//		if (found) {
+//			new->info.position = pos;
+//			break;
+//		}
+//	}
+//
+//	if (!found) {
+//		printf("Cannot find free spot!!!!, will use 0\n");
+//		consumer->counters[0] = new;
+//	}
+//
+//	int changed = false;
+//	service_counter_t *old;
+//	while (!changed) {
+//		old = consumer->current;
+//		changed = __sync_bool_compare_and_swap(&consumer->current, old, new);
+//	}
+//
+//	while (old->info.counter != 0) {usleep(10);}
+//	consumer->counters[old->info.position] = NULL;
+//	free(old);
+
+	return CELIX_SUCCESS;
+}
+
+celix_status_t consumer_removeMathService(consumer_pt consumer, math_service_pt mathService) {
+	if (consumer->currentLockingType == LOCKING_TYPE_NO_LOCKING) {
+		__sync_val_compare_and_swap(&consumer->math, mathService, NULL);
+	} else if (consumer->currentLockingType == LOCKING_TYPE_MUTEX) {
+		pthread_mutex_lock(&consumer->mutex);
+		if (consumer->math == mathService) {
+			consumer->math = NULL;
+		}
+		pthread_mutex_unlock(&consumer->mutex);
+	} else if (consumer->currentLockingType == LOCKING_TYPE_RCU) {
+		uatomic_cmpxchg(&consumer->math, mathService, NULL);
+	} else if (consumer->currentLockingType == LOCKING_TYPE_REFERENCE_COUNTER) {
+		//TODO DONT KNOWN IGNORE FOR NOW
+	}
+	return CELIX_SUCCESS;
+}
+
+static void * consumer_reference_run(run_info_t *info) {
+	int i;
+
+	gettimeofday(&info->begin, NULL);
+	for (i = 0; i < info->nrOfsamples; i += 1) {
+		info->result = consumer_reference_calc(info->result, i);
+	}
+	gettimeofday(&info->end, NULL);
+	return NULL;
+}
+
+static void * consumer_no_locking_run(run_info_t *info) {
+	int i;
+
+	gettimeofday(&info->begin, NULL);
+	for (i = 0; i < info->nrOfsamples; i += 1) {
+		if (info->consumer->math != NULL) {
+				info->result = info->consumer->math->calc(info->result, i);
+		} else {
+				info->skips +=1; //should not happen
+		}
+	}
+	gettimeofday(&info->end, NULL);
+	return NULL;
+}
+
+static void * consumer_mutex_run(run_info_t *info) {
+	int i;
+
+	gettimeofday(&info->begin, NULL);
+	for (i = 0; i < info->nrOfsamples; i += 1) {
+		pthread_mutex_lock(&info->consumer->mutex);
+		if (info->consumer->math != NULL) {
+			info->result = info->consumer->math->calc(info->result, i);
+		} else {
+			info->skips += 1; //should not happen
+		}
+		pthread_mutex_unlock(&info->consumer->mutex);
+	}
+	gettimeofday(&info->end, NULL);
+	return NULL;
+}
+
+static void * consumer_rw_lock_run(run_info_t *info) {
+	int i;
+	consumer_pt cons = info->consumer;
+	int result = info->result;
+	pthread_rwlock_t *lock = &cons->rw_lock;
+	int nrOfsamples = info->nrOfsamples;
+
+	gettimeofday(&info->begin, NULL);
+	for (i = 0; i < nrOfsamples; i += 1) {
+		pthread_rwlock_rdlock(lock);
+		if (cons->math != NULL) {
+			result = cons->math->calc(result, i);
+		} else {
+			info->skips += 1; //should not happen
+		}
+		pthread_rwlock_unlock(lock);
+	}
+	gettimeofday(&info->end, NULL);
+	info->result = result;
+	return NULL;
+}
+
+static void * consumer_rcu_run(run_info_t *info) {
+	rcu_register_thread();
+	int i;
+	math_service_pt service;
+
+	gettimeofday(&info->begin, NULL);
+	for (i = 0; i < info->nrOfsamples; i += 1) {
+		rcu_read_lock();
+		if (info->consumer->math != NULL) {
+			info->result = info->consumer->math->calc(info->result, i);
+		} else {
+			info->skips +=1; //should not happen
+		}
+		rcu_read_unlock();
+	}
+	gettimeofday(&info->end, NULL);
+	rcu_unregister_thread();
+	return NULL;
+}
+
+static void * consumer_reference_counting_run(run_info_t *info) {
+	int i;
+	service_counter_t posAndCount;
+
+	gettimeofday(&info->begin, NULL);
+	for (i = 0; i < info->nrOfsamples; i += 1) {
+		posAndCount.data = __sync_add_and_fetch((u_int64_t *)&info->consumer->current->data, 1);
+		volatile service_counter_t *serv = (volatile void *)info->consumer->counters[posAndCount.info.position];
+		if (serv->info.math != NULL) {
+			info->result = serv->info.math->calc(info->result, i);
+		} else {
+			info->skips += 1;
+		}
+		__sync_sub_and_fetch((u_int64_t *)&serv->data, -1);
+
+		//not service_counter will not be deleted...but can we still find it??? is info->consumer->serviceCounter still te same?
+		//change write to swap compare and then only changing the pointer is the counter is null?? not possible.. can compare counter , but not change pointer
+
+		//IDEA create a list with service_counter based on a id (number) this number is 32bit long and put a counter + id in a 64bit value.
+		//use this value to atomic increment and return value and use the id to retrieve the actual pointer. the value can be stored in the heap.
+		//A list with id is used to retrieve a pointer to the service. If the value is null the slot is available this can be check with
+		//compare_and_swap while looping through the list. The list can be extended when the end is reached and then a next list pointer can
+		//be used. This can also be a linked list and the limitation is the max 32bit uint value (of 16bits for 32bit platforms).
+	}
+
+	gettimeofday(&info->end, NULL);
+	return NULL;
+}
+
+//NOTE: copy implementation of the math_service->calc function, for reference.
+static int consumer_reference_calc(int arg1, int arg2) {
+	return  arg1 * arg2 + arg2;
+}

http://git-wip-us.apache.org/repos/asf/celix/blob/e0231e51/examples/locking/math_provider/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/examples/locking/math_provider/CMakeLists.txt b/examples/locking/math_provider/CMakeLists.txt
new file mode 100644
index 0000000..288d6ba
--- /dev/null
+++ b/examples/locking/math_provider/CMakeLists.txt
@@ -0,0 +1,32 @@
+# 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.
+
+SET(BUNDLE_SYMBOLICNAME math_provider)
+SET(BUNDLE_VERSION 0.0.0)
+
+bundle(math_provider SOURCES 
+	private/src/provider_activator 
+	private/src/math_component
+)
+
+include_directories(public/include)
+include_directories(../benchmark/public/include)
+include_directories("${PROJECT_SOURCE_DIR}/framework/public/include")
+include_directories("${PROJECT_SOURCE_DIR}/utils/public/include")
+include_directories("${PROJECT_SOURCE_DIR}/shell/public/include")
+include_directories(private/include)
+target_link_libraries(math_provider celix_framework)

http://git-wip-us.apache.org/repos/asf/celix/blob/e0231e51/examples/locking/math_provider/private/include/math_component.h
----------------------------------------------------------------------
diff --git a/examples/locking/math_provider/private/include/math_component.h b/examples/locking/math_provider/private/include/math_component.h
new file mode 100644
index 0000000..0b55d10
--- /dev/null
+++ b/examples/locking/math_provider/private/include/math_component.h
@@ -0,0 +1,14 @@
+#ifndef MATH_COMPONENT_H_
+#define MATH_COMPONENT_H_
+
+#include "celix_errno.h"
+
+typedef struct math_component *math_component_pt;
+
+celix_status_t mathComponent_create(math_component_pt *math);
+celix_status_t mathComponent_destroy(math_component_pt math);
+
+int mathComponent_calc(math_component_pt math, int arg1, int arg2);
+
+
+#endif /* MATH_COMPONENT_H_ */

http://git-wip-us.apache.org/repos/asf/celix/blob/e0231e51/examples/locking/math_provider/private/src/math_component.c
----------------------------------------------------------------------
diff --git a/examples/locking/math_provider/private/src/math_component.c b/examples/locking/math_provider/private/src/math_component.c
new file mode 100644
index 0000000..2937fee
--- /dev/null
+++ b/examples/locking/math_provider/private/src/math_component.c
@@ -0,0 +1,28 @@
+/*
+ * math.c
+ *
+ *  Created on: Oct 8, 2014
+ *      Author: dl436
+ */
+
+#include "math_component.h"
+
+struct math_component {
+	//emtpy
+};
+
+celix_status_t mathComponent_create(math_component_pt *math) {
+	(*math) = malloc(sizeof(struct math_component));
+	return CELIX_SUCCESS;
+}
+
+celix_status_t mathComponent_destroy(math_component_pt math) {
+	free(math);
+	return CELIX_SUCCESS;
+}
+
+int mathComponent_calc(math_component_pt math, int arg1, int arg2) {
+	return arg1 * arg2 + arg2;
+}
+
+

http://git-wip-us.apache.org/repos/asf/celix/blob/e0231e51/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
new file mode 100644
index 0000000..319980f
--- /dev/null
+++ b/examples/locking/math_provider/private/src/provider_activator.c
@@ -0,0 +1,219 @@
+/**
+ *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.
+ */
+/*
+ * echo_server_activator.c
+ *
+ *  \date       Sep 21, 2010
+ *  \author    	<a href="mailto:celix-dev@incubator.apache.org">Apache Celix Project Team</a>
+ *  \copyright	Apache License, Version 2.0
+ */
+#include <stdlib.h>
+#include <unistd.h>
+#include <stdbool.h>
+#include <sys/time.h>
+
+#include "bundle_activator.h"
+#include "bundle_context.h"
+#include "service_registration.h"
+
+#include "math_service.h"
+#include "frequency_service.h"
+#include "math_component.h"
+
+typedef struct activator {
+	bundle_context_pt context;
+
+	frequency_service_pt freqService;
+	service_registration_pt freqRegistration;
+
+	math_component_pt math;
+	math_service_pt mathService;
+	char *benchmarkName;
+	service_registration_pt registration;
+
+	uint updateFrequency;
+	uint nrOfThreads;
+	pthread_t *threads;
+
+
+	volatile uint counter;
+	struct timeval beginMeasurement;
+	struct timeval endMeasurement;
+} activator_t;
+
+static int calc(int arg1, int arg2);
+static void run(activator_t *activator);
+static void setFrequency(activator_t *activator, uint freq);
+static void setNrOfThreads(activator_t *activator, uint nrOfThreads);
+static void resetCounter(activator_t *activator);
+static void stopThreads(activator_t *activator);
+static void startThreads(activator_t *activator, uint nrOfThreads);
+static uint getCounter(activator_t *activator);
+static void setBenchmarkName(activator_t *activator, char *benchmark);
+static math_service_pt registerMath(activator_t *activator, service_registration_pt *reg);
+
+celix_status_t bundleActivator_create(bundle_context_pt context, void **userData) {
+	activator_t * activator = malloc(sizeof(*activator));
+	activator->context = context;
+	activator->benchmarkName = NULL;
+	activator->freqService  = NULL;
+	activator->freqRegistration  = NULL;
+	activator->updateFrequency = 0;
+	activator->nrOfThreads = 0;
+	activator->math = NULL;
+
+	mathComponent_create(&activator->math);
+
+	*userData = activator;
+
+	return CELIX_SUCCESS;
+}
+
+celix_status_t bundleActivator_start(void * userData, bundle_context_pt context) {
+	celix_status_t status = CELIX_SUCCESS;
+	struct activator * activator = userData;
+
+	activator->mathService = malloc(sizeof(*activator->mathService));
+	activator->mathService->handle = activator->math;
+	activator->mathService->calc = (void *)mathComponent_calc;
+	bundleContext_registerService(activator->context, MATH_SERVICE_NAME, activator->mathService, NULL, &activator->registration);
+
+	activator->freqService = malloc(sizeof(*activator->freqService));
+	activator->freqService->handle = (void *)activator;
+	activator->freqService->setFrequency = (void *)setFrequency;
+	activator->freqService->resetCounter = (void *)resetCounter;
+	activator->freqService->getCounter = (void *)getCounter;
+	activator->freqService->setBenchmarkName = (void *)setBenchmarkName;
+	activator->freqService->setNrOfThreads = (void *)setNrOfThreads;
+	bundleContext_registerService(activator->context, FREQUENCY_SERVICE_NAME, activator->freqService, NULL, &activator->freqRegistration);
+
+	startThreads(activator, activator->nrOfThreads);
+
+	return status;
+}
+
+celix_status_t bundleActivator_stop(void * userData, bundle_context_pt context) {
+	struct activator * activator = userData;
+
+	printf("Stopping service registration thread\n");
+	stopThreads(activator);
+
+	//TODO deregister service & freqService
+
+	return CELIX_SUCCESS;
+}
+
+celix_status_t bundleActivator_destroy(void * userData, bundle_context_pt context) {
+	struct echoActivator * activator = userData;
+
+	//TODO free service & freqService struct
+
+	free(activator);
+
+	return CELIX_SUCCESS;
+}
+
+static int calc(int arg1, int arg2) {
+	return  arg1 * arg2 + arg2;
+}
+
+static void stopThreads(activator_t *activator) {
+	//cancel and join threads
+	if (activator->threads != NULL) {
+		for (int i = 0 ; i < activator->nrOfThreads ; i += 1) {
+			pthread_cancel(activator->threads[i]);
+			pthread_join(activator->threads[i], NULL);
+		}
+	}
+}
+
+static void startThreads(activator_t *activator, uint nrOfThreads) {
+	activator->threads = malloc(sizeof(pthread_t) * nrOfThreads);
+	for (int i = 0 ; i < nrOfThreads ; i += 1) {
+		pthread_create(&activator->threads[i], NULL, (void *)run, activator);
+	}
+	activator->nrOfThreads = nrOfThreads;
+}
+
+static void run(activator_t *activator) {
+	service_registration_pt currentReg = NULL;
+	service_registration_pt prevReg = NULL;
+	math_service_pt current = NULL;
+	math_service_pt prev = NULL;
+	while (1) {
+		pthread_testcancel(); //NOTE no clean exit still need to clear a register service
+ 		uint delayInMicroseconds =  activator->updateFrequency == 0 ? 0 : (1000 * 1000) / activator->updateFrequency;
+		if (delayInMicroseconds > 0) {
+			prevReg = currentReg;
+			prev = current;
+
+			currentReg = NULL;
+			current = registerMath(activator, &currentReg);
+
+			if (prevReg != NULL) {
+				serviceRegistration_unregister(prevReg);
+				free(prev);
+			}
+		}
+		usleep(delayInMicroseconds > 0 ? delayInMicroseconds : 1000000);
+	}
+}
+
+static math_service_pt registerMath(activator_t *activator, service_registration_pt *reg) {
+	math_service_pt serv = NULL;
+	serv = malloc(sizeof(*activator->mathService));
+	serv->handle = activator->math;
+	serv->calc = (void *)mathComponent_calc;
+	properties_pt props = properties_create();
+	if (activator->benchmarkName != NULL) { //TODO FIXME race condition
+		properties_set(props, "benchmark", activator->benchmarkName);
+	}
+	bundleContext_registerService(activator->context, MATH_SERVICE_NAME,
+			serv, props, reg);
+	activator->counter += 1;
+	return serv;
+}
+
+static void setBenchmarkName(activator_t *activator, char *benchmark) {
+	char *old = activator->benchmarkName;
+	activator->benchmarkName = strdup(benchmark);
+	free(old);
+	if (activator->updateFrequency == 0) {
+		service_registration_pt reg = NULL;
+		registerMath(activator, &reg); //TODO service will not be cleaned up !
+	}
+}
+
+static void setFrequency(activator_t *activator, uint freq) {
+	printf("Setting frequency to %i\n", freq);
+	activator->updateFrequency = freq;
+}
+
+static void setNrOfThreads(activator_t *activator, uint nrOfThreads) {
+	stopThreads(activator);
+	startThreads(activator, nrOfThreads);
+}
+
+static void resetCounter(activator_t *activator) {
+	activator->counter = 0;
+}
+
+static uint getCounter(activator_t *activator) {
+	return activator->counter;
+}

http://git-wip-us.apache.org/repos/asf/celix/blob/e0231e51/examples/locking/modified_bool_benchmark/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/examples/locking/modified_bool_benchmark/CMakeLists.txt b/examples/locking/modified_bool_benchmark/CMakeLists.txt
new file mode 100644
index 0000000..46ceb7a
--- /dev/null
+++ b/examples/locking/modified_bool_benchmark/CMakeLists.txt
@@ -0,0 +1,32 @@
+# 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.
+
+SET(BUNDLE_SYMBOLICNAME bool_benchmark)
+SET(BUNDLE_VERSION 0.0.0)
+
+bundle(modified_bool_benchmark SOURCES
+	../benchmark/public/src/benchmark_activator
+	private/src/modified_bool_benchmark 
+)
+
+include_directories(public/include)
+include_directories(../benchmark/public/include)
+include_directories("${PROJECT_SOURCE_DIR}/framework/public/include")
+include_directories("${PROJECT_SOURCE_DIR}/utils/public/include")
+include_directories("${PROJECT_SOURCE_DIR}/shell/public/include")
+target_link_libraries(modified_bool_benchmark celix_framework)
+

http://git-wip-us.apache.org/repos/asf/celix/blob/e0231e51/examples/locking/modified_bool_benchmark/private/src/modified_bool_benchmark.c
----------------------------------------------------------------------
diff --git a/examples/locking/modified_bool_benchmark/private/src/modified_bool_benchmark.c b/examples/locking/modified_bool_benchmark/private/src/modified_bool_benchmark.c
new file mode 100644
index 0000000..b482b2c
--- /dev/null
+++ b/examples/locking/modified_bool_benchmark/private/src/modified_bool_benchmark.c
@@ -0,0 +1,162 @@
+#include <stdlib.h>
+#include <pthread.h>
+#include <unistd.h>
+#include <sys/time.h>
+#include <pthread.h>
+
+#include "array_list.h"
+
+#include "benchmark.h"
+#include "math_service.h"
+
+static const char * const BENCHMARK_NAME = "MODIFIED_BIT";
+static const double SAMPLE_FACTOR = 1;
+static const useconds_t SLEEP_TIME = 10;
+
+typedef struct thread_info {
+	benchmark_pt benchmark;
+	unsigned int result;
+	struct timeval begin;
+	struct timeval end;
+	int skips;
+	bool isModified;
+    bool isUpdated;
+} thread_info_t;
+
+struct benchmark {
+    pthread_mutex_t mutex;
+    math_service_pt math;
+    int nrOfSamples;
+    int nrOfThreads;
+    thread_info_t *threads;
+};
+
+static void benchmark_thread(thread_info_t *info);
+
+celix_status_t benchmark_create(benchmark_pt *benchmark) {
+	(*benchmark) = malloc(sizeof(struct benchmark));
+	(*benchmark)->math = NULL;
+	pthread_mutex_init(&(*benchmark)->mutex, NULL);
+    return CELIX_SUCCESS;
+}
+
+celix_status_t benchmark_destroy(benchmark_pt benchmark) {
+    //free threads array
+	free(benchmark);
+    return CELIX_SUCCESS;
+}
+
+benchmark_result_t benchmark_run(benchmark_pt benchmark, int nrOfThreads, int nrOfSamples) {
+	int i;
+	pthread_t threads[nrOfThreads];
+	thread_info_t infos[nrOfThreads];
+	benchmark_result_t result;
+	unsigned long elapsedTime = 0;
+
+	benchmark->threads = infos;
+	benchmark->nrOfSamples = nrOfSamples;
+    benchmark->nrOfThreads = nrOfThreads;
+
+	result.skips =0;
+    pthread_mutex_lock(&benchmark->mutex);
+	for (i = 0 ; i < nrOfThreads ; i += 1) {
+		infos[i].benchmark = benchmark;
+		infos[i].skips = 0;
+		infos[i].result = rand();
+		infos[i].isUpdated = false;
+		infos[i].isModified = false;
+		pthread_create(&threads[i], NULL, (void *)benchmark_thread,  &infos[i]);
+	}
+    pthread_mutex_unlock(&benchmark->mutex);
+
+	for (i = 0; i < nrOfThreads ; i += 1) {
+		pthread_join(threads[i], NULL);
+		elapsedTime += ((infos[i].end.tv_sec - infos[i].begin.tv_sec) * 1000000) + (infos[i].end.tv_usec - infos[i].begin.tv_usec);
+		result.skips += infos[i].skips;
+	}
+
+	result.averageCallTimeInNanoseconds = ((double)elapsedTime * 1000) / (nrOfSamples * nrOfThreads);
+	result.callFrequencyInMhz = ((double)(nrOfSamples * nrOfThreads) / elapsedTime);
+	result.nrOfThreads = nrOfThreads;
+	result.nrOfsamples = nrOfSamples;
+
+	return result;
+}
+
+static void benchmark_thread(thread_info_t *info) {
+	int i = 0;
+
+    math_service_pt local = info->benchmark->math;
+	int nrOfSamples = info->benchmark->nrOfSamples;
+	
+	gettimeofday(&info->begin, NULL);
+	while (i < nrOfSamples) {
+		if (!info->isModified) {
+            if (local != NULL) {
+                info->result = local->calc(local->handle, info->result, i);
+            } else {
+                info->skips += 1; //should not happen
+            }
+            i += 1;
+        } else {
+			local = info->benchmark->math;
+			info->isModified = false;
+		}
+	}
+	gettimeofday(&info->end, NULL);
+
+}
+
+char * benchmark_getName(benchmark_pt benchmark) {
+	return (char *)BENCHMARK_NAME;
+}
+
+celix_status_t benchmark_addMathService(benchmark_pt benchmark, math_service_pt mathService) {
+	int i;
+
+	pthread_mutex_lock(&benchmark->mutex);
+	benchmark->math = mathService;
+	pthread_mutex_unlock(&benchmark->mutex);
+
+	//inform threads to update servicd
+	for (i = 0 ; i < benchmark->nrOfSamples ; i += 1) {
+		benchmark->threads[i].isModified = true;
+	}	
+
+	//Wait till al thread are not in a modified state, e.g. update to date mathService and not using the old service
+	for (i = 0; i < benchmark->nrOfThreads ; i += 1) {
+		if (benchmark->threads[i].isModified) {
+			usleep(SLEEP_TIME);
+		}
+	}
+
+	return CELIX_SUCCESS;
+}
+
+celix_status_t benchmark_removeMathService(benchmark_pt benchmark, math_service_pt mathService) {
+	pthread_mutex_lock(&benchmark->mutex);
+	if (benchmark->math == mathService) {
+		benchmark->math = NULL;
+	} 
+	pthread_mutex_unlock(&benchmark->mutex);
+
+	//inform threads to update servicd
+    int i;
+	for (i = 0 ; i < benchmark->nrOfThreads ; i += 1) {
+		benchmark->threads[i].isModified = true;
+	}	
+
+	//Wait till al thread are not in a modified state, e.g. update to date mathService and not using the old service
+	for (i = 0; i < benchmark->nrOfThreads ; i += 1) {
+		if (benchmark->threads[i].isModified) {
+			usleep(SLEEP_TIME);
+		}
+	}
+
+	
+	return CELIX_SUCCESS;
+}
+
+double benchmark_getSampleFactor(benchmark_pt benchmark) {
+	return SAMPLE_FACTOR;
+}

http://git-wip-us.apache.org/repos/asf/celix/blob/e0231e51/examples/locking/mutex_benchmark/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/examples/locking/mutex_benchmark/CMakeLists.txt b/examples/locking/mutex_benchmark/CMakeLists.txt
new file mode 100644
index 0000000..b822ffa
--- /dev/null
+++ b/examples/locking/mutex_benchmark/CMakeLists.txt
@@ -0,0 +1,32 @@
+# 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.
+
+SET(BUNDLE_SYMBOLICNAME mutex_benchmark)
+SET(BUNDLE_VERSION 0.0.0)
+
+bundle(mutex_benchmark SOURCES
+	../benchmark/public/src/benchmark_activator
+	private/src/mutex_benchmark 
+)
+
+include_directories(public/include)
+include_directories(../benchmark/public/include)
+include_directories("${PROJECT_SOURCE_DIR}/framework/public/include")
+include_directories("${PROJECT_SOURCE_DIR}/utils/public/include")
+include_directories("${PROJECT_SOURCE_DIR}/shell/public/include")
+target_link_libraries(mutex_benchmark celix_framework)
+

http://git-wip-us.apache.org/repos/asf/celix/blob/e0231e51/examples/locking/mutex_benchmark/private/src/mutex_benchmark.c
----------------------------------------------------------------------
diff --git a/examples/locking/mutex_benchmark/private/src/mutex_benchmark.c b/examples/locking/mutex_benchmark/private/src/mutex_benchmark.c
new file mode 100644
index 0000000..3cacfb8
--- /dev/null
+++ b/examples/locking/mutex_benchmark/private/src/mutex_benchmark.c
@@ -0,0 +1,117 @@
+/*
+ * mutex_benchmark.c
+ *
+ *  Created on: Feb 13, 2014
+ *      Author: dl436
+ */
+
+#include <stdlib.h>
+#include <pthread.h>
+#include <unistd.h>
+#include <sys/time.h>
+
+#include "benchmark.h"
+
+static const char * const BENCHMARK_NAME = "MUTEX";
+static const double SAMPLE_FACTOR = 1;
+
+struct benchmark {
+	pthread_mutex_t mutex;
+	math_service_pt math;
+};
+
+typedef struct thread_info {
+	benchmark_pt benchmark;
+	int nrOfSamples;
+	unsigned int result;
+	struct timeval begin;
+	struct timeval end;
+	int skips;
+} thread_info_t;
+
+static void benchmark_thread(thread_info_t *info);
+
+celix_status_t benchmark_create(benchmark_pt *benchmark) {
+	(*benchmark) = malloc(sizeof(struct benchmark));
+	(*benchmark)->math = NULL;
+	pthread_mutex_init(&(*benchmark)->mutex, NULL);
+	return CELIX_SUCCESS;
+}
+
+celix_status_t benchmark_destroy(benchmark_pt benchmark) {
+	free(benchmark);
+	return CELIX_SUCCESS;
+}
+
+benchmark_result_t benchmark_run(benchmark_pt benchmark, int nrOfThreads, int nrOfSamples) {
+	int i;
+	pthread_t threads[nrOfThreads];
+	thread_info_t infos[nrOfThreads];
+	benchmark_result_t result;
+	unsigned long elapsedTime = 0;
+
+	result.skips =0;
+
+	for (i = 0 ; i < nrOfThreads ; i += 1) {
+		infos[i].benchmark = benchmark;
+		infos[i].nrOfSamples = nrOfSamples;
+		infos[i].skips = 0;
+		infos[i].result = rand();
+		pthread_create(&threads[i], NULL, (void *)benchmark_thread,  &infos[i]);
+	}
+
+	for (i = 0; i < nrOfThreads ; i += 1) {
+		pthread_join(threads[i], NULL);
+		elapsedTime += ((infos[i].end.tv_sec - infos[i].begin.tv_sec) * 1000000) + (infos[i].end.tv_usec - infos[i].begin.tv_usec);
+		result.skips += infos[i].skips;
+	}
+
+	result.averageCallTimeInNanoseconds = ((double)elapsedTime * 1000) / (nrOfSamples * nrOfThreads);
+	result.callFrequencyInMhz = ((double)(nrOfSamples * nrOfThreads) / elapsedTime);
+	result.nrOfThreads = nrOfThreads;
+	result.nrOfsamples = nrOfSamples;
+
+	return result;
+}
+
+static void benchmark_thread(thread_info_t *info) {
+	int i;
+
+	gettimeofday(&info->begin, NULL);
+	for (i = 0; i < info->nrOfSamples; i += 1) {
+		pthread_mutex_lock(&info->benchmark->mutex);
+		if (info->benchmark->math != NULL) {
+			info->result = info->benchmark->math->calc(info->benchmark->math->handle, info->result, i);
+		} else {
+			info->skips += 1; //should not happen
+		}
+		pthread_mutex_unlock(&info->benchmark->mutex);
+	}
+	gettimeofday(&info->end, NULL);
+
+}
+
+char * benchmark_getName(benchmark_pt benchmark) {
+	return (char *)BENCHMARK_NAME;
+}
+
+celix_status_t benchmark_addMathService(benchmark_pt benchmark, math_service_pt mathService) {
+	pthread_mutex_lock(&benchmark->mutex);
+	benchmark->math = mathService;
+	pthread_mutex_unlock(&benchmark->mutex);
+	return CELIX_SUCCESS;
+}
+
+celix_status_t benchmark_removeMathService(benchmark_pt benchmark, math_service_pt mathService) {
+	pthread_mutex_lock(&benchmark->mutex);
+	if (benchmark->math == mathService) {
+		benchmark->math = NULL;
+	}
+	pthread_mutex_unlock(&benchmark->mutex);
+	return CELIX_SUCCESS;
+
+}
+
+double benchmark_getSampleFactor(benchmark_pt benchmark) {
+	return SAMPLE_FACTOR;
+}

http://git-wip-us.apache.org/repos/asf/celix/blob/e0231e51/examples/locking/reference_benchmark/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/examples/locking/reference_benchmark/CMakeLists.txt b/examples/locking/reference_benchmark/CMakeLists.txt
new file mode 100644
index 0000000..592bb9c
--- /dev/null
+++ b/examples/locking/reference_benchmark/CMakeLists.txt
@@ -0,0 +1,32 @@
+# 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.
+
+SET(BUNDLE_SYMBOLICNAME reference_benchmark)
+SET(BUNDLE_VERSION 0.0.0)
+
+bundle(reference_benchmark SOURCES
+	../benchmark/public/src/benchmark_activator
+	private/src/reference_benchmark 
+)
+
+include_directories(public/include)
+include_directories(../benchmark/public/include)
+include_directories("${PROJECT_SOURCE_DIR}/framework/public/include")
+include_directories("${PROJECT_SOURCE_DIR}/utils/public/include")
+include_directories("${PROJECT_SOURCE_DIR}/shell/public/include")
+target_link_libraries(reference_benchmark celix_framework)
+

http://git-wip-us.apache.org/repos/asf/celix/blob/e0231e51/examples/locking/reference_benchmark/private/src/reference_benchmark.c
----------------------------------------------------------------------
diff --git a/examples/locking/reference_benchmark/private/src/reference_benchmark.c b/examples/locking/reference_benchmark/private/src/reference_benchmark.c
new file mode 100644
index 0000000..f4bb93f
--- /dev/null
+++ b/examples/locking/reference_benchmark/private/src/reference_benchmark.c
@@ -0,0 +1,116 @@
+/*
+ * mutex_benchmark.c
+ *
+ *  Created on: Feb 13, 2014
+ *      Author: dl436
+ */
+
+#include <stdlib.h>
+#include <pthread.h>
+#include <unistd.h>
+#include <sys/time.h>
+
+#include "benchmark.h"
+
+static const char * const BENCHMARK_NAME = "REFERENCE";
+static const double SAMPLE_FACTOR = 100;
+
+typedef struct thread_info {
+	benchmark_pt benchmark;
+	int nrOfSamples;
+	unsigned int result;
+	struct timeval begin;
+	struct timeval end;
+	int skips;
+} thread_info_t;
+
+static void benchmark_thread(thread_info_t *info);
+static int benchmark_calc(int arg1, int arg2);
+
+celix_status_t benchmark_create(benchmark_pt *benchmark) {
+	//do nothing
+	return CELIX_SUCCESS;
+}
+
+celix_status_t benchmark_destroy(benchmark_pt benchmark) {
+	//do nothing
+	return CELIX_SUCCESS;
+}
+
+benchmark_result_t benchmark_run(benchmark_pt benchmark, int nrOfThreads, int nrOfSamples) {
+	int i;
+	pthread_t threads[nrOfThreads];
+	thread_info_t infos[nrOfThreads];
+	benchmark_result_t result;
+	unsigned long elapsedTime = 0;
+
+	result.skips =0;
+
+	for (i = 0 ; i < nrOfThreads ; i += 1) {
+		infos[i].benchmark = benchmark;
+		infos[i].nrOfSamples = nrOfSamples;
+		infos[i].skips = 0;
+		infos[i].result = rand();
+		pthread_create(&threads[i], NULL, (void *)benchmark_thread,  &infos[i]);
+	}
+
+	for (i = 0; i < nrOfThreads ; i += 1) {
+		pthread_join(threads[i], NULL);
+		elapsedTime += ((infos[i].end.tv_sec - infos[i].begin.tv_sec) * 1000000) + (infos[i].end.tv_usec - infos[i].begin.tv_usec);
+		result.skips += infos[i].skips;
+	}
+
+	result.averageCallTimeInNanoseconds = elapsedTime;
+	result.averageCallTimeInNanoseconds *= 1000;
+	result.averageCallTimeInNanoseconds /= nrOfSamples;
+	result.averageCallTimeInNanoseconds /= nrOfThreads;
+	result.callFrequencyInMhz = ((double)(nrOfSamples * nrOfThreads) / elapsedTime);
+	result.nrOfThreads = nrOfThreads;
+	result.nrOfsamples = nrOfSamples;
+
+	return result;
+}
+
+static void benchmark_thread(thread_info_t *info) {
+	int i;
+
+	int result = info->result;
+	struct timeval *begin = &info->begin;
+	struct timeval *end = &info->end;
+	int nrOFSamples = info->nrOfSamples;
+
+
+	gettimeofday(begin, NULL);
+	for (i = 0; i < nrOFSamples; i += 1) {
+		result = benchmark_calc(result, i);
+	}
+	gettimeofday(end, NULL);
+
+	info->result = result;
+}
+
+char * benchmark_getName(benchmark_pt benchmark) {
+	return (char *)BENCHMARK_NAME;
+}
+
+celix_status_t benchmark_addMathService(benchmark_pt benchmark, math_service_pt mathService) {
+	//ignore service is not used
+	return CELIX_SUCCESS;
+}
+
+celix_status_t benchmark_removeMathService(benchmark_pt benchmark, math_service_pt mathService) {
+	//ignore service is not used
+	return CELIX_SUCCESS;
+
+}
+
+/*
+ * Same implementation as the math_service. This function is used a reference.
+ */
+static int benchmark_calc(int arg1, int arg2) {
+	return  arg1 * arg2 + arg2;
+}
+
+double benchmark_getSampleFactor(benchmark_pt benchmark) {
+	return SAMPLE_FACTOR;
+}

http://git-wip-us.apache.org/repos/asf/celix/blob/e0231e51/examples/locking/start_stop_benchmark/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/examples/locking/start_stop_benchmark/CMakeLists.txt b/examples/locking/start_stop_benchmark/CMakeLists.txt
new file mode 100644
index 0000000..bca651e
--- /dev/null
+++ b/examples/locking/start_stop_benchmark/CMakeLists.txt
@@ -0,0 +1,32 @@
+# 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.
+
+SET(BUNDLE_SYMBOLICNAME stop_benchmark)
+SET(BUNDLE_VERSION 0.0.0)
+
+bundle(start_stop_benchmark SOURCES
+	../benchmark/public/src/benchmark_activator
+	private/src/start_stop_benchmark 
+)
+
+include_directories(public/include)
+include_directories(../benchmark/public/include)
+include_directories("${PROJECT_SOURCE_DIR}/framework/public/include")
+include_directories("${PROJECT_SOURCE_DIR}/utils/public/include")
+include_directories("${PROJECT_SOURCE_DIR}/shell/public/include")
+target_link_libraries(start_stop_benchmark celix_framework)
+

http://git-wip-us.apache.org/repos/asf/celix/blob/e0231e51/examples/locking/start_stop_benchmark/private/src/start_stop_benchmark.c
----------------------------------------------------------------------
diff --git a/examples/locking/start_stop_benchmark/private/src/start_stop_benchmark.c b/examples/locking/start_stop_benchmark/private/src/start_stop_benchmark.c
new file mode 100644
index 0000000..1d445c5
--- /dev/null
+++ b/examples/locking/start_stop_benchmark/private/src/start_stop_benchmark.c
@@ -0,0 +1,189 @@
+/*
+ * mutex_benchmark.c
+ *
+ *  Created on: Feb 13, 2014
+ *      Author: dl436
+ */
+
+#include <stdlib.h>
+#include <pthread.h>
+#include <unistd.h>
+#include <sys/time.h>
+#include <stdio.h>
+
+#include "benchmark.h"
+
+static const char * const BENCHMARK_NAME = "INTR_CONT";
+static const double SAMPLE_FACTOR = 100;
+static const __useconds_t WAIT_TIME = 1; //100 * 1000;
+
+typedef enum benchmark_state {
+	BENCHMARK_STATE_INTERRUPTED,
+	BENCHMARK_STATE_RUNNING
+} benchmark_state_t;
+
+struct benchmark {
+	int nrOfThreads;
+	pthread_mutex_t mutex; //write protect for state
+	math_service_pt math;
+	benchmark_state_t state;
+	int threadsRunning;
+};
+
+typedef struct thread_info {
+	benchmark_pt benchmark;
+	int nrOfSamples;
+	unsigned int result;
+	struct timeval begin;
+	struct timeval end;
+	int skips;
+} thread_info_t;
+
+static void benchmark_thread(thread_info_t *info);
+static void benchmark_runSamples(thread_info_t *info, int *i, volatile benchmark_state_t *state);
+static void benchmark_interrupt(benchmark_pt benchmark);
+static void benchmark_continue(benchmark_pt benchmark);
+
+celix_status_t benchmark_create(benchmark_pt *benchmark) {
+	(*benchmark) = malloc(sizeof(struct benchmark));
+	(*benchmark)->math = NULL;
+	(*benchmark)->state = BENCHMARK_STATE_INTERRUPTED;
+	(*benchmark)->nrOfThreads = 0;
+	(*benchmark)->threadsRunning = 0;
+
+	pthread_mutex_init(&(*benchmark)->mutex, NULL);
+
+	return CELIX_SUCCESS;
+}
+
+celix_status_t benchmark_destroy(benchmark_pt benchmark) {
+	free(benchmark);
+
+	return CELIX_SUCCESS;
+}
+
+benchmark_result_t benchmark_run(benchmark_pt benchmark, int nrOfThreads, int nrOfSamples) {
+	int i;
+	pthread_t threads[nrOfThreads];
+	thread_info_t infos[nrOfThreads];
+	int isThreadRunning[nrOfThreads];
+	benchmark_result_t result;
+	unsigned long elapsedTime = 0;
+	result.skips =0;
+
+	for (i = 0 ; i < nrOfThreads ; i += 1) {
+		infos[i].benchmark = benchmark;
+		infos[i].nrOfSamples = nrOfSamples;
+		infos[i].skips = 0;
+		infos[i].result = rand();
+		pthread_create(&threads[i], NULL, (void *)benchmark_thread,  &infos[i]);
+	}
+
+	benchmark->nrOfThreads = nrOfThreads;
+
+	for (i = 0; i < nrOfThreads ; i += 1) {
+		pthread_join(threads[i], NULL);
+		elapsedTime += ((infos[i].end.tv_sec - infos[i].begin.tv_sec) * 1000000) + (infos[i].end.tv_usec - infos[i].begin.tv_usec);
+		result.skips += infos[i].skips;
+	}
+
+	benchmark->nrOfThreads = 0;
+
+	result.averageCallTimeInNanoseconds = elapsedTime;
+	result.averageCallTimeInNanoseconds *= 1000;
+	result.averageCallTimeInNanoseconds /= nrOfSamples;
+	result.averageCallTimeInNanoseconds /= nrOfThreads;
+	result.callFrequencyInMhz = ((double)(nrOfSamples * nrOfThreads) / elapsedTime);
+	result.nrOfThreads = nrOfThreads;
+	result.nrOfsamples = nrOfSamples;
+
+	return result;
+}
+
+static void benchmark_thread(thread_info_t *info) {
+	int i = 0;
+
+	gettimeofday(&info->begin, NULL);
+	while (i < info->nrOfSamples) {
+		if (info->benchmark->state == BENCHMARK_STATE_RUNNING ) {
+			//TODO race condition?? or not because of the mutex on changing the state
+			__sync_add_and_fetch(&info->benchmark->threadsRunning, 1);
+			benchmark_runSamples(info, &i, &info->benchmark->state);
+			__sync_sub_and_fetch(&info->benchmark->threadsRunning, 1);
+		} else {
+			usleep(WAIT_TIME);
+		}
+	}
+	gettimeofday(&info->end, NULL);
+
+}
+
+static void benchmark_runSamples(thread_info_t *info, int *i, volatile benchmark_state_t *state) {
+	int nrOfSamples = info->nrOfSamples;
+	unsigned int result = info->result;
+	math_service_pt math = info->benchmark->math;
+
+	for (; *i < nrOfSamples && *state == BENCHMARK_STATE_RUNNING; *i += 1) {
+		result = math->calc(math->handle, result, *i);
+	}
+
+	info->result = result;
+}
+
+char * benchmark_getName(benchmark_pt benchmark) {
+	return (char *)BENCHMARK_NAME;
+}
+
+static void benchmark_continue(benchmark_pt benchmark) {
+	benchmark->state = BENCHMARK_STATE_RUNNING;
+	unsigned long waitTime = 0;
+	while (benchmark->threadsRunning < benchmark->nrOfThreads) {
+		usleep(WAIT_TIME);
+		waitTime += WAIT_TIME;
+		if (waitTime > 1000 * 1000 * 2) {
+			printf("still waiting to stop, running threads are %i\n",
+					benchmark->threadsRunning);
+		}
+	}
+}
+
+static void benchmark_interrupt(benchmark_pt benchmark) {
+	int i = 0;
+	unsigned long waitTime = 0;
+	if (benchmark->state == BENCHMARK_STATE_RUNNING) {
+		benchmark->state = BENCHMARK_STATE_INTERRUPTED;
+		while (benchmark->threadsRunning > 0) {
+			usleep(WAIT_TIME);
+			waitTime += WAIT_TIME;
+			if (waitTime > 1000 * 1000 * 2) {
+				printf("still waiting to stop, running threads are %i\n",
+						benchmark->threadsRunning);
+			}
+		}
+	}
+}
+
+celix_status_t benchmark_addMathService(benchmark_pt benchmark, math_service_pt mathService) {
+	pthread_mutex_lock(&benchmark->mutex);
+	benchmark_interrupt(benchmark);
+	benchmark->math = mathService;
+	benchmark_continue(benchmark);
+	pthread_mutex_unlock(&benchmark->mutex);
+	return CELIX_SUCCESS;
+}
+
+celix_status_t benchmark_removeMathService(benchmark_pt benchmark, math_service_pt mathService) {
+	pthread_mutex_lock(&benchmark->mutex);
+	if (benchmark->math == mathService) {
+		benchmark_interrupt(benchmark);
+		benchmark->math = NULL;
+		benchmark_continue(benchmark);
+	}
+	pthread_mutex_unlock(&benchmark->mutex);
+	return CELIX_SUCCESS;
+
+}
+
+double benchmark_getSampleFactor(benchmark_pt benchmark) {
+	return SAMPLE_FACTOR;
+}

http://git-wip-us.apache.org/repos/asf/celix/blob/e0231e51/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 b297c14..114eae1 100644
--- a/framework/private/include/service_reference_private.h
+++ b/framework/private/include/service_reference_private.h
@@ -33,12 +33,17 @@
 struct serviceReference {
 	bundle_pt bundle;
 	struct serviceRegistration * registration;
+
+	size_t refCount;
+    celix_thread_mutex_t mutex; //protects refCount
 };
 
 celix_status_t serviceReference_create(bundle_pt bundle, service_registration_pt registration, service_reference_pt *reference);
-celix_status_t serviceReference_destroy(service_reference_pt *reference);
+
+void serviceReference_retain(service_reference_pt ref);
+void serviceReference_release(service_reference_pt ref);
 
 celix_status_t serviceReference_invalidate(service_reference_pt reference);
-celix_status_t serviceRefernce_isValid(service_reference_pt reference, bool *result);
+celix_status_t serviceReference_isValid(service_reference_pt reference, bool *result);
 
 #endif /* SERVICE_REFERENCE_PRIVATE_H_ */

http://git-wip-us.apache.org/repos/asf/celix/blob/e0231e51/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 8f31a14..081f996 100644
--- a/framework/private/include/service_registration_private.h
+++ b/framework/private/include/service_registration_private.h
@@ -51,11 +51,15 @@ struct serviceRegistration {
 
 	struct service *services;
 	int nrOfServices;
+
+	size_t refCount; //protected by mutex
 };
 
 service_registration_pt serviceRegistration_create(service_registry_pt registry, bundle_pt bundle, char * serviceName, long serviceId, void * serviceObject, properties_pt dictionary);
 service_registration_pt serviceRegistration_createServiceFactory(service_registry_pt registry, bundle_pt bundle, char * serviceName, long serviceId, void * serviceObject, properties_pt dictionary);
-celix_status_t serviceRegistration_destroy(service_registration_pt registration);
+
+void serviceRegistration_retain(service_registration_pt registration);
+void serviceRegistration_release(service_registration_pt registration);
 
 bool serviceRegistration_isValid(service_registration_pt registration);
 void serviceRegistration_invalidate(service_registration_pt registration);

http://git-wip-us.apache.org/repos/asf/celix/blob/e0231e51/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 7bda186..d89f28e 100644
--- a/framework/private/include/service_registry_private.h
+++ b/framework/private/include/service_registry_private.h
@@ -50,6 +50,7 @@ struct usageCount {
 	unsigned int count;
 	service_reference_pt reference;
 	void * service;
+	service_registration_pt registration;
 };
 
 typedef struct usageCount * usage_count_pt;

http://git-wip-us.apache.org/repos/asf/celix/blob/e0231e51/framework/private/src/properties.c
----------------------------------------------------------------------
diff --git a/framework/private/src/properties.c b/framework/private/src/properties.c
index 14455c4..271eed1 100644
--- a/framework/private/src/properties.c
+++ b/framework/private/src/properties.c
@@ -180,6 +180,28 @@ void properties_store(properties_pt properties, char * filename, char * header)
 	}
 }
 
+celix_status_t properties_copy(properties_pt properties, properties_pt *out) {
+	celix_status_t status = CELIX_SUCCESS;
+	properties_pt copy = properties_create();
+
+	if (copy != NULL) {
+		hash_map_iterator_pt iter = hashMapIterator_create(properties);
+		while (hashMapIterator_hasNext(iter)) {
+			hash_map_entry_pt entry = hashMapIterator_nextEntry(iter);
+			char *key = hashMapEntry_getKey(entry);
+			char *value = hashMapEntry_getValue(entry);
+			properties_set(copy, key, value);
+		}
+		hashMapIterator_destroy(iter);
+	} else {
+		status = CELIX_ENOMEM;
+	}
+
+	if (status == CELIX_SUCCESS) {
+		*out = copy;
+	}
+}
+
 char * properties_get(properties_pt properties, char * key) {
 	return hashMap_get(properties, key);
 }

http://git-wip-us.apache.org/repos/asf/celix/blob/e0231e51/framework/private/src/service_reference.c
----------------------------------------------------------------------
diff --git a/framework/private/src/service_reference.c b/framework/private/src/service_reference.c
index 528b4be..24fdc99 100644
--- a/framework/private/src/service_reference.c
+++ b/framework/private/src/service_reference.c
@@ -28,6 +28,7 @@
 #include <constants.h>
 #include <stdint.h>
 #include <utils.h>
+#include <assert.h>
 
 #include "service_reference.h"
 
@@ -39,29 +40,53 @@
 #include "bundle.h"
 #include "celix_log.h"
 
-celix_status_t serviceReference_create(bundle_pt bundle, service_registration_pt registration, service_reference_pt *reference) {
+static void serviceReference_destroy(service_reference_pt);
+
+celix_status_t serviceReference_create(bundle_pt bundle, service_registration_pt registration, service_reference_pt *out) {
 	celix_status_t status = CELIX_SUCCESS;
 
-	*reference = malloc(sizeof(**reference));
-	if (!*reference) {
+	service_reference_pt ref = calloc(1, sizeof(*ref));
+	if (!ref) {
 		status = CELIX_ENOMEM;
 	} else {
-
-		(*reference)->bundle = bundle;
-		(*reference)->registration = registration;
+		ref->bundle = bundle;
+		ref->registration = registration;
+		celixThreadMutex_create(&ref->mutex, NULL);
+		ref->refCount = 1;
 	}
 
-	framework_logIfError(logger, status, NULL, "Cannot create service reference");
+	if (status == CELIX_SUCCESS) {
+		*out = ref;
+	} else {
+		framework_logIfError(logger, status, NULL, "Cannot create service reference");
+	}
 
 	return status;
 }
 
-celix_status_t serviceReference_destroy(service_reference_pt *reference) {
-	(*reference)->bundle = NULL;
-	(*reference)->registration = NULL;
-	free(*reference);
-	*reference = NULL;
-	return CELIX_SUCCESS;
+void serviceReference_retain(service_reference_pt ref) {
+    celixThreadMutex_lock(&ref->mutex);
+    ref->refCount += 1;
+    celixThreadMutex_unlock(&ref->mutex);
+}
+
+void serviceReference_release(service_reference_pt ref) {
+    celixThreadMutex_lock(&ref->mutex);
+    assert(ref->refCount > 0);
+    ref->refCount -= 1;
+    if (ref->refCount == 0) {
+        serviceReference_destroy(ref);
+    } else {
+        celixThreadMutex_unlock(&ref->mutex);
+    }
+}
+
+static void serviceReference_destroy(service_reference_pt ref) {
+	assert(ref->refCount == 0);
+    celixThreadMutex_destroy(&ref->mutex);
+	ref->bundle = NULL;
+	ref->registration = NULL;
+	free(ref);
 }
 
 celix_status_t serviceReference_getBundle(service_reference_pt reference, bundle_pt *bundle) {
@@ -109,7 +134,7 @@ celix_status_t serviceReference_invalidate(service_reference_pt reference) {
 	return CELIX_SUCCESS;
 }
 
-celix_status_t serviceRefernce_isValid(service_reference_pt reference, bool *result) {
+celix_status_t serviceReference_isValid(service_reference_pt reference, bool *result) {
 	(*result) = reference->registration != NULL;
 	return CELIX_SUCCESS;
 }
@@ -117,22 +142,8 @@ celix_status_t serviceRefernce_isValid(service_reference_pt reference, bool *res
 bool serviceReference_isAssignableTo(service_reference_pt reference, bundle_pt requester, char * serviceName) {
 	bool allow = true;
 
-	bundle_pt provider = reference->bundle;
-	if (requester == provider) {
-		return allow;
-	}
-//	wire_pt providerWire = module_getWire(bundle_getCurrentModule(provider), serviceName);
-//	wire_pt requesterWire = module_getWire(bundle_getCurrentModule(requester), serviceName);
-//
-//	if (providerWire == NULL && requesterWire != NULL) {
-//		allow = (bundle_getCurrentModule(provider) == wire_getExporter(requesterWire));
-//	} else if (providerWire != NULL && requesterWire != NULL) {
-//		allow = (wire_getExporter(providerWire) == wire_getExporter(requesterWire));
-//	} else if (providerWire != NULL && requesterWire == NULL) {
-//		allow = (wire_getExporter(providerWire) == bundle_getCurrentModule(requester));
-//	} else {
-//		allow = false;
-//	}
+	/*NOTE for now always true. It would be nice to be able to do somechecks if the services are really assignable.
+	 */
 
 	return allow;
 }


[14/38] celix git commit: CELIX-289: fix warnings

Posted by pn...@apache.org.
CELIX-289: fix warnings


Project: http://git-wip-us.apache.org/repos/asf/celix/repo
Commit: http://git-wip-us.apache.org/repos/asf/celix/commit/37720bd6
Tree: http://git-wip-us.apache.org/repos/asf/celix/tree/37720bd6
Diff: http://git-wip-us.apache.org/repos/asf/celix/diff/37720bd6

Branch: refs/heads/develop
Commit: 37720bd6d904aff6504a5fc5ab19e57eba3b8bf5
Parents: f4aabbe
Author: Bjoern Petri <bp...@apache.org>
Authored: Wed Nov 11 22:34:33 2015 +0100
Committer: Pepijn Noltes <pe...@gmail.com>
Committed: Thu Nov 12 17:40:27 2015 +0100

----------------------------------------------------------------------
 utils/private/test/celix_threads_test.cpp | 1 +
 utils/private/test/hash_map_test.cpp      | 8 ++++----
 2 files changed, 5 insertions(+), 4 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/celix/blob/37720bd6/utils/private/test/celix_threads_test.cpp
----------------------------------------------------------------------
diff --git a/utils/private/test/celix_threads_test.cpp b/utils/private/test/celix_threads_test.cpp
index 29e4475..620b42b 100644
--- a/utils/private/test/celix_threads_test.cpp
+++ b/utils/private/test/celix_threads_test.cpp
@@ -288,6 +288,7 @@ static void * thread_test_func_exit(void *) {
 	*pi = 666;
 
 	celixThread_exit(pi);
+	return NULL;
 }
 
 static void * thread_test_func_detach(void *) {

http://git-wip-us.apache.org/repos/asf/celix/blob/37720bd6/utils/private/test/hash_map_test.cpp
----------------------------------------------------------------------
diff --git a/utils/private/test/hash_map_test.cpp b/utils/private/test/hash_map_test.cpp
index 024655d..2051942 100644
--- a/utils/private/test/hash_map_test.cpp
+++ b/utils/private/test/hash_map_test.cpp
@@ -167,10 +167,10 @@ TEST(hash_map, create){
 	CHECK(map != NULL);
 	LONGS_EQUAL(0, map->size);
 	// This fails on windows due to dllimport providing a proxy for exported functions.
-	CHECK_EQUAL(hashMap_equals, map->equalsKey);
-	CHECK_EQUAL(hashMap_equals, map->equalsValue);
-	CHECK_EQUAL(hashMap_hashCode, map->hashKey);
-	CHECK_EQUAL(hashMap_hashCode, map->hashValue);
+	CHECK_EQUAL(&hashMap_equals, map->equalsKey);
+	CHECK_EQUAL(&hashMap_equals, map->equalsValue);
+	CHECK_EQUAL(&hashMap_hashCode, map->hashKey);
+	CHECK_EQUAL(&hashMap_hashCode, map->hashValue);
 }
 
 TEST(hash_map, size){


[30/38] celix git commit: CELIX-272: Fix mem leak in rsa dfi

Posted by pn...@apache.org.
CELIX-272: Fix mem leak in rsa dfi


Project: http://git-wip-us.apache.org/repos/asf/celix/repo
Commit: http://git-wip-us.apache.org/repos/asf/celix/commit/d0dbdb38
Tree: http://git-wip-us.apache.org/repos/asf/celix/tree/d0dbdb38
Diff: http://git-wip-us.apache.org/repos/asf/celix/diff/d0dbdb38

Branch: refs/heads/develop
Commit: d0dbdb38d30f5092fb06d585f206755712471de4
Parents: 0a177d9
Author: Pepijn Noltes <pe...@gmail.com>
Authored: Mon Nov 16 21:16:10 2015 +0100
Committer: Pepijn Noltes <pe...@gmail.com>
Committed: Mon Nov 16 21:16:10 2015 +0100

----------------------------------------------------------------------
 .../rsa/private/src/remote_service_admin_dfi.c                  | 5 +----
 1 file changed, 1 insertion(+), 4 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/celix/blob/d0dbdb38/remote_services/remote_service_admin_dfi/rsa/private/src/remote_service_admin_dfi.c
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_dfi/rsa/private/src/remote_service_admin_dfi.c b/remote_services/remote_service_admin_dfi/rsa/private/src/remote_service_admin_dfi.c
index fc0303b..87a494a 100644
--- a/remote_services/remote_service_admin_dfi/rsa/private/src/remote_service_admin_dfi.c
+++ b/remote_services/remote_service_admin_dfi/rsa/private/src/remote_service_admin_dfi.c
@@ -388,10 +388,7 @@ celix_status_t remoteServiceAdmin_exportService(remote_service_admin_pt admin, c
             bundleContext_ungetServiceReference(admin->context, arrayList_get(references, i));
         }
     }
-
-    if(references != NULL){
-        arrayList_destroy(references);
-    }
+    arrayList_destroy(references);
 
     if (reference == NULL) {
         logHelper_log(admin->loghelper, OSGI_LOGSERVICE_ERROR, "ERROR: expected a reference for service id %s.", serviceId);


[08/38] celix git commit: CELIX-272: Fix some bc_ungetServiceRefernce issues.

Posted by pn...@apache.org.
CELIX-272: Fix some bc_ungetServiceRefernce issues.


Project: http://git-wip-us.apache.org/repos/asf/celix/repo
Commit: http://git-wip-us.apache.org/repos/asf/celix/commit/07d0dfe6
Tree: http://git-wip-us.apache.org/repos/asf/celix/tree/07d0dfe6
Diff: http://git-wip-us.apache.org/repos/asf/celix/diff/07d0dfe6

Branch: refs/heads/develop
Commit: 07d0dfe65fcba3df5355d0a64c8c1a2fc1228ca7
Parents: df56860
Author: Pepijn Noltes <pe...@gmail.com>
Authored: Wed Nov 11 17:17:18 2015 +0100
Committer: Pepijn Noltes <pe...@gmail.com>
Committed: Wed Nov 11 17:17:18 2015 +0100

----------------------------------------------------------------------
 .../private/src/dm_shell_list_command.c         |  2 +-
 .../private/include/service_reference_private.h | 10 ++-
 .../include/service_registration_private.h      |  4 +-
 framework/private/src/service_reference.c       | 53 ++++++++++-
 framework/private/src/service_registration.c    | 94 ++++++++++++--------
 framework/private/src/service_registry.c        | 29 ++++--
 .../private/src/calculator_endpoint_activator.c |  2 +-
 .../private/src/calculator_activator.c          | 12 +--
 .../rsa/private/src/export_registration_dfi.c   |  3 +
 .../rsa/private/src/remote_service_admin_dfi.c  | 10 ++-
 .../rsa_tst/rsa_tests.cpp                       |  6 ++
 11 files changed, 162 insertions(+), 63 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/celix/blob/07d0dfe6/dependency_manager/private/src/dm_shell_list_command.c
----------------------------------------------------------------------
diff --git a/dependency_manager/private/src/dm_shell_list_command.c b/dependency_manager/private/src/dm_shell_list_command.c
index fd7c5d9..ed2c5f0 100644
--- a/dependency_manager/private/src/dm_shell_list_command.c
+++ b/dependency_manager/private/src/dm_shell_list_command.c
@@ -43,7 +43,7 @@ void dmListCommand_execute(bundle_context_pt context, char * line, FILE *out, FI
     array_list_pt servRefs = NULL;
     int i;
     bundleContext_getServiceReferences(context, DM_INFO_SERVICE_NAME ,NULL, &servRefs);
-    char *term = getenv("TERM");
+    char *term = secure_getenv("TERM");
     bool colors = false;
     if (strcmp("xterm-256color", term) == 0) {
         colors = true;

http://git-wip-us.apache.org/repos/asf/celix/blob/07d0dfe6/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 2ac4ee5..7eea45e 100644
--- a/framework/private/include/service_reference_private.h
+++ b/framework/private/include/service_reference_private.h
@@ -34,6 +34,7 @@ struct serviceReference {
 	bundle_pt referenceOwner;
 	struct serviceRegistration * registration;
     bundle_pt registrationBundle;
+    void *service;
 
 	size_t refCount;
     size_t usageCount;
@@ -46,8 +47,8 @@ celix_status_t serviceReference_create(bundle_pt referenceOwner, service_registr
 celix_status_t serviceReference_retain(service_reference_pt ref);
 celix_status_t serviceReference_release(service_reference_pt ref, bool *destroyed);
 
-celix_status_t serviceReference_increaseUsage(service_reference_pt ref);
-celix_status_t serviceReference_decreaseUsage(service_reference_pt ref);
+celix_status_t serviceReference_increaseUsage(service_reference_pt ref, size_t *updatedCount);
+celix_status_t serviceReference_decreaseUsage(service_reference_pt ref, size_t *updatedCount);
 
 celix_status_t serviceReference_invalidate(service_reference_pt reference);
 celix_status_t serviceReference_isValid(service_reference_pt reference, bool *result);
@@ -55,4 +56,9 @@ celix_status_t serviceReference_isValid(service_reference_pt reference, bool *re
 celix_status_t serviceReference_getUsageCount(service_reference_pt reference, size_t *count);
 celix_status_t serviceReference_getReferenceCount(service_reference_pt reference, size_t *count);
 
+celix_status_t serviceReference_setService(service_reference_pt ref, void *service);
+celix_status_t serviceReference_getService(service_reference_pt reference, void **service);
+
+
+
 #endif /* SERVICE_REFERENCE_PRIVATE_H_ */

http://git-wip-us.apache.org/repos/asf/celix/blob/07d0dfe6/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 081f996..1b48887 100644
--- a/framework/private/include/service_registration_private.h
+++ b/framework/private/include/service_registration_private.h
@@ -43,7 +43,6 @@ struct serviceRegistration {
 	void * svcObj;
 	long serviceId;
 
-	celix_thread_mutex_t mutex;
 	bool isUnregistering;
 
 	bool isServiceFactory;
@@ -53,6 +52,8 @@ struct serviceRegistration {
 	int nrOfServices;
 
 	size_t refCount; //protected by mutex
+
+	celix_thread_rwlock_t lock;
 };
 
 service_registration_pt serviceRegistration_create(service_registry_pt registry, bundle_pt bundle, char * serviceName, long serviceId, void * serviceObject, properties_pt dictionary);
@@ -67,7 +68,6 @@ void serviceRegistration_invalidate(service_registration_pt registration);
 celix_status_t serviceRegistration_getService(service_registration_pt registration, bundle_pt bundle, void **service);
 celix_status_t serviceRegistration_ungetService(service_registration_pt registration, bundle_pt bundle, void **service);
 
-celix_status_t serviceRegistration_getRegistry(service_registration_pt registration, service_registry_pt *registry);
 celix_status_t serviceRegistration_getBundle(service_registration_pt registration, bundle_pt *bundle);
 celix_status_t serviceRegistration_getServiceName(service_registration_pt registration, char **serviceName);
 

http://git-wip-us.apache.org/repos/asf/celix/blob/07d0dfe6/framework/private/src/service_reference.c
----------------------------------------------------------------------
diff --git a/framework/private/src/service_reference.c b/framework/private/src/service_reference.c
index 73e9778..333339e 100644
--- a/framework/private/src/service_reference.c
+++ b/framework/private/src/service_reference.c
@@ -43,7 +43,7 @@
 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(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));
@@ -53,6 +53,7 @@ celix_status_t serviceReference_create(bundle_pt referenceOwner, service_registr
         serviceRegistration_retain(registration);
 		ref->referenceOwner = referenceOwner;
 		ref->registration = registration;
+        ref->service = NULL;
         serviceRegistration_getBundle(registration, &ref->registrationBundle);
 		celixThreadRwlock_create(&ref->lock, NULL);
 		ref->refCount = 1;
@@ -76,6 +77,23 @@ celix_status_t serviceReference_retain(service_reference_pt ref) {
 }
 
 celix_status_t serviceReference_release(service_reference_pt ref, bool *out) {
+    celixThreadRwlock_writeLock(&ref->lock);
+    if (ref->refCount > 0) {
+        ref->refCount -= 1;
+    } else {
+        fw_log(logger, OSGI_FRAMEWORK_LOG_ERROR, "serviceReference_release error serv reference count already at 0\n");
+    }
+
+    if (out) {
+        *out = ref->refCount == 0;
+    }
+
+    celixThreadRwlock_unlock(&ref->lock);
+    return CELIX_SUCCESS;
+}
+
+/* TODO enable, for now use a leak version to prevent to much errors
+celix_status_t serviceReference_release(service_reference_pt ref, bool *out) {
     bool destroyed = false;
     celixThreadRwlock_writeLock(&ref->lock);
     assert(ref->refCount > 0);
@@ -91,17 +109,23 @@ celix_status_t serviceReference_release(service_reference_pt ref, bool *out) {
         *out = destroyed;
     }
     return CELIX_SUCCESS;
-}
+}*/
 
-celix_status_t serviceReference_increaseUsage(service_reference_pt ref) {
+celix_status_t serviceReference_increaseUsage(service_reference_pt ref, size_t *out) {
+    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) {
+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);
@@ -109,7 +133,12 @@ celix_status_t serviceReference_decreaseUsage(service_reference_pt ref) {
     } else {
         ref->usageCount -= 1;
     }
+    localCount = ref->usageCount;
     celixThreadRwlock_unlock(&ref->lock);
+
+    if (out) {
+        *out = localCount;
+    }
     return status;
 }
 
@@ -134,6 +163,22 @@ celix_status_t serviceReference_getReferenceCount(service_reference_pt ref, size
     return status;
 }
 
+celix_status_t serviceReference_getService(service_reference_pt ref, void **service) {
+    celix_status_t status = CELIX_SUCCESS;
+    celixThreadRwlock_readLock(&ref->lock);
+    *service = ref->service;
+    celixThreadRwlock_unlock(&ref->lock);
+    return status;
+}
+
+celix_status_t serviceReference_setService(service_reference_pt ref, 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);

http://git-wip-us.apache.org/repos/asf/celix/blob/07d0dfe6/framework/private/src/service_registration.c
----------------------------------------------------------------------
diff --git a/framework/private/src/service_registration.c b/framework/private/src/service_registration.c
index 3bd9ddd..f9c2ec2 100644
--- a/framework/private/src/service_registration.c
+++ b/framework/private/src/service_registration.c
@@ -75,7 +75,7 @@ static celix_status_t serviceRegistration_createInternal(service_registry_pt reg
 		}
 
 		reg->isUnregistering = false;
-		celixThreadMutex_create(&reg->mutex, NULL);
+        celixThreadRwlock_create(&reg->lock, NULL);
 
 		serviceRegistration_initializeProperties(reg, dictionary);
     } else {
@@ -90,19 +90,19 @@ static celix_status_t serviceRegistration_createInternal(service_registry_pt reg
 }
 
 void serviceRegistration_retain(service_registration_pt registration) {
-	celixThreadMutex_lock(&registration->mutex);
+	celixThreadRwlock_writeLock(&registration->lock);
 	registration->refCount += 1;
-	celixThreadMutex_unlock(&registration->mutex);
+    celixThreadRwlock_unlock(&registration->lock);
 }
 
 void serviceRegistration_release(service_registration_pt registration) {
-	celixThreadMutex_lock(&registration->mutex);
-	assert(registration->refCount > 0);
+    celixThreadRwlock_writeLock(&registration->lock);
+    assert(registration->refCount > 0);
 	registration->refCount -= 1;
 	if (registration->refCount == 0) {
 		serviceRegistration_destroy(registration);
 	} else {
-		celixThreadMutex_unlock(&registration->mutex);
+        celixThreadRwlock_unlock(&registration->lock);
 	}
 }
 
@@ -112,7 +112,7 @@ static celix_status_t serviceRegistration_destroy(service_registration_pt regist
 	registration->registry = NULL;
 
 	properties_destroy(registration->properties);
-	celixThreadMutex_destroy(&registration->mutex);
+    celixThreadRwlock_destroy(&registration->lock);
 	free(registration);
 
 	return CELIX_SUCCESS;
@@ -125,7 +125,6 @@ static celix_status_t serviceRegistration_initializeProperties(service_registrat
 		dictionary = properties_create();
 	}
 
-	registration->properties = dictionary;
 
 	snprintf(sId, 32, "%ld", registration->serviceId);
 	properties_set(dictionary, (char *) OSGI_FRAMEWORK_SERVICE_ID, sId);
@@ -134,29 +133,46 @@ static celix_status_t serviceRegistration_initializeProperties(service_registrat
 		properties_set(dictionary, (char *) OSGI_FRAMEWORK_OBJECTCLASS, registration->className);
 	}
 
-	return CELIX_SUCCESS;
+
+    celixThreadRwlock_writeLock(&registration->lock);
+    registration->properties = dictionary;
+    celixThreadRwlock_unlock(&registration->lock);
+
+
+    return CELIX_SUCCESS;
 }
 
 bool serviceRegistration_isValid(service_registration_pt registration) {
-	return registration == NULL ? false : registration->svcObj != NULL;
+    bool result;
+    celixThreadRwlock_readLock(&registration->lock);
+    result = registration == NULL ? false : registration->svcObj != NULL;
+    celixThreadRwlock_unlock(&registration->lock);
+    return result;
 }
 
 void serviceRegistration_invalidate(service_registration_pt registration) {
-	celixThreadMutex_lock(&registration->mutex);
+    celixThreadRwlock_writeLock(&registration->lock);
 	registration->svcObj = NULL;
-	celixThreadMutex_unlock(&registration->mutex);
+    celixThreadRwlock_unlock(&registration->lock);
 }
 
 celix_status_t serviceRegistration_unregister(service_registration_pt registration) {
 	celix_status_t status = CELIX_SUCCESS;
-	celixThreadMutex_lock(&registration->mutex);
-	if (!serviceRegistration_isValid(registration) || registration->isUnregistering) {
+
+    bool notValidOrUnregistering;
+    celixThreadRwlock_readLock(&registration->lock);
+    notValidOrUnregistering = !serviceRegistration_isValid(registration) || registration->isUnregistering;
+    celixThreadRwlock_unlock(&registration->lock);
+
+
+    if (notValidOrUnregistering) {
 		printf("Service is already unregistered\n");
 		status = CELIX_ILLEGAL_STATE;
 	} else {
-		registration->isUnregistering = true;
-	}
-	celixThreadMutex_unlock(&registration->mutex);
+        celixThreadRwlock_writeLock(&registration->lock);
+        registration->isUnregistering = true;
+        celixThreadRwlock_unlock(&registration->lock);
+    }
 
 	if (status == CELIX_SUCCESS) {
 		serviceRegistry_unregisterService(registration->registry, registration->bundle, registration);
@@ -169,71 +185,71 @@ celix_status_t serviceRegistration_unregister(service_registration_pt registrati
 
 celix_status_t serviceRegistration_getService(service_registration_pt registration, bundle_pt bundle, void **service) {
 	int status = CELIX_SUCCESS;
+    celixThreadRwlock_readLock(&registration->lock);
     if (registration->isServiceFactory) {
         service_factory_pt factory = registration->serviceFactory;
         status = factory->getService(factory->factory, bundle, registration, service);
     } else {
         (*service) = registration->svcObj;
     }
+    celixThreadRwlock_unlock(&registration->lock);
     return status;
 }
 
 celix_status_t serviceRegistration_ungetService(service_registration_pt registration, bundle_pt bundle, void **service) {
+    celixThreadRwlock_readLock(&registration->lock);
     if (registration->isServiceFactory) {
         service_factory_pt factory = registration->serviceFactory;
         factory->ungetService(factory->factory, bundle, registration, service);
     }
+    celixThreadRwlock_unlock(&registration->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 && *properties == NULL) {
+    celixThreadRwlock_readLock(&registration->lock);
+    if (registration != NULL && *properties == NULL) {
 		*properties = registration->properties;
 	} else {
 		status = CELIX_ILLEGAL_ARGUMENT;
 	}
+    celixThreadRwlock_unlock(&registration->lock);
+
 
-	framework_logIfError(logger, status, NULL, "Cannot get registration properties");
+    framework_logIfError(logger, status, NULL, "Cannot get registration properties");
 
 	return status;
 }
 
 celix_status_t serviceRegistration_setProperties(service_registration_pt registration, properties_pt properties) {
-	properties_pt oldProps = registration->properties;
 
-	serviceRegistration_initializeProperties(registration, properties);
+
+    celixThreadRwlock_writeLock(&registration->lock);
+    properties_pt oldProps = registration->properties;
+    serviceRegistration_initializeProperties(registration, properties);
+    celixThreadRwlock_unlock(&registration->lock);
 
 	serviceRegistry_servicePropertiesModified(registration->registry, registration, oldProps);
 
 	return CELIX_SUCCESS;
 }
 
-celix_status_t serviceRegistration_getRegistry(service_registration_pt registration, service_registry_pt *registry) {
-	celix_status_t status = CELIX_SUCCESS;
-
-	if (registration != NULL && *registry == NULL) {
-		*registry = registration->registry;
-	} else {
-		status = CELIX_ILLEGAL_ARGUMENT;
-	}
-
-	framework_logIfError(logger, status, NULL, "Cannot get registry");
-
-	return status;
-}
 
 celix_status_t serviceRegistration_getBundle(service_registration_pt registration, bundle_pt *bundle) {
 	celix_status_t status = CELIX_SUCCESS;
 
-	if (registration != NULL && *bundle == NULL) {
+    celixThreadRwlock_readLock(&registration->lock);
+    if (registration != NULL && *bundle == NULL) {
 		*bundle = registration->bundle;
 	} else {
 		status = CELIX_ILLEGAL_ARGUMENT;
 	}
+    celixThreadRwlock_unlock(&registration->lock);
+
 
-	framework_logIfError(logger, status, NULL, "Cannot get bundle");
+    framework_logIfError(logger, status, NULL, "Cannot get bundle");
 
 	return status;
 }
@@ -241,13 +257,15 @@ celix_status_t serviceRegistration_getBundle(service_registration_pt registratio
 celix_status_t serviceRegistration_getServiceName(service_registration_pt registration, char **serviceName) {
 	celix_status_t status = CELIX_SUCCESS;
 
-	if (registration != NULL && *serviceName == NULL) {
+    celixThreadRwlock_readLock(&registration->lock);
+    if (registration != NULL && *serviceName == NULL) {
 		*serviceName = registration->className;
 	} else {
 		status = CELIX_ILLEGAL_ARGUMENT;
 	}
+    celixThreadRwlock_unlock(&registration->lock);
 
-	framework_logIfError(logger, status, NULL, "Cannot get service name");
+    framework_logIfError(logger, status, NULL, "Cannot get service name");
 
 	return status;
 }

http://git-wip-us.apache.org/repos/asf/celix/blob/07d0dfe6/framework/private/src/service_registry.c
----------------------------------------------------------------------
diff --git a/framework/private/src/service_registry.c b/framework/private/src/service_registry.c
index 9f84ded..6abd0cc 100644
--- a/framework/private/src/service_registry.c
+++ b/framework/private/src/service_registry.c
@@ -201,7 +201,6 @@ celix_status_t serviceRegistry_clearServiceRegistrations(service_registry_pt reg
     celix_status_t status = CELIX_SUCCESS;
     array_list_pt registrations = NULL;
 
-
     celixThreadMutex_lock(&registry->mutex);
 
     registrations = hashMap_get(registry->serviceRegistrations, bundle);
@@ -386,8 +385,7 @@ celix_status_t serviceRegistry_clearReferencesFor(service_registry_pt registry,
             serviceRegistry_logWarningServiceReferenceUsageCount(registry, usageCount, refCount);
 
             while (usageCount > 0) {
-                serviceReference_decreaseUsage(ref);
-                serviceReference_getUsageCount(ref, &usageCount);
+                serviceReference_decreaseUsage(ref, &usageCount);
             }
 
             bool destroyed = false;
@@ -431,14 +429,21 @@ celix_status_t serviceRegistry_getServicesInUse(service_registry_pt registry, bu
 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;
+    size_t count = 0;
+    void *service = NULL;
 
 	serviceReference_getServiceRegistration(reference, &registration);
-	
 	celixThreadMutex_lock(&registry->mutex);
 
+
 	if (serviceRegistration_isValid(registration)) {
-        serviceReference_increaseUsage(reference);
-		serviceRegistration_getService(registration, bundle, out);
+        serviceReference_increaseUsage(reference, &count);
+        if (count == 1) {
+            serviceRegistration_getService(registration, bundle, &service);
+            serviceReference_setService(reference, service);
+        }
+
+        serviceReference_getService(reference, out);
 	} else {
         *out = NULL; //invalid service registration
     }
@@ -451,8 +456,18 @@ celix_status_t serviceRegistry_getService(service_registry_pt registry, bundle_p
 
 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;
+    void *service = NULL;
+    size_t count = 0;
+
+    celix_status_t subStatus = serviceReference_decreaseUsage(reference, &count);
+
+    if (count == 0) {
+        serviceReference_getService(reference, &service);
+        serviceReference_getServiceRegistration(reference, &reg);
+        serviceRegistration_ungetService(reg, bundle, &service);
+    }
 
-    celix_status_t subStatus = serviceReference_decreaseUsage(reference);
     if (result) {
         *result = (subStatus == CELIX_SUCCESS);
     }

http://git-wip-us.apache.org/repos/asf/celix/blob/07d0dfe6/remote_services/examples/calculator_endpoint/private/src/calculator_endpoint_activator.c
----------------------------------------------------------------------
diff --git a/remote_services/examples/calculator_endpoint/private/src/calculator_endpoint_activator.c b/remote_services/examples/calculator_endpoint/private/src/calculator_endpoint_activator.c
index e76ebfa..04130f8 100644
--- a/remote_services/examples/calculator_endpoint/private/src/calculator_endpoint_activator.c
+++ b/remote_services/examples/calculator_endpoint/private/src/calculator_endpoint_activator.c
@@ -81,7 +81,7 @@ celix_status_t bundleActivator_stop(void * userData, bundle_context_pt context)
 
 	serviceRegistration_unregister(activator->endpointServiceRegistration);
 
-	free(activator->endpointService->endpoint);
+	//calculatorEndpoint_destroy(activator->endpointService->endpoint);
 	free(activator->endpointService);
 
 	return status;

http://git-wip-us.apache.org/repos/asf/celix/blob/07d0dfe6/remote_services/examples/calculator_service/private/src/calculator_activator.c
----------------------------------------------------------------------
diff --git a/remote_services/examples/calculator_service/private/src/calculator_activator.c b/remote_services/examples/calculator_service/private/src/calculator_activator.c
index 13ea995..688a7b0 100644
--- a/remote_services/examples/calculator_service/private/src/calculator_activator.c
+++ b/remote_services/examples/calculator_service/private/src/calculator_activator.c
@@ -76,13 +76,13 @@ celix_status_t bundleActivator_start(void * userData, bundle_context_pt context)
 			properties = properties_create();
 			properties_set(properties, (char *) OSGI_RSA_SERVICE_EXPORTED_INTERFACES, (char *) CALCULATOR_SERVICE);
 
-                        bundleContext_registerService(context, (char *) CALCULATOR_SERVICE, activator->service, properties, &activator->calculatorReg);
+			bundleContext_registerService(context, (char *) CALCULATOR_SERVICE, activator->service, properties, &activator->calculatorReg);
 
-                        properties_pt properties2 = properties_create();
-            properties_set(properties2, (char *) OSGI_RSA_SERVICE_EXPORTED_INTERFACES, (char *) CALCULATOR2_SERVICE);
-                        bundleContext_registerService(context, CALCULATOR2_SERVICE, activator->service, properties2, &activator->calculatorReg2);
-                }
-        }
+			properties_pt properties2 = properties_create();
+			properties_set(properties2, (char *) OSGI_RSA_SERVICE_EXPORTED_INTERFACES, (char *) CALCULATOR2_SERVICE);
+			bundleContext_registerService(context, CALCULATOR2_SERVICE, activator->service, properties2, &activator->calculatorReg2);
+		}
+	}
 
 	return status;
 }

http://git-wip-us.apache.org/repos/asf/celix/blob/07d0dfe6/remote_services/remote_service_admin_dfi/rsa/private/src/export_registration_dfi.c
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_dfi/rsa/private/src/export_registration_dfi.c b/remote_services/remote_service_admin_dfi/rsa/private/src/export_registration_dfi.c
index 4182a4c..0567870 100644
--- a/remote_services/remote_service_admin_dfi/rsa/private/src/export_registration_dfi.c
+++ b/remote_services/remote_service_admin_dfi/rsa/private/src/export_registration_dfi.c
@@ -191,6 +191,9 @@ static void exportRegistration_removeServ(export_registration_pt reg, service_re
 celix_status_t exportRegistration_stop(export_registration_pt reg) {
     celix_status_t status = CELIX_SUCCESS;
     status = bundleContext_ungetService(reg->context, reg->exportReference.reference, NULL);
+    if (status == CELIX_SUCCESS) {
+        bundleContext_ungetServiceReference(reg->context, reg->exportReference.reference);
+    }
     return status;
 }
 

http://git-wip-us.apache.org/repos/asf/celix/blob/07d0dfe6/remote_services/remote_service_admin_dfi/rsa/private/src/remote_service_admin_dfi.c
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_dfi/rsa/private/src/remote_service_admin_dfi.c b/remote_services/remote_service_admin_dfi/rsa/private/src/remote_service_admin_dfi.c
index 066c3da..fc0303b 100644
--- a/remote_services/remote_service_admin_dfi/rsa/private/src/remote_service_admin_dfi.c
+++ b/remote_services/remote_service_admin_dfi/rsa/private/src/remote_service_admin_dfi.c
@@ -379,8 +379,14 @@ celix_status_t remoteServiceAdmin_exportService(remote_service_admin_pt admin, c
 
     logHelper_log(admin->loghelper, OSGI_LOGSERVICE_ERROR, "RSA: exportService called for serviceId %s", serviceId);
 
-    if (status == CELIX_SUCCESS && arrayList_size(references) >= 1) {
-        reference = arrayList_get(references, 0);
+    int i;
+    int size = arrayList_size(references);
+    for (i = 0; i < size; i += 1) {
+        if (i == 0) {
+            reference = arrayList_get(references, i);
+        } else {
+            bundleContext_ungetServiceReference(admin->context, arrayList_get(references, i));
+        }
     }
 
     if(references != NULL){

http://git-wip-us.apache.org/repos/asf/celix/blob/07d0dfe6/remote_services/remote_service_admin_dfi/rsa_tst/rsa_tests.cpp
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_dfi/rsa_tst/rsa_tests.cpp b/remote_services/remote_service_admin_dfi/rsa_tst/rsa_tests.cpp
index 5784730..fd764d2 100644
--- a/remote_services/remote_service_admin_dfi/rsa_tst/rsa_tests.cpp
+++ b/remote_services/remote_service_admin_dfi/rsa_tst/rsa_tests.cpp
@@ -79,9 +79,15 @@ extern "C" {
         rc = bundleContext_ungetService(context, rsaRef, NULL);
         CHECK_EQUAL(CELIX_SUCCESS, rc);
 
+        rc = bundleContext_ungetServiceReference(context, rsaRef);
+        CHECK_EQUAL(CELIX_SUCCESS, rc);
+
         rc = bundleContext_ungetService(context, calcRef, NULL);
         CHECK_EQUAL(CELIX_SUCCESS, rc);
 
+        rc = bundleContext_ungetServiceReference(context, calcRef);
+        CHECK_EQUAL(CELIX_SUCCESS, rc);
+
         celixLauncher_stop(framework);
         celixLauncher_waitForShutdown(framework);
         celixLauncher_destroy(framework);


[35/38] celix git commit: CELIX-272: Add missing return status

Posted by pn...@apache.org.
CELIX-272: Add missing return status


Project: http://git-wip-us.apache.org/repos/asf/celix/repo
Commit: http://git-wip-us.apache.org/repos/asf/celix/commit/530b4f72
Tree: http://git-wip-us.apache.org/repos/asf/celix/tree/530b4f72
Diff: http://git-wip-us.apache.org/repos/asf/celix/diff/530b4f72

Branch: refs/heads/develop
Commit: 530b4f72df23291e2764542fad09f96293e769cc
Parents: a40693f
Author: Pepijn Noltes <pe...@gmail.com>
Authored: Tue Nov 17 10:15:52 2015 +0100
Committer: Pepijn Noltes <pe...@gmail.com>
Committed: Tue Nov 17 10:15:52 2015 +0100

----------------------------------------------------------------------
 remote_shell/private/src/shell_mediator.c | 2 ++
 1 file changed, 2 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/celix/blob/530b4f72/remote_shell/private/src/shell_mediator.c
----------------------------------------------------------------------
diff --git a/remote_shell/private/src/shell_mediator.c b/remote_shell/private/src/shell_mediator.c
index 9b08035..ae4de10 100644
--- a/remote_shell/private/src/shell_mediator.c
+++ b/remote_shell/private/src/shell_mediator.c
@@ -81,6 +81,8 @@ celix_status_t shellMediator_stop(shell_mediator_pt instance) {
 	if (tracker != NULL) {
 		serviceTracker_close(tracker);
 	}
+
+    return CELIX_SUCCESS;
 }
 
 celix_status_t shellMediator_destroy(shell_mediator_pt instance) {


[38/38] celix git commit: Merge branch 'feature/CELIX-272_synchronization_service_registry' into develop

Posted by pn...@apache.org.
Merge branch 'feature/CELIX-272_synchronization_service_registry' into develop


Project: http://git-wip-us.apache.org/repos/asf/celix/repo
Commit: http://git-wip-us.apache.org/repos/asf/celix/commit/61b08289
Tree: http://git-wip-us.apache.org/repos/asf/celix/tree/61b08289
Diff: http://git-wip-us.apache.org/repos/asf/celix/diff/61b08289

Branch: refs/heads/develop
Commit: 61b08289354233e2a7ea9a5ec8ea688e87e04dfd
Parents: 0366d02 5eb0321
Author: Pepijn Noltes <pe...@gmail.com>
Authored: Tue Nov 17 12:54:15 2015 +0100
Committer: Pepijn Noltes <pe...@gmail.com>
Committed: Tue Nov 17 12:54:15 2015 +0100

----------------------------------------------------------------------
 .../private/src/dm_component_impl.c             |  14 +-
 .../private/src/dm_service_dependency.c         |   3 +
 .../private/src/dm_shell_list_command.c         |   4 +
 examples/CMakeLists.txt                         |   1 +
 examples/deploy.cmake                           |   3 +
 examples/locking/CMakeLists.txt                 |  24 +
 examples/locking/benchmark/CMakeLists.txt       |  30 +
 .../private/src/benchmark_runner_activator.c    | 255 ++++++
 .../benchmark/public/include/benchmark.h        |  29 +
 .../benchmark/public/include/benchmark_result.h |  20 +
 .../public/include/benchmark_service.h          |  27 +
 .../public/include/frequency_service.h          |  47 ++
 .../benchmark/public/include/math_service.h     |  40 +
 .../benchmark/public/src/benchmark_activator.c  | 133 ++++
 examples/locking/consumer.c                     | 372 +++++++++
 examples/locking/math_provider/CMakeLists.txt   |  32 +
 .../private/include/math_component.h            |  14 +
 .../math_provider/private/src/math_component.c  |  28 +
 .../private/src/provider_activator.c            | 220 ++++++
 .../modified_bool_benchmark/CMakeLists.txt      |  32 +
 .../private/src/modified_bool_benchmark.c       | 162 ++++
 examples/locking/mutex_benchmark/CMakeLists.txt |  32 +
 .../private/src/mutex_benchmark.c               | 117 +++
 .../locking/reference_benchmark/CMakeLists.txt  |  32 +
 .../private/src/reference_benchmark.c           | 116 +++
 .../locking/start_stop_benchmark/CMakeLists.txt |  32 +
 .../private/src/start_stop_benchmark.c          | 189 +++++
 framework/CMakeLists.txt                        |  24 +-
 .../private/include/registry_callback_private.h |  42 +
 .../private/include/service_reference_private.h |  31 +-
 .../include/service_registration_private.h      |  23 +-
 .../private/include/service_registry_private.h  |  24 +-
 .../service_tracker_customizer_private.h        |   4 +
 framework/private/mock/service_reference_mock.c |  17 +-
 .../private/mock/service_registration_mock.c    |  10 +
 framework/private/mock/service_registry_mock.c  |  23 +
 framework/private/src/bundle_archive.c          |  68 +-
 framework/private/src/bundle_cache.c            |  92 ++-
 framework/private/src/bundle_context.c          |   2 +-
 framework/private/src/framework.c               |  78 +-
 framework/private/src/properties.c              |  24 +
 framework/private/src/service_reference.c       | 299 +++++--
 framework/private/src/service_registration.c    | 218 ++---
 framework/private/src/service_registry.c        | 791 ++++++++++---------
 framework/private/src/service_tracker.c         | 154 ++--
 .../private/test/service_reference_test.cpp     |  23 +-
 .../private/test/service_registration_test.cpp  |  62 +-
 .../private/test/service_registry_test.cpp      |  13 +-
 framework/public/include/properties.h           |   3 +
 framework/public/include/service_reference.h    |   3 +-
 framework/public/include/service_registration.h |   1 -
 framework/public/include/service_registry.h     |  19 +-
 .../private/src/calculator_endpoint_activator.c |   2 +-
 .../private/src/calculator_activator.c          |  12 +-
 .../CMakeLists.txt                              |   5 +
 .../rsa/private/src/export_registration_dfi.c   |   4 +-
 .../rsa/private/src/remote_service_admin_dfi.c  |  15 +-
 .../rsa_tst/CMakeLists.txt                      |   2 +-
 .../rsa_tst/rsa_tests.cpp                       |   6 +
 remote_shell/private/include/shell_mediator.h   |   1 +
 remote_shell/private/src/activator.c            |   1 +
 remote_shell/private/src/shell_mediator.c       |  41 +-
 shell/private/src/activator.c                   |   6 +-
 shell/private/src/shell.c                       |   5 -
 utils/private/src/celix_threads.c               |  32 +
 utils/public/include/celix_threads.h            |  20 +-
 66 files changed, 3308 insertions(+), 900 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/celix/blob/61b08289/remote_services/remote_service_admin_dfi/rsa/private/src/remote_service_admin_dfi.c
----------------------------------------------------------------------


[37/38] celix git commit: CELIX-272: Fix some small (lint warning) issues

Posted by pn...@apache.org.
CELIX-272: Fix some small (lint warning) issues


Project: http://git-wip-us.apache.org/repos/asf/celix/repo
Commit: http://git-wip-us.apache.org/repos/asf/celix/commit/5eb0321c
Tree: http://git-wip-us.apache.org/repos/asf/celix/tree/5eb0321c
Diff: http://git-wip-us.apache.org/repos/asf/celix/diff/5eb0321c

Branch: refs/heads/develop
Commit: 5eb0321ca22f92a55a5ac8ea600503918f5ac26f
Parents: 47fe773
Author: Pepijn Noltes <pe...@gmail.com>
Authored: Tue Nov 17 11:25:15 2015 +0100
Committer: Pepijn Noltes <pe...@gmail.com>
Committed: Tue Nov 17 11:25:15 2015 +0100

----------------------------------------------------------------------
 framework/private/src/service_registration.c | 34 +++++++++++------------
 framework/private/src/service_registry.c     |  2 +-
 2 files changed, 17 insertions(+), 19 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/celix/blob/5eb0321c/framework/private/src/service_registration.c
----------------------------------------------------------------------
diff --git a/framework/private/src/service_registration.c b/framework/private/src/service_registration.c
index f1fea32..d9c5752 100644
--- a/framework/private/src/service_registration.c
+++ b/framework/private/src/service_registration.c
@@ -148,13 +148,13 @@ void serviceRegistration_invalidate(service_registration_pt registration) {
 
 bool serviceRegistration_isValid(service_registration_pt registration) {
     bool isValid;
-    celixThreadRwlock_readLock(&registration->lock);
     if (registration != NULL) {
+        celixThreadRwlock_readLock(&registration->lock);
         isValid = registration->svcObj != NULL;
+        celixThreadRwlock_unlock(&registration->lock);
     } else {
         isValid = false;
     }
-    celixThreadRwlock_unlock(&registration->lock);
     return isValid;
 }
 
@@ -216,14 +216,13 @@ celix_status_t serviceRegistration_ungetService(service_registration_pt registra
 celix_status_t serviceRegistration_getProperties(service_registration_pt registration, properties_pt *properties) {
 	celix_status_t status = CELIX_SUCCESS;
 
-    celixThreadRwlock_readLock(&registration->lock);
     if (registration != NULL && *properties == NULL) {
-		*properties = registration->properties;
+        celixThreadRwlock_readLock(&registration->lock);
+        *properties = registration->properties;
+        celixThreadRwlock_unlock(&registration->lock);
 	} else {
 		status = CELIX_ILLEGAL_ARGUMENT;
 	}
-    celixThreadRwlock_unlock(&registration->lock);
-
 
     framework_logIfError(logger, status, NULL, "Cannot get registration properties");
 
@@ -231,11 +230,10 @@ celix_status_t serviceRegistration_getProperties(service_registration_pt registr
 }
 
 celix_status_t serviceRegistration_setProperties(service_registration_pt registration, properties_pt properties) {
-    celix_status_t status = CELIX_SUCCESS;
+    celix_status_t status;
 
     properties_pt oldProperties = NULL;
     registry_callback_t callback;
-    callback.modified = NULL;
 
     celixThreadRwlock_writeLock(&registration->lock);
     oldProperties = registration->properties;
@@ -247,21 +245,20 @@ celix_status_t serviceRegistration_setProperties(service_registration_pt registr
         callback.modified(callback.handle, registration, oldProperties);
     }
 
-	return CELIX_SUCCESS;
+	return status;
 }
 
 
 celix_status_t serviceRegistration_getBundle(service_registration_pt registration, bundle_pt *bundle) {
 	celix_status_t status = CELIX_SUCCESS;
 
-    celixThreadRwlock_readLock(&registration->lock);
     if (registration != NULL && *bundle == NULL) {
-		*bundle = registration->bundle;
+        celixThreadRwlock_readLock(&registration->lock);
+        *bundle = registration->bundle;
+        celixThreadRwlock_unlock(&registration->lock);
 	} else {
 		status = CELIX_ILLEGAL_ARGUMENT;
 	}
-    celixThreadRwlock_unlock(&registration->lock);
-
 
     framework_logIfError(logger, status, NULL, "Cannot get bundle");
 
@@ -271,13 +268,14 @@ celix_status_t serviceRegistration_getBundle(service_registration_pt registratio
 celix_status_t serviceRegistration_getServiceName(service_registration_pt registration, char **serviceName) {
 	celix_status_t status = CELIX_SUCCESS;
 
-    celixThreadRwlock_readLock(&registration->lock);
     if (registration != NULL && *serviceName == NULL) {
-		*serviceName = registration->className;
+        celixThreadRwlock_readLock(&registration->lock);
+        *serviceName = registration->className;
+        celixThreadRwlock_unlock(&registration->lock);
 	} else {
-		status = CELIX_ILLEGAL_ARGUMENT;
-	}
-    celixThreadRwlock_unlock(&registration->lock);
+        status = CELIX_ILLEGAL_ARGUMENT;
+    }
+
 
     framework_logIfError(logger, status, NULL, "Cannot get service name");
 

http://git-wip-us.apache.org/repos/asf/celix/blob/5eb0321c/framework/private/src/service_registry.c
----------------------------------------------------------------------
diff --git a/framework/private/src/service_registry.c b/framework/private/src/service_registry.c
index 277fe77..4155854 100644
--- a/framework/private/src/service_registry.c
+++ b/framework/private/src/service_registry.c
@@ -99,7 +99,7 @@ celix_status_t serviceRegistry_destroy(service_registry_pt registry) {
     hashMap_destroy(registry->serviceRegistrations, false, false);
 
     //destroy service references (double) map);
-    size = hashMap_size(registry->serviceReferences);
+    //size = hashMap_size(registry->serviceReferences);
     //assert(size == 0); FIXME This gives a problem in the remote_service_admin_dfi test. seems that the bundleActivator_stop of the calculator is activated twice ??
     hashMap_destroy(registry->serviceReferences, false, false);
 


[09/38] celix git commit: CELIX-272: Change readdir to readdir_r (reentrant)

Posted by pn...@apache.org.
CELIX-272: Change readdir to readdir_r (reentrant)


Project: http://git-wip-us.apache.org/repos/asf/celix/repo
Commit: http://git-wip-us.apache.org/repos/asf/celix/commit/ca19830e
Tree: http://git-wip-us.apache.org/repos/asf/celix/tree/ca19830e
Diff: http://git-wip-us.apache.org/repos/asf/celix/diff/ca19830e

Branch: refs/heads/develop
Commit: ca19830e4a7b11f4e7705eaeadf509486c8e69d3
Parents: 07d0dfe
Author: Pepijn Noltes <pe...@gmail.com>
Authored: Wed Nov 11 18:02:51 2015 +0100
Committer: Pepijn Noltes <pe...@gmail.com>
Committed: Wed Nov 11 18:02:51 2015 +0100

----------------------------------------------------------------------
 framework/private/src/bundle_archive.c | 55 +++++++++++++++++-----------
 framework/private/src/bundle_cache.c   | 57 +++++++++++++++++++----------
 2 files changed, 72 insertions(+), 40 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/celix/blob/ca19830e/framework/private/src/bundle_archive.c
----------------------------------------------------------------------
diff --git a/framework/private/src/bundle_archive.c b/framework/private/src/bundle_archive.c
index c1a23aa..b126617 100644
--- a/framework/private/src/bundle_archive.c
+++ b/framework/private/src/bundle_archive.c
@@ -187,15 +187,22 @@ celix_status_t bundleArchive_recreate(char * archiveRoot, bundle_archive_pt *bun
 		if (archive->archiveRootDir == NULL) {
 		    status = CELIX_FRAMEWORK_EXCEPTION;
 		} else {
-		    struct dirent *dent;
+
             long idx = 0;
             char *location = NULL;
 
-            while ((dent = readdir(archive->archiveRootDir)) != NULL) {
-                if (dent->d_type == DT_DIR && (strncmp(dent->d_name, "version", 7) == 0)) {
-                    sscanf(dent->d_name, "version%*d.%ld", &idx);
-                }
-            }
+			struct dirent dent;
+			struct dirent *result;
+			int rc;
+
+			rc = readdir_r(archive->archiveRootDir, &dent, &result);
+
+			while (rc == 0 && result != NULL) {
+				if (dent.d_type == DT_DIR && (strncmp(dent.d_name, "version", 7) == 0)) {
+					sscanf(dent.d_name, "version%*d.%ld", &idx);
+				}
+				rc = readdir_r(archive->archiveRootDir, &dent, &result);
+			}
 
             status = CELIX_DO_IF(status, bundleArchive_getRevisionLocation(archive, 0, &location));
             status = CELIX_DO_IF(status, bundleArchive_reviseInternal(archive, true, idx, location, NULL));
@@ -708,21 +715,27 @@ static celix_status_t bundleArchive_deleteTree(bundle_archive_pt archive, char *
 	if (dir == NULL) {
 	    status = CELIX_FILE_IO_EXCEPTION;
 	} else {
-		struct dirent *dp;
-		while ((dp = readdir(dir)) != NULL) {
-		    if ((strcmp((dp->d_name), ".") != 0) && (strcmp((dp->d_name), "..") != 0)) {
-                char subdir[512];
-                snprintf(subdir, sizeof(subdir), "%s/%s", directory, dp->d_name);
-
-                if (dp->d_type == DT_DIR) {
-                    status = bundleArchive_deleteTree(archive, subdir);
-                } else {
-                    if (remove(subdir) != 0) {
-                        status = CELIX_FILE_IO_EXCEPTION;
-                        break;
-                    }
-                }
-		    }
+
+		struct dirent dp;
+		struct dirent *result = NULL;
+		int rc = 0;
+
+		rc = readdir_r(dir, &dp, &result);
+		while (rc == 0 && result != NULL) {
+			if ((strcmp((dp.d_name), ".") != 0) && (strcmp((dp.d_name), "..") != 0)) {
+				char subdir[512];
+				snprintf(subdir, sizeof(subdir), "%s/%s", directory, dp.d_name);
+
+				if (dp.d_type == DT_DIR) {
+					status = bundleArchive_deleteTree(archive, subdir);
+				} else {
+					if (remove(subdir) != 0) {
+						status = CELIX_FILE_IO_EXCEPTION;
+						break;
+					}
+				}
+			}
+			rc = readdir_r(dir, &dp, &result);
 		}
 
 		if (closedir(dir) != 0) {

http://git-wip-us.apache.org/repos/asf/celix/blob/ca19830e/framework/private/src/bundle_cache.c
----------------------------------------------------------------------
diff --git a/framework/private/src/bundle_cache.c b/framework/private/src/bundle_cache.c
index 6eaf5d0..efe4f01 100644
--- a/framework/private/src/bundle_cache.c
+++ b/framework/private/src/bundle_cache.c
@@ -74,7 +74,8 @@ celix_status_t bundleCache_destroy(bundle_cache_pt *cache) {
 }
 
 celix_status_t bundleCache_delete(bundle_cache_pt cache) {
-	return bundleCache_deleteTree(cache, cache->cacheDir);
+    printf("DELETING CACHE DIR: %s\n", cache->cacheDir);
+    return bundleCache_deleteTree(cache, cache->cacheDir);
 }
 
 celix_status_t bundleCache_getArchives(bundle_cache_pt cache, array_list_pt *archives) {
@@ -90,19 +91,23 @@ celix_status_t bundleCache_getArchives(bundle_cache_pt cache, array_list_pt *arc
 
 	if (dir != NULL) {
         array_list_pt list = NULL;
-		struct dirent *dp;
         arrayList_create(&list);
-        
-        while ((dp = readdir(dir)) != NULL) {
-			char archiveRoot[512];
 
-			snprintf(archiveRoot, sizeof(archiveRoot), "%s/%s", cache->cacheDir, dp->d_name);
+        struct dirent dp;
+        struct dirent *result = NULL;
+        int rc = 0;
 
-            if (dp->d_type == DT_DIR
-                    && (strcmp((dp->d_name), ".") != 0)
-                    && (strcmp((dp->d_name), "..") != 0)
-                    && (strncmp(dp->d_name, "bundle", 6) == 0)
-                    && (strcmp(dp->d_name, "bundle0") != 0)) {
+        rc = readdir_r(dir, &dp, &result);
+        while (rc == 0 && result != NULL) {
+            char archiveRoot[512];
+
+            snprintf(archiveRoot, sizeof(archiveRoot), "%s/%s", cache->cacheDir, dp.d_name);
+
+            if (dp.d_type == DT_DIR
+                && (strcmp((dp.d_name), ".") != 0)
+                && (strcmp((dp.d_name), "..") != 0)
+                && (strncmp(dp.d_name, "bundle", 6) == 0)
+                && (strcmp(dp.d_name, "bundle0") != 0)) {
 
                 bundle_archive_pt archive = NULL;
                 status = bundleArchive_recreate(strdup(archiveRoot), &archive);
@@ -110,13 +115,23 @@ celix_status_t bundleCache_getArchives(bundle_cache_pt cache, array_list_pt *arc
                     arrayList_add(list, archive);
                 }
             }
+
+            readdir_r(dir, &dp, &result);
+        }
+
+        if (rc != 0) {
+            fw_log(logger, OSGI_FRAMEWORK_LOG_ERROR, "Error reading dir");
+            status = CELIX_FILE_IO_EXCEPTION;
+        } else {
+            status = CELIX_SUCCESS;
         }
 
         closedir(dir);
 
-        *archives = list;
+        if (status == CELIX_SUCCESS) {
+            *archives = list;
+        }
 
-        status = CELIX_SUCCESS;
 	} else {
 	    status = CELIX_FILE_IO_EXCEPTION;
 	}
@@ -147,13 +162,16 @@ static celix_status_t bundleCache_deleteTree(bundle_cache_pt cache, char * direc
     if (dir == NULL) {
         status = CELIX_FILE_IO_EXCEPTION;
     } else {
-        struct dirent *dp;
-        while ((dp = readdir(dir)) != NULL) {
-            if ((strcmp((dp->d_name), ".") != 0) && (strcmp((dp->d_name), "..") != 0)) {
+        struct dirent dp;
+        struct dirent *result = NULL;
+        int rc = 0;
+        rc = readdir_r(dir, &dp, &result);
+        while (rc == 0 && result != NULL) {
+            if ((strcmp((dp.d_name), ".") != 0) && (strcmp((dp.d_name), "..") != 0)) {
                 char subdir[512];
-                snprintf(subdir, sizeof(subdir), "%s/%s", directory, dp->d_name);
+                snprintf(subdir, sizeof(subdir), "%s/%s", directory, dp.d_name);
 
-                if (dp->d_type == DT_DIR) {
+                if (dp.d_type == DT_DIR) {
                     status = bundleCache_deleteTree(cache, subdir);
                 } else {
                     if (remove(subdir) != 0) {
@@ -162,6 +180,7 @@ static celix_status_t bundleCache_deleteTree(bundle_cache_pt cache, char * direc
                     }
                 }
             }
+            readdir_r(dir, &dp, &result);
         }
 
         if (closedir(dir) != 0) {
@@ -174,7 +193,7 @@ static celix_status_t bundleCache_deleteTree(bundle_cache_pt cache, char * direc
         }
     }
 
-    framework_logIfError(logger, status, NULL, "Failed to delete tree");
+    framework_logIfError(logger, status, NULL, "Failed to delete tree at dir '%s'", directory);
 
     return status;
 }


[22/38] celix git commit: Merge branch 'develop' into feature/CELIX-272_synchronization_service_registry

Posted by pn...@apache.org.
Merge branch 'develop' into feature/CELIX-272_synchronization_service_registry


Project: http://git-wip-us.apache.org/repos/asf/celix/repo
Commit: http://git-wip-us.apache.org/repos/asf/celix/commit/8c02ecf3
Tree: http://git-wip-us.apache.org/repos/asf/celix/tree/8c02ecf3
Diff: http://git-wip-us.apache.org/repos/asf/celix/diff/8c02ecf3

Branch: refs/heads/develop
Commit: 8c02ecf382b529af57509188e380768f2817b20b
Parents: eae936a 437da02
Author: Pepijn Noltes <pe...@gmail.com>
Authored: Mon Nov 16 16:43:07 2015 +0100
Committer: Pepijn Noltes <pe...@gmail.com>
Committed: Mon Nov 16 16:43:07 2015 +0100

----------------------------------------------------------------------
 .travis.yml                                     |   2 +-
 log_service/public/src/log_helper.c             |   4 +-
 .../private/include/endpoint_discovery_server.h |   2 +-
 .../private/src/endpoint_discovery_poller.c     |   2 -
 remote_services/discovery_shm/CMakeLists.txt    |   4 +-
 .../private/include/discovery_impl.h            |   2 +-
 .../private/include/discovery_shm.h             |  56 +++
 .../private/include/discovery_shmWatcher.h      |  40 +++
 .../discovery_shm/private/include/shm.h         |  56 ---
 .../discovery_shm/private/include/shm_watcher.h |  40 ---
 .../discovery_shm/private/src/discovery_impl.c  |  81 ++---
 .../discovery_shm/private/src/discovery_shm.c   | 279 +++++++++++++++
 .../private/src/discovery_shmWatcher.c          | 249 +++++++++++++
 remote_services/discovery_shm/private/src/shm.c | 264 --------------
 .../discovery_shm/private/src/shm_watcher.c     | 230 ------------
 .../dynamic_function_interface/CMakeLists.txt   |   2 +-
 .../private/test/rsa_client_server_tests.cpp    | 351 ++++++++++++++++---
 .../remote_service_admin_shm/CMakeLists.txt     |   7 +
 .../src/remote_service_admin_activator.c        | 114 +++---
 .../private/src/remote_service_admin_impl.c     | 199 ++++++-----
 .../private/test/CMakeLists.txt                 |  58 +++
 .../private/test/client.properties.in           |  25 ++
 .../private/test/rsa_client_server_tests.cpp    | 126 +++++++
 .../private/test/run_tests.cpp                  |  24 ++
 .../private/test/server.properties.in           |  25 ++
 .../private/src/topology_manager.c              |   8 +-
 shell/private/src/activator.c                   |   2 +
 shell/private/src/shell.c                       |   3 +
 28 files changed, 1405 insertions(+), 850 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/celix/blob/8c02ecf3/shell/private/src/activator.c
----------------------------------------------------------------------
diff --cc shell/private/src/activator.c
index 19f9a17,aed0d9b..edd2931
--- a/shell/private/src/activator.c
+++ b/shell/private/src/activator.c
@@@ -269,10 -269,14 +269,12 @@@ celix_status_t bundleActivator_destroy(
          }
      }
  
 +    serviceRegistration_unregister(instance_ptr->registration);
 +
      shell_destroy(&instance_ptr->shellService);
  
+     free(instance_ptr->listener);
+ 
      free(instance_ptr);
  
  	return CELIX_SUCCESS;

http://git-wip-us.apache.org/repos/asf/celix/blob/8c02ecf3/shell/private/src/shell.c
----------------------------------------------------------------------


[12/38] celix git commit: CELIX-288: Fix in finding highest bundle archive version

Posted by pn...@apache.org.
CELIX-288: Fix in finding highest bundle archive version


Project: http://git-wip-us.apache.org/repos/asf/celix/repo
Commit: http://git-wip-us.apache.org/repos/asf/celix/commit/90b92ffd
Tree: http://git-wip-us.apache.org/repos/asf/celix/tree/90b92ffd
Diff: http://git-wip-us.apache.org/repos/asf/celix/diff/90b92ffd

Branch: refs/heads/develop
Commit: 90b92ffd0d923aca6edb8bf4577261b7fa5b478b
Parents: 1836ed4
Author: Pepijn Noltes <pe...@gmail.com>
Authored: Thu Nov 12 17:38:16 2015 +0100
Committer: Pepijn Noltes <pe...@gmail.com>
Committed: Thu Nov 12 17:40:27 2015 +0100

----------------------------------------------------------------------
 framework/private/src/bundle_archive.c | 18 +++++++++++-------
 1 file changed, 11 insertions(+), 7 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/celix/blob/90b92ffd/framework/private/src/bundle_archive.c
----------------------------------------------------------------------
diff --git a/framework/private/src/bundle_archive.c b/framework/private/src/bundle_archive.c
index f7add7e..6df7270 100644
--- a/framework/private/src/bundle_archive.c
+++ b/framework/private/src/bundle_archive.c
@@ -189,10 +189,11 @@ celix_status_t bundleArchive_recreate(char * archiveRoot, bundle_archive_pt *bun
 		} else {
 
             long idx = 0;
+            long highestId = -1;
             char *location = NULL;
 
 			struct dirent dent;
-			struct dirent *result;
+			struct dirent *result = NULL;
             struct stat st;
 			int rc;
 
@@ -203,15 +204,15 @@ celix_status_t bundleArchive_recreate(char * archiveRoot, bundle_archive_pt *bun
                 stat(subdir, &st);
 				if (S_ISDIR(st.st_mode) && (strncmp(dent.d_name, "version", 7) == 0)) {
 					sscanf(dent.d_name, "version%*d.%ld", &idx);
-				} else {
-                    status = CELIX_FILE_IO_EXCEPTION;
-                    break;
-                }
+                    if (idx > highestId) {
+                        highestId = idx;
+                    }
+				}
 				rc = readdir_r(archive->archiveRootDir, &dent, &result);
 			}
 
             status = CELIX_DO_IF(status, bundleArchive_getRevisionLocation(archive, 0, &location));
-            status = CELIX_DO_IF(status, bundleArchive_reviseInternal(archive, true, idx, location, NULL));
+            status = CELIX_DO_IF(status, bundleArchive_reviseInternal(archive, true, highestId, location, NULL));
             if (location) {
                 free(location);
             }
@@ -668,7 +669,10 @@ static celix_status_t bundleArchive_initialize(bundle_archive_pt archive) {
 	celix_status_t status = CELIX_SUCCESS;
 
 	if (archive->archiveRootDir == NULL) {
-	    if (mkdir(archive->archiveRoot, S_IRWXU) != 0) {
+        int err = mkdir(archive->archiveRoot, S_IRWXU) ;
+	    if (err != 0) {
+            char *errmsg = strerror(errno);
+            fw_log(logger, OSGI_FRAMEWORK_LOG_ERROR, "Error mkdir: %s\n", errmsg);
 			status = CELIX_FILE_IO_EXCEPTION;
 		} else {
 		    archive->archiveRootDir = opendir(archive->archiveRoot);


[18/38] celix git commit: CELIX-272: Fix missing unregister service for shell

Posted by pn...@apache.org.
CELIX-272: Fix missing unregister service for shell


Project: http://git-wip-us.apache.org/repos/asf/celix/repo
Commit: http://git-wip-us.apache.org/repos/asf/celix/commit/a6213e45
Tree: http://git-wip-us.apache.org/repos/asf/celix/tree/a6213e45
Diff: http://git-wip-us.apache.org/repos/asf/celix/diff/a6213e45

Branch: refs/heads/develop
Commit: a6213e45525e0d69c7c6cb736769f781a244911f
Parents: 90b92ff
Author: Pepijn Noltes <pe...@gmail.com>
Authored: Mon Nov 16 12:20:23 2015 +0100
Committer: Pepijn Noltes <pe...@gmail.com>
Committed: Mon Nov 16 12:20:23 2015 +0100

----------------------------------------------------------------------
 shell/private/src/activator.c | 6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/celix/blob/a6213e45/shell/private/src/activator.c
----------------------------------------------------------------------
diff --git a/shell/private/src/activator.c b/shell/private/src/activator.c
index 7cb2946..19f9a17 100644
--- a/shell/private/src/activator.c
+++ b/shell/private/src/activator.c
@@ -266,13 +266,11 @@ celix_status_t bundleActivator_destroy(void *_ptr, bundle_context_pt __attribute
     if (instance_ptr) {
         for (unsigned int i = 0; instance_ptr->std_commands[i].exec != NULL; i++) {
             free(instance_ptr->std_commands[i].service);
-
-            if (instance_ptr->std_commands[i].props != NULL) {
-                properties_destroy(instance_ptr->std_commands[i].props);
-            }
         }
     }
 
+    serviceRegistration_unregister(instance_ptr->registration);
+
     shell_destroy(&instance_ptr->shellService);
 
     free(instance_ptr);


[36/38] celix git commit: CELIX-272: Fix for mocks. Disabled service_registry test for now

Posted by pn...@apache.org.
CELIX-272: Fix for mocks. Disabled service_registry test for now


Project: http://git-wip-us.apache.org/repos/asf/celix/repo
Commit: http://git-wip-us.apache.org/repos/asf/celix/commit/47fe773a
Tree: http://git-wip-us.apache.org/repos/asf/celix/tree/47fe773a
Diff: http://git-wip-us.apache.org/repos/asf/celix/diff/47fe773a

Branch: refs/heads/develop
Commit: 47fe773a77aaa334f7eb6f3979ad351a8a30adea
Parents: 530b4f7
Author: Pepijn Noltes <pe...@gmail.com>
Authored: Tue Nov 17 10:35:47 2015 +0100
Committer: Pepijn Noltes <pe...@gmail.com>
Committed: Tue Nov 17 10:35:47 2015 +0100

----------------------------------------------------------------------
 framework/CMakeLists.txt                        | 24 ++++----
 framework/private/mock/service_reference_mock.c | 17 +++++-
 .../private/mock/service_registration_mock.c    | 10 ++++
 framework/private/mock/service_registry_mock.c  | 23 ++++++++
 .../private/test/service_reference_test.cpp     | 23 ++++----
 .../private/test/service_registration_test.cpp  | 62 +++-----------------
 .../private/test/service_registry_test.cpp      | 13 +---
 7 files changed, 81 insertions(+), 91 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/celix/blob/47fe773a/framework/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/framework/CMakeLists.txt b/framework/CMakeLists.txt
index 7b447d3..2f1e608 100644
--- a/framework/CMakeLists.txt
+++ b/framework/CMakeLists.txt
@@ -288,18 +288,18 @@ if (FRAMEWORK)
         target_link_libraries(service_registration_test ${CPPUTEST_LIBRARY} ${CPPUTEST_EXT_LIBRARY} celix_utils pthread)
 	    
 	    
-        add_executable(service_registry_test 
-            private/test/service_registry_test.cpp
-            private/mock/framework_mock.c
-            private/mock/bundle_mock.c
-            private/mock/filter_mock.c
-            private/mock/service_reference_mock.c
-            private/mock/service_registration_mock.c
-            private/mock/properties_mock.c
-            private/src/service_registry.c
-            private/src/celix_errorcodes.c
-            private/mock/celix_log_mock.c) 
-        target_link_libraries(service_registry_test ${CPPUTEST_LIBRARY} ${CPPUTEST_EXT_LIBRARY} celix_utils pthread)
+        #add_executable(service_registry_test
+        #    private/test/service_registry_test.cpp
+        #    private/mock/framework_mock.c
+        #    private/mock/bundle_mock.c
+        #    private/mock/filter_mock.c
+        #    private/mock/service_reference_mock.c
+        #    private/mock/service_registration_mock.c
+        #    private/mock/properties_mock.c
+        #    private/src/service_registry.c
+        #    private/src/celix_errorcodes.c
+        #    private/mock/celix_log_mock.c)
+        #target_link_libraries(service_registry_test ${CPPUTEST_LIBRARY} ${CPPUTEST_EXT_LIBRARY} celix_utils pthread)
 	    
         add_executable(service_tracker_customizer_test 
             private/test/service_tracker_customizer_test.cpp

http://git-wip-us.apache.org/repos/asf/celix/blob/47fe773a/framework/private/mock/service_reference_mock.c
----------------------------------------------------------------------
diff --git a/framework/private/mock/service_reference_mock.c b/framework/private/mock/service_reference_mock.c
index da4eede..70fc6c2 100644
--- a/framework/private/mock/service_reference_mock.c
+++ b/framework/private/mock/service_reference_mock.c
@@ -27,14 +27,27 @@
 
 #include "service_reference_private.h"
 
-celix_status_t serviceReference_create(bundle_pt bundle, 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) {
 	mock_c()->actualCall("serviceReference_create")
-			->withPointerParameters("bundle", bundle)
+			->withParameterOfType("registry_callback_t", "callback", &callback)
+			->withPointerParameters("referenceOwner", referenceOwner)
 			->withPointerParameters("registration", registration)
 			->withOutputParameter("reference", (void **) reference);
 	return mock_c()->returnValue().value.intValue;
 }
 
+celix_status_t serviceReference_retain(service_reference_pt ref) {
+    mock_c()->actualCall("serviceReference_retain")
+            ->withPointerParameters("ref", ref);
+    return mock_c()->returnValue().value.intValue;
+}
+celix_status_t serviceReference_release(service_reference_pt ref, bool *destroyed) {
+    mock_c()->actualCall("serviceReference_release")
+            ->withPointerParameters("ref", ref)
+            ->withOutputParameter("destroyed", destroyed);
+    return mock_c()->returnValue().value.intValue;
+}
+
 celix_status_t serviceReference_destroy(service_reference_pt *reference) {
 	mock_c()->actualCall("serviceReference_destroy")
 			->withPointerParameters("reference", *reference);

http://git-wip-us.apache.org/repos/asf/celix/blob/47fe773a/framework/private/mock/service_registration_mock.c
----------------------------------------------------------------------
diff --git a/framework/private/mock/service_registration_mock.c b/framework/private/mock/service_registration_mock.c
index e54be41..fe5466c 100644
--- a/framework/private/mock/service_registration_mock.c
+++ b/framework/private/mock/service_registration_mock.c
@@ -126,5 +126,15 @@ celix_status_t serviceRegistration_getServiceName(service_registration_pt regist
 	return mock_c()->returnValue().value.intValue;
 }
 
+void serviceRegistration_retain(service_registration_pt registration) {
+    mock_c()->actualCall("serviceRegistration_retain")
+            ->withPointerParameters("registration", registration);
+}
+
+void serviceRegistration_release(service_registration_pt registration) {
+    mock_c()->actualCall("serviceRegistration_release")
+            ->withPointerParameters("registration", registration);
+}
+
 
 

http://git-wip-us.apache.org/repos/asf/celix/blob/47fe773a/framework/private/mock/service_registry_mock.c
----------------------------------------------------------------------
diff --git a/framework/private/mock/service_registry_mock.c b/framework/private/mock/service_registry_mock.c
index f5e726e..af877ef 100644
--- a/framework/private/mock/service_registry_mock.c
+++ b/framework/private/mock/service_registry_mock.c
@@ -179,3 +179,26 @@ celix_status_t serviceRegistry_removeReference(service_reference_pt reference) {
     return mock_c()->returnValue().value.intValue;
 }
 
+
+celix_status_t serviceRegistry_getServiceReference(service_registry_pt registry, bundle_pt bundle, service_registration_pt registration, service_reference_pt *reference) {
+	mock_c()->actualCall("serviceRegistry_getServiceReference")
+			->withPointerParameters("registry", registry)
+			->withPointerParameters("bundle", bundle)
+			->withPointerParameters("registration", registration)
+			->withOutputParameter("reference", reference);
+	return mock_c()->returnValue().value.intValue;
+}
+
+celix_status_t serviceRegistry_clearReferencesFor(service_registry_pt registry, bundle_pt bundle) {
+	mock_c()->actualCall("serviceRegistry_clearReferencesFor")
+			->withPointerParameters("registry", registry)
+			->withPointerParameters("bundle", bundle);
+	return mock_c()->returnValue().value.intValue;
+}
+
+celix_status_t serviceRegistry_clearServiceRegistrations(service_registry_pt registry, bundle_pt bundle) {
+	mock_c()->actualCall("serviceRegistry_clearReferencesFor")
+			->withPointerParameters("registry", registry)
+			->withPointerParameters("bundle", bundle);
+	return mock_c()->returnValue().value.intValue;
+}

http://git-wip-us.apache.org/repos/asf/celix/blob/47fe773a/framework/private/test/service_reference_test.cpp
----------------------------------------------------------------------
diff --git a/framework/private/test/service_reference_test.cpp b/framework/private/test/service_reference_test.cpp
index 5d8213a..cb5c0b4 100644
--- a/framework/private/test/service_reference_test.cpp
+++ b/framework/private/test/service_reference_test.cpp
@@ -55,20 +55,21 @@ TEST_GROUP(service_reference) {
 };
 
 TEST(service_reference, create) {
-	bundle_pt bundle = (bundle_pt) 0x10;
+	registry_callback_t callback;
+	bundle_pt owner = (bundle_pt) 0x10;
 	service_registration_pt registration = (service_registration_pt) 0x20;
 
 	service_reference_pt reference = NULL;
-	serviceReference_create(bundle, registration, &reference);
+	serviceReference_create(callback, owner, registration, &reference);
 
-	POINTERS_EQUAL(bundle, reference->bundle);
+	POINTERS_EQUAL(owner, reference->referenceOwner);
 	POINTERS_EQUAL(registration, reference->registration);
 }
 
 TEST(service_reference, getBundle) {
 	service_reference_pt reference = (service_reference_pt) malloc(sizeof(*reference));
 	bundle_pt bundle = (bundle_pt) 0x10;
-	reference->bundle = bundle;
+	reference->registrationBundle = bundle;
 
 	bundle_pt actual = NULL;
 	celix_status_t status = serviceReference_getBundle(reference, &actual);
@@ -129,13 +130,13 @@ TEST(service_reference, equals) {
 	service_registration_pt registration = (service_registration_pt) 0x10;
 	reference->registration = registration;
 	bundle_pt bundle = (bundle_pt) 0x20;
-	reference->bundle = bundle;
+	reference->registrationBundle = bundle;
 
 	service_reference_pt toCompare = (service_reference_pt) malloc(sizeof(*reference));
 	registration = (service_registration_pt) 0x10;
 	toCompare->registration = registration;
 	bundle = (bundle_pt) 0x30;
-	toCompare->bundle = bundle;
+	toCompare->registrationBundle = bundle;
 
 	bool equal = false;
 	celix_status_t status = serviceReference_equals(reference, toCompare, &equal);
@@ -146,7 +147,7 @@ TEST(service_reference, equals) {
 	registration = (service_registration_pt) 0x11;
 	toCompare->registration = registration;
 	bundle = (bundle_pt) 0x30;
-	toCompare->bundle = bundle;
+	toCompare->registrationBundle = bundle;
 
 	equal = true;
 	status = serviceReference_equals(reference, toCompare, &equal);
@@ -159,13 +160,13 @@ TEST(service_reference, equals2) {
 	service_registration_pt registration = (service_registration_pt) 0x10;
 	reference->registration = registration;
 	bundle_pt bundle = (bundle_pt) 0x20;
-	reference->bundle = bundle;
+	reference->registrationBundle = bundle;
 
 	service_reference_pt toCompare = (service_reference_pt) malloc(sizeof(*reference));
 	registration = (service_registration_pt) 0x10;
 	toCompare->registration = registration;
 	bundle = (bundle_pt) 0x30;
-	toCompare->bundle = bundle;
+	toCompare->registrationBundle = bundle;
 
 	bool equal = serviceReference_equals2(reference, toCompare);
 	LONGS_EQUAL(true, equal);
@@ -174,7 +175,7 @@ TEST(service_reference, equals2) {
 	registration = (service_registration_pt) 0x11;
 	toCompare->registration = registration;
 	bundle = (bundle_pt) 0x30;
-	toCompare->bundle = bundle;
+	toCompare->registrationBundle = bundle;
 
 	equal = serviceReference_equals2(reference, toCompare);
 	LONGS_EQUAL(false, equal);
@@ -185,7 +186,7 @@ TEST(service_reference, hashCode) {
 	service_registration_pt registration = (service_registration_pt) 0x10;
 	reference->registration = registration;
 	bundle_pt bundle = (bundle_pt) 0x20;
-	reference->bundle = bundle;
+	reference->registrationBundle = bundle;
 
 	unsigned int hash = serviceReference_hashCode(reference);
 	LONGS_EQUAL(79, hash);

http://git-wip-us.apache.org/repos/asf/celix/blob/47fe773a/framework/private/test/service_registration_test.cpp
----------------------------------------------------------------------
diff --git a/framework/private/test/service_registration_test.cpp b/framework/private/test/service_registration_test.cpp
index a24c804..8677e9f 100644
--- a/framework/private/test/service_registration_test.cpp
+++ b/framework/private/test/service_registration_test.cpp
@@ -73,9 +73,9 @@ TEST(service_registration, create) {
 		.withParameter("value", "service")
 		.andReturnValue((char *) NULL);
 
-	service_registration_pt registration = serviceRegistration_create(registry, bundle, (char *) serviceName.c_str(), serviceId, service, NULL);
+	registry_callback_t callback;
+	service_registration_pt registration = serviceRegistration_create(callback, bundle, (char *) serviceName.c_str(), serviceId, service, NULL);
 
-	POINTERS_EQUAL(registry, registration->registry);
 	STRCMP_EQUAL("service", registration->className);
 	POINTERS_EQUAL(bundle, registration->bundle);
 	POINTERS_EQUAL(properties, registration->properties);
@@ -110,9 +110,9 @@ TEST(service_registration, createServiceFactory) {
 		.withParameter("value", "service")
 		.andReturnValue((char *) NULL);
 
-	service_registration_pt registration = serviceRegistration_createServiceFactory(registry, bundle, (char *) serviceName.c_str(), serviceId, service, NULL);
+    registry_callback_t callback;
+	service_registration_pt registration = serviceRegistration_createServiceFactory(callback, bundle, (char *) serviceName.c_str(), serviceId, service, NULL);
 
-	POINTERS_EQUAL(registry, registration->registry);
 	STRCMP_EQUAL("service", registration->className);
 	POINTERS_EQUAL(bundle, registration->bundle);
 	POINTERS_EQUAL(properties, registration->properties);
@@ -147,7 +147,7 @@ TEST(service_registration, isValidFalse) {
 
 TEST(service_registration, invalidate) {
 	service_registration_pt registration = (service_registration_pt) malloc(sizeof(*registration));
-	celixThreadMutex_create(&registration->mutex, NULL);
+    celixThreadRwlock_create(&registration->lock, NULL);
 	void *service = (void *) 0x30;
 	registration->svcObj = service;
 
@@ -160,9 +160,8 @@ TEST(service_registration, unregisterValid) {
 	service_registry_pt registry = (service_registry_pt) 0x10;
 	bundle_pt bundle = (bundle_pt) 0x20;
 	service_registration_pt registration = (service_registration_pt) malloc(sizeof(*registration));
-	registration->registry = registry;
 	registration->bundle = bundle;
-	celixThreadMutex_create(&registration->mutex, NULL);
+    celixThreadRwlock_create(&registration->lock, NULL);
 	void *service = (void *) 0x30;
 	registration->svcObj = service;
 
@@ -181,9 +180,8 @@ TEST(service_registration, unregisterInvalid) {
 	service_registry_pt registry = (service_registry_pt) 0x10;
 	bundle_pt bundle = (bundle_pt) 0x20;
 	service_registration_pt registration = (service_registration_pt) malloc(sizeof(*registration));
-	registration->registry = registry;
 	registration->bundle = bundle;
-	celixThreadMutex_create(&registration->mutex, NULL);
+    celixThreadRwlock_create(&registration->lock, NULL);
 	registration->svcObj = NULL;
 
 	celix_status_t status = serviceRegistration_unregister(registration);
@@ -245,52 +243,6 @@ TEST(service_registration, getPropertiesIllegalArgument) {
 	LONGS_EQUAL(CELIX_ILLEGAL_ARGUMENT, status);
 }
 
-TEST(service_registration, getRegistry) {
-	service_registration_pt registration = (service_registration_pt) malloc(sizeof(*registration));
-	service_registry_pt registry = (service_registry_pt) 0x10;
-	registration->registry = registry;
-
-	service_registry_pt actual = NULL;
-	celix_status_t status = serviceRegistration_getRegistry(registration, &actual);
-	LONGS_EQUAL(CELIX_SUCCESS, status);
-	POINTERS_EQUAL(registry, actual);
-}
-
-TEST(service_registration, getRegistryIllegalArgument) {
-	service_registration_pt registration = (service_registration_pt) malloc(sizeof(*registration));
-	registration->registry = NULL;
-
-	service_registry_pt actual = (service_registry_pt) 0x01;
-	celix_status_t status = serviceRegistration_getRegistry(registration, &actual);
-	LONGS_EQUAL(CELIX_ILLEGAL_ARGUMENT, status);
-}
- 
-TEST(service_registration, getServiceReferences) {
-	service_registration_pt registration = (service_registration_pt) malloc(sizeof(*registration));
-	array_list_pt references = NULL;
-	//service_registry_pt registry = (service_registry_pt) 0x10;
-	//service_registry_pt registry = (service_registry_pt) 0x0;
-	service_registry_pt registry = registration->registry;
-	bundle_pt bundle = (bundle_pt) 0x20;
-
-	mock().expectOneCall("serviceRegistry_getServiceReferencesForRegistration")
-			.withParameter("registry", registry)
-			.withParameter("registration", registration)
-			.withOutputParameterReturning("references", &references, sizeof(references));
-
-	celix_status_t status = serviceRegistration_getServiceReferences(registration, &references);
-	LONGS_EQUAL(CELIX_SUCCESS, status);
-}
-
-TEST(service_registration, getServiceReferencesIllegalArgument) {
-	service_registration_pt registration = (service_registration_pt) malloc(sizeof(*registration));
-	registration->registry = NULL;
-
-	array_list_pt actual = (array_list_pt) 0x01;
-	celix_status_t status = serviceRegistration_getServiceReferences(registration, &actual);
-	LONGS_EQUAL(CELIX_ILLEGAL_ARGUMENT, status);
-}
-
 TEST(service_registration, getServiceName) {
 	service_registration_pt registration = (service_registration_pt) malloc(sizeof(*registration));
 	std::string serviceName = "service";

http://git-wip-us.apache.org/repos/asf/celix/blob/47fe773a/framework/private/test/service_registry_test.cpp
----------------------------------------------------------------------
diff --git a/framework/private/test/service_registry_test.cpp b/framework/private/test/service_registry_test.cpp
index 507bda2..34dab24 100644
--- a/framework/private/test/service_registry_test.cpp
+++ b/framework/private/test/service_registry_test.cpp
@@ -70,7 +70,6 @@ TEST(service_registry, create) {
 	POINTERS_EQUAL(framework, registry->framework);
 	POINTERS_EQUAL(serviceRegistryTest_serviceChanged, registry->serviceChanged);
 	LONGS_EQUAL(1l, registry->currentServiceId);
-	CHECK(registry->inUseMap != NULL);
 	CHECK(registry->listenerHooks != NULL);
 	//CHECK(registry->mutex != NULL);
 	CHECK(registry->serviceReferences != NULL);
@@ -83,10 +82,7 @@ TEST(service_registry, getRegisteredServices) {
 	service_registry_pt registry = (service_registry_pt) malloc(sizeof(*registry));
 	registry->serviceRegistrations = hashMap_create(NULL, NULL, NULL, NULL);
 	registry->serviceReferences = hashMap_create(NULL, NULL, NULL, NULL);
-	celixThreadMutexAttr_create(&registry->mutexAttr);
-    celixThreadMutexAttr_settype(&registry->mutexAttr, CELIX_THREAD_MUTEX_RECURSIVE);
-    celixThreadMutex_create(&registry->mutex, &registry->mutexAttr);
-	celixThreadMutex_create(&registry->referencesMapMutex, NULL);
+	celixThreadRwlock_create(&registry->lock, NULL);
 	array_list_pt registrations = NULL;
 	arrayList_create(&registrations);
 	service_registration_pt reg = (service_registration_pt) 0x10;
@@ -132,12 +128,7 @@ TEST(service_registry, getRegisteredServices) {
 
 TEST(service_registry, getServicesInUse) {
 	service_registry_pt registry = (service_registry_pt) malloc(sizeof(*registry));
-	registry->inUseMap = hashMap_create(NULL, NULL, NULL, NULL);
-	celixThreadMutexAttr_create(&registry->mutexAttr);
-    celixThreadMutexAttr_settype(&registry->mutexAttr, CELIX_THREAD_MUTEX_RECURSIVE);
-    celixThreadMutex_create(&registry->mutex, &registry->mutexAttr);
-
-	celixThreadMutex_create(&registry->referencesMapMutex, NULL);
+	celixThreadRwlock_create(&registry->lock, NULL);
 
 	array_list_pt usages = NULL;
 	arrayList_create(&usages);


[17/38] celix git commit: CELIX-272: Fix in incorrect call to bundleContext_ungetService from service_tracker.

Posted by pn...@apache.org.
CELIX-272: Fix in incorrect call to bundleContext_ungetService from service_tracker.


Project: http://git-wip-us.apache.org/repos/asf/celix/repo
Commit: http://git-wip-us.apache.org/repos/asf/celix/commit/1836ed49
Tree: http://git-wip-us.apache.org/repos/asf/celix/tree/1836ed49
Diff: http://git-wip-us.apache.org/repos/asf/celix/diff/1836ed49

Branch: refs/heads/develop
Commit: 1836ed49794033d599d78af76440ea8b6d377e5d
Parents: e651c8a
Author: Pepijn Noltes <pe...@gmail.com>
Authored: Thu Nov 12 17:37:11 2015 +0100
Committer: Pepijn Noltes <pe...@gmail.com>
Committed: Thu Nov 12 17:40:27 2015 +0100

----------------------------------------------------------------------
 framework/private/src/service_tracker.c                         | 2 +-
 remote_services/remote_service_admin_dfi/rsa_tst/CMakeLists.txt | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/celix/blob/1836ed49/framework/private/src/service_tracker.c
----------------------------------------------------------------------
diff --git a/framework/private/src/service_tracker.c b/framework/private/src/service_tracker.c
index b5edbd6..23db0aa 100644
--- a/framework/private/src/service_tracker.c
+++ b/framework/private/src/service_tracker.c
@@ -346,7 +346,7 @@ static celix_status_t serviceTracker_untrack(service_tracker_pt tracker, service
 		if (equals) {
 			arrayList_remove(tracker->tracked, i);
             serviceTracker_invokeRemovingService(tracker, tracked->reference, tracked->service);
-            bundleContext_ungetService(tracker->context, tracked->reference, tracked->service);
+            bundleContext_ungetService(tracker->context, tracked->reference, NULL);
 			free(tracked);
             break;
 		}

http://git-wip-us.apache.org/repos/asf/celix/blob/1836ed49/remote_services/remote_service_admin_dfi/rsa_tst/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_dfi/rsa_tst/CMakeLists.txt b/remote_services/remote_service_admin_dfi/rsa_tst/CMakeLists.txt
index e666e92..99d6a23 100644
--- a/remote_services/remote_service_admin_dfi/rsa_tst/CMakeLists.txt
+++ b/remote_services/remote_service_admin_dfi/rsa_tst/CMakeLists.txt
@@ -32,7 +32,7 @@ SET(CMAKE_INSTALL_RPATH "${PROJECT_BINARY_DIR}/framework" "${PROJECT_BINARY_DIR}
 
 add_executable(test_rsa_dfi
     run_tests.cpp
-    #rsa_tests.cpp
+    rsa_tests.cpp
     rsa_client_server_tests.cpp
 
     ${PROJECT_SOURCE_DIR}/remote_services/remote_service_admin/private/src/endpoint_description.c


[05/38] celix git commit: CELIX-272: Refactoring of ServiceRegistry. Added warning log of incorrect handling service refs/regs

Posted by pn...@apache.org.
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/develop
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, &regProps);
-            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, &regProps);
+                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, &registry);
-
-	*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, &reg1);
+    serviceReference_getServiceRegistration(compareTo, &reg2);
+	*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(&registration->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(&registry->mutexAttr);
     celixThreadMutex_destroy(&registry->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(&registry->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(&registry->mutex);
@@ -248,27 +177,17 @@ celix_status_t serviceRegistry_unregisterService(service_registry_pt registry, b
 	}
 
 	celixThreadMutex_lock(&registry->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(&registry->mutex);
-	regs = (array_list_pt) hashMap_get(registry->serviceRegistrations, bundle);
-	celixThreadMutex_unlock(&registry->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(&registry->mutex);
-		array_list_pt removed = hashMap_remove(registry->serviceRegistrations, bundle);
-		celixThreadMutex_unlock(&registry->mutex);
-		arrayList_destroy(removed);
-		removed = NULL;
-	}
 
-	celixThreadMutex_lock(&registry->mutex);
-	hashMap_remove(registry->serviceRegistrations, bundle);
-	celixThreadMutex_unlock(&registry->mutex);
+    celixThreadMutex_lock(&registry->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(&registry->mutex);
 
-	serviceRegistration_getBundle(registration, &bundle);
-	serviceReference_create(bundle, registration, reference);
 
-	// Lock
-	celixThreadMutex_lock(&registry->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(&registry->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(&registry->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(&registry->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, &reg);
-                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(&registry->referencesMapMutex);
+    if (status == CELIX_SUCCESS) {
+        *out = ref;
+    }
 
-    return status;
+    // Unlock
+	celixThreadMutex_unlock(&registry->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(&registry->mutex);
+    serviceReference_getUsageCount(reference, &count);
+    serviceReference_getServiceRegistration(reference, &reg);
+    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(&registry->mutex);
+    return status;
+}
 
-    celixThreadMutex_lock(&registry->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(&registry->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(&registry->referencesMapMutex);
-    array_list_pt references = hashMap_get(registry->serviceReferences, owner);
-    celixThreadMutex_unlock(&registry->referencesMapMutex);
+    celixThreadMutex_lock(&registry->mutex);
+    hash_map_pt refsMap = hashMap_remove(registry->serviceReferences, bundle);
+    celixThreadMutex_unlock(&registry->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(&registry->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(&registry->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, &registration);
 	
 	celixThreadMutex_lock(&registry->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(&registry->mutex);
-
-	if ((usage != NULL) && (*service == NULL)) {
-		status = serviceRegistration_getService(registration, bundle, service);
-	}
-	celixThreadMutex_lock(&registry->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(&registry->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, &registration);
-
-	celixThreadMutex_lock(&registry->mutex);
-
-	status = serviceRegistry_getUsageCount(registry, bundle, reference, &usage);
-	if (usage == NULL) {
-		celixThreadMutex_unlock(&registry->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(&registry->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(&registry->mutex);
-	usages = hashMap_get(registry->inUseMap, bundle);
-	celixThreadMutex_unlock(&registry->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(&registry->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(&registry->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(&registry->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);