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/feature/CELIX-272_synchronization_service_registry
Commit: e0231e51e4cac30018c7a71f9469e838348f642b
Parents: e9f2baa
Author: Pepijn Noltes <[email protected]>
Authored: Mon Nov 9 18:06:18 2015 +0100
Committer: Pepijn Noltes <[email protected]>
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:[email protected]";>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:[email protected]";>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:[email protected]";>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:[email protected]";>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:[email protected]";>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:[email protected]";>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;
 }

Reply via email to