celix-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From pnol...@apache.org
Subject [1/3] celix git commit: CELIX-272: Add locking to service_tracker. NULL check to servRef_equals. Enable mutex benchmark.
Date Thu, 19 Nov 2015 15:37:34 GMT
Repository: celix
Updated Branches:
  refs/heads/develop d72713e6c -> 254d7bf1f


CELIX-272: Add locking to service_tracker. NULL check to servRef_equals. Enable mutex benchmark.


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

Branch: refs/heads/develop
Commit: ab4f80ba39bf6f5719fef107679a3c126cde2478
Parents: 1ab9d02
Author: Pepijn Noltes <pepijnnoltes@gmail.com>
Authored: Thu Nov 19 16:18:42 2015 +0100
Committer: Pepijn Noltes <pepijnnoltes@gmail.com>
Committed: Thu Nov 19 16:18:42 2015 +0100

----------------------------------------------------------------------
 examples/CMakeLists.txt                         |   2 +-
 examples/locking/CMakeLists.txt                 |   8 +-
 examples/locking/benchmark/CMakeLists.txt       |  10 +-
 .../private/src/benchmark_runner_activator.c    | 176 +++++++++++--------
 .../benchmark/public/include/benchmark_result.h |   1 +
 .../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  |  16 +-
 examples/locking/deploy.cmake                   |  26 +++
 examples/locking/math_provider/CMakeLists.txt   |  11 +-
 .../math_provider/private/src/math_component.c  |   5 +-
 .../private/src/provider_activator.c            |  50 +++---
 examples/locking/mutex_benchmark/CMakeLists.txt |  11 +-
 .../private/src/mutex_benchmark.c               |  13 +-
 examples/locking/services/benchmark_service.h   |  27 +++
 examples/locking/services/frequency_service.h   |  47 +++++
 examples/locking/services/math_service.h        |  40 +++++
 .../private/include/service_tracker_private.h   |   4 +-
 framework/private/src/service_reference.c       |  18 +-
 framework/private/src/service_tracker.c         | 103 +++++++----
 21 files changed, 399 insertions(+), 283 deletions(-)
----------------------------------------------------------------------


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

http://git-wip-us.apache.org/repos/asf/celix/blob/ab4f80ba/examples/locking/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/examples/locking/CMakeLists.txt b/examples/locking/CMakeLists.txt
index e6c80ab..ccbdb70 100644
--- a/examples/locking/CMakeLists.txt
+++ b/examples/locking/CMakeLists.txt
@@ -15,10 +15,12 @@
 # specific language governing permissions and limitations
 # under the License.
 
+include_directories(services)
+
 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)
+#add_subdirectory(reference_benchmark)
+#add_subdirectory(start_stop_benchmark)
+#add_subdirectory(modified_bool_benchmark)

http://git-wip-us.apache.org/repos/asf/celix/blob/ab4f80ba/examples/locking/benchmark/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/examples/locking/benchmark/CMakeLists.txt b/examples/locking/benchmark/CMakeLists.txt
index ce5db7c..12db9f5 100644
--- a/examples/locking/benchmark/CMakeLists.txt
+++ b/examples/locking/benchmark/CMakeLists.txt
@@ -18,13 +18,15 @@
 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)
+include_directories(${PROJECT_SOURCE_DIR}/shell/public/include)
+
+bundle(benchmark_runner SOURCES
+	private/src/benchmark_runner_activator 
+)
 
 target_link_libraries(benchmark_runner celix_framework)
+

http://git-wip-us.apache.org/repos/asf/celix/blob/ab4f80ba/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
index e06b77b..99af502 100644
--- a/examples/locking/benchmark/private/src/benchmark_runner_activator.c
+++ b/examples/locking/benchmark/private/src/benchmark_runner_activator.c
@@ -29,13 +29,14 @@
 #include <stdlib.h>
 #include <unistd.h>
 #include <sys/time.h>
-#include <sys/queue.h>
 
 #include <pthread.h>
+#include <string.h>
+#include <assert.h>
+
+#include "command.h"
 
 #include "bundle_activator.h"
-#include "bundle_context.h"
-#include "service_registration.h"
 #include "service_tracker.h"
 
 #include "benchmark_service.h"
@@ -46,26 +47,25 @@ static celix_status_t benchmarkRunner_addedService(void * handle, service_refere
 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);
+static void benchmarkRunner_runBenchmark(struct activator *activator, FILE *out);
+static void benchmarkRunner_printHeader(char *name, unsigned int nrOfSamples, FILE *out);
+static void benchmarkRunner_printResult(benchmark_result_t result, double updateFreq, unsigned long elapsedTime,
+                                       FILE *out);
+static void benchmarkRunner_printFooter(char *name, FILE *out);
+static celix_status_t benchmarkRunner_execute(void *handle, char * line, FILE *out, FILE *err);
 
-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;
+	benchmark_service_pt benchmark;
 	frequency_service_pt freqService;
+
+    command_service_pt command;
+    service_registration_pt reg;
 };
 
 celix_status_t bundleActivator_create(bundle_context_pt context, void **userData) {
@@ -73,11 +73,9 @@ celix_status_t bundleActivator_create(bundle_context_pt context, void **userData
 	activator->context=context;
 	activator->customizer = NULL;
 	activator->tracker= NULL;
-	activator->benchmarks = NULL;
+	activator->benchmark = NULL;
 	activator->freqService = NULL;
 
-	LIST_INIT(&activator->benchmarkEntries);
-
 	*userData = activator;
 
 	return CELIX_SUCCESS;
@@ -89,8 +87,6 @@ celix_status_t bundleActivator_start(void * userData, bundle_context_pt context)
 
 	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];
@@ -98,30 +94,40 @@ celix_status_t bundleActivator_start(void * userData, bundle_context_pt context)
 	serviceTracker_createWithFilter(context, filter, activator->customizer, &activator->tracker);
 	serviceTracker_open(activator->tracker);
 
-	pthread_create(&activator->thread, NULL, (void *)benchmarkRunner_runBenchmark, activator);
+
+    activator->reg = NULL;
+    activator->command = calloc(1, sizeof(*activator->command));
+    activator->command->handle = activator;
+    activator->command->executeCommand = benchmarkRunner_execute;
+    properties_pt props = properties_create();
+    properties_set(props, OSGI_SHELL_COMMAND_NAME, "benchmark");
+    properties_set(props, OSGI_SHELL_COMMAND_USAGE, "benchmark run");
+    properties_set(props, OSGI_SHELL_COMMAND_DESCRIPTION, "run the available benchmark");
+
+    bundleContext_registerService(context, (char *)OSGI_SHELL_COMMAND_SERVICE_NAME, activator->command, props, &activator->reg);
 
 	return status;
 }
 
 
-celix_status_t bundleActivator_stop(void * userData, bundle_context_pt context) {
+celix_status_t bundleActivator_stop(void * userData, bundle_context_pt context __attribute__((unused))) {
 	struct activator * activator = userData;
 
-	pthread_join(activator->thread, NULL);
-
 	serviceTracker_close(activator->tracker);
 
+    serviceRegistration_unregister(activator->reg);
+
 	return CELIX_SUCCESS;
 }
 
-celix_status_t bundleActivator_destroy(void * userData, bundle_context_pt context) {
+celix_status_t bundleActivator_destroy(void * userData, bundle_context_pt context __attribute__((unused))) {
 	struct activator * activator = userData;
-
+    free(activator);
 	return CELIX_SUCCESS;
 }
 
 static celix_status_t benchmarkRunner_addingService(void * handle, service_reference_pt reference, void **service) {
-	celix_status_t status = CELIX_SUCCESS;
+	celix_status_t status;
 	struct activator * activator = handle;
 	status = bundleContext_getService(activator->context, reference, service);
 	return status;
@@ -139,7 +145,7 @@ static celix_status_t benchmarkRunner_addedService(void * handle, service_refere
 	serviceName = properties_get(properties, "objectClass");
 	if (strcmp(serviceName, BENCHMARK_SERVICE_NAME) == 0) {
 		pthread_mutex_lock(&activator->mutex);
-		arrayList_add(activator->benchmarks, service);
+		activator->benchmark = service;
 		pthread_mutex_unlock(&activator->mutex);
 	} else if (strcmp(serviceName, FREQUENCY_SERVICE_NAME) == 0 ) {
 		pthread_mutex_lock(&activator->mutex);
@@ -149,9 +155,9 @@ static celix_status_t benchmarkRunner_addedService(void * handle, service_refere
 
 	return status;
 }
-static celix_status_t benchmarkRunner_modifiedService(void * handle, service_reference_pt reference, void * service) {
+static celix_status_t benchmarkRunner_modifiedService(void * handle __attribute__((unused)), service_reference_pt reference __attribute__((unused)), void * service __attribute__((unused))) {
 	celix_status_t status = CELIX_SUCCESS;
-	struct activator * activator = handle;
+	//ignore
 	return status;
 }
 
@@ -167,7 +173,9 @@ static celix_status_t benchmarkRunner_removedService(void * handle, service_refe
 		serviceName = properties_get(properties, "objectClass");
 		if (strcmp(serviceName, BENCHMARK_SERVICE_NAME) == 0) {
 			pthread_mutex_lock(&activator->mutex);
-			arrayList_removeElement(activator->benchmarks, service);
+			if (activator->benchmark == service) {
+				activator->benchmark = NULL;
+			}
 			pthread_mutex_unlock(&activator->mutex);
 		} else if (strcmp(serviceName, FREQUENCY_SERVICE_NAME) == 0 ) {
 			pthread_mutex_lock(&activator->mutex);
@@ -180,10 +188,10 @@ static celix_status_t benchmarkRunner_removedService(void * handle, service_refe
 	return status;
 }
 
-static void benchmarkRunner_runBenchmark(struct activator *activator) {
-	int i, k;
-	int nrOfBenchmarks;
-	double updateFrequency, measuredFrequency;
+static void benchmarkRunner_runBenchmark(struct activator *activator, FILE *out) {
+	int k;
+	double updateFrequency;
+    double measuredFrequency = 0.0;
 	unsigned int measuredUpdateCounter, nrOfUpdateThreads;
 	int nrOfSamples;
 	benchmark_service_pt benchmarkServ;
@@ -193,6 +201,7 @@ static void benchmarkRunner_runBenchmark(struct activator *activator) {
 	unsigned long elapsedTime;
 	double sampleFactor;
 
+
 	int nrOfThreadRuns = 12;
 	int threads[] = {1,2,3,4,5,6,7,8,16,32,64,128};
 
@@ -200,56 +209,81 @@ static void benchmarkRunner_runBenchmark(struct activator *activator) {
 	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);
+	benchmarkServ = activator->benchmark;
+	name = benchmarkServ->name(benchmarkServ->handler);
+	sampleFactor = benchmarkServ->getSampleFactor(benchmarkServ->handler);
+	activator->freqService->setBenchmarkName(activator->freqService->handle, name);
+	usleep(1000);
+    benchmarkRunner_printHeader(name, nrOfSamples * (int)sampleFactor, out);
+	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_printFooter(name);
+        benchmarkRunner_printResult(result, measuredFrequency, elapsedTime, out);
 	}
+    benchmarkRunner_printFooter(name, out);
+
 	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_printHeader(char *name, unsigned int nrOfSamples, FILE *out) {
+		fprintf(out, "---%35s---------------------------------------------------------------------------------------\n", name);
+		fprintf(out, "-------samples: %10i---------------------------------------------------------------------------------------------------\n", nrOfSamples);
+}
+
+static void benchmarkRunner_printResult(benchmark_result_t result, double updateFreq, unsigned long elapsedTime,
+                                       FILE *out) {
+	fprintf(out, "| threads %5i | ", result.nrOfThreads);
+	fprintf(out, "average call time: %10.2f nanoseconds | ", result.averageCallTimeInNanoseconds);
+	fprintf(out, "frequency calls is %10.5f MHz | ", result.callFrequencyInMhz);
+	fprintf(out, "update freq ~ %8.2f Hz | ", updateFreq);
+	fprintf(out, "elapsed time is %8.5f seconds | ", ((double)elapsedTime) / 1000000);
+    if (result.skips > 0 ) {
+        fprintf(out, "Warning skipped %i calls", result.skips);
+    }
+	fprintf(out, "\n");
 }
 
-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 __attribute__((unused)), FILE *out) {
+	fprintf(out, "-----------------------------------------------------------------------------------------------------------------------------\n\n\n");
 }
 
-static void benchmarkRunner_printFooter(char *name) {
-	printf("-----------------------------------------------------------------------------------------------------------------------------\n\n\n");
+static celix_status_t benchmarkRunner_execute(void *handle, char * line, FILE *out, FILE *err) {
+    struct activator * activator = handle;
+    char *savePtr;
+    char *token = NULL;
+    token = strtok_r(line, " ", &savePtr); //command name
+    assert(strcmp(token, "benchmark") == 0);
+    token = strtok_r(NULL, " ", &savePtr); //sub command
+    if (strcmp("run", token) == 0) {
+        token = strtok_r(NULL, " ", &savePtr); //possible nr of time to run
+        int times = 1;
+        int i;
+        if (token != NULL) {
+            times = atoi(token);
+        }
+        for (i = 0; i < times; i += 1) {
+            fprintf(out, "running benchmark %i of %i\n", i+1, times);
+            benchmarkRunner_runBenchmark(activator, out);
+        }
+    } else {
+        fprintf(err, "Unknown subcommand '%s'\n", token);
+    }
+
+    return CELIX_SUCCESS;
 }

http://git-wip-us.apache.org/repos/asf/celix/blob/ab4f80ba/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
index e0750a8..e7f32d0 100644
--- a/examples/locking/benchmark/public/include/benchmark_result.h
+++ b/examples/locking/benchmark/public/include/benchmark_result.h
@@ -11,6 +11,7 @@
 typedef struct benchmark_result {
 		unsigned int nrOfThreads;
 		unsigned int nrOfsamples;
+		uint requestedNrOfSamples;
 		unsigned int result;
 		unsigned int skips;
 		double averageCallTimeInNanoseconds;

http://git-wip-us.apache.org/repos/asf/celix/blob/ab4f80ba/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
deleted file mode 100644
index 63ada04..0000000
--- a/examples/locking/benchmark/public/include/benchmark_service.h
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * 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/ab4f80ba/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
deleted file mode 100644
index 5c022ce..0000000
--- a/examples/locking/benchmark/public/include/frequency_service.h
+++ /dev/null
@@ -1,47 +0,0 @@
-/**
- *Licensed to the Apache Software Foundation (ASF) under one
- *or more contributor license agreements.  See the NOTICE file
- *distributed with this work for additional information
- *regarding copyright ownership.  The ASF licenses this file
- *to you under the Apache License, Version 2.0 (the
- *"License"); you may not use this file except in compliance
- *with the License.  You may obtain a copy of the License at
- *
- *  http://www.apache.org/licenses/LICENSE-2.0
- *
- *Unless required by applicable law or agreed to in writing,
- *software distributed under the License is distributed on an
- *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- *specific language governing permissions and limitations
- *under the License.
- */
-/*
- * frequence_service.h
- *
- *  \date       Feb 4, 2014
- *  \author    	<a href="mailto:celix-dev@incubator.apache.org">Apache Celix Project Team</a>
- *  \copyright	Apache License, Version 2.0
- */
-
-//TODO change to math provider service ???
-
-#ifndef FREQUENCY_SERVICE_H
-#define FREQUENCY_SERVICE_H
-
-#define FREQUENCY_SERVICE_NAME "frequency_service"
-
-typedef struct frequency_hander frequence_handler_t;
-
-struct frequency_service {
-	frequence_handler_t *handle;
-	void (*setFrequency)(frequence_handler_t *handle, int freq);
-	void (*resetCounter)(frequence_handler_t *handle);
-	uint (*getCounter)(frequence_handler_t *handle);
-	void (*setBenchmarkName)(frequence_handler_t *handle, char *name);
-	void (*setNrOfThreads)(frequence_handler_t *handle, uint nrOfThreads);
-};
-
-typedef struct frequency_service * frequency_service_pt;
-
-#endif /* FREQUENCY_SERVICE_H */

http://git-wip-us.apache.org/repos/asf/celix/blob/ab4f80ba/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
deleted file mode 100644
index 154cc9c..0000000
--- a/examples/locking/benchmark/public/include/math_service.h
+++ /dev/null
@@ -1,40 +0,0 @@
-/**
- *Licensed to the Apache Software Foundation (ASF) under one
- *or more contributor license agreements.  See the NOTICE file
- *distributed with this work for additional information
- *regarding copyright ownership.  The ASF licenses this file
- *to you under the Apache License, Version 2.0 (the
- *"License"); you may not use this file except in compliance
- *with the License.  You may obtain a copy of the License at
- *
- *  http://www.apache.org/licenses/LICENSE-2.0
- *
- *Unless required by applicable law or agreed to in writing,
- *software distributed under the License is distributed on an
- *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- *specific language governing permissions and limitations
- *under the License.
- */
-/*
- * echo_server.h
- *
- *  \date       Sep 21, 2010
- *  \author    	<a href="mailto:celix-dev@incubator.apache.org">Apache Celix Project Team</a>
- *  \copyright	Apache License, Version 2.0
- */
-
-#ifndef MATH_SERVICE_H 
-#define MATH_SERVICE_H 
-
-#define MATH_SERVICE_NAME "math_service"
-
-
-struct math_service {
-	void *handle;
-	int (*calc)(void *handle, int arg1, int arg2);
-};
-
-typedef struct math_service * math_service_pt;
-
-#endif /* MATH_SERVICE_H */

http://git-wip-us.apache.org/repos/asf/celix/blob/ab4f80ba/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
index a161f11..ffd9621 100644
--- a/examples/locking/benchmark/public/src/benchmark_activator.c
+++ b/examples/locking/benchmark/public/src/benchmark_activator.c
@@ -36,9 +36,7 @@
 #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 {
@@ -69,7 +67,7 @@ celix_status_t bundleActivator_start(void * userData, bundle_context_pt context)
 	struct activator * activator = userData;
 
 	status = benchmark_create(&activator->benchmark);
-	serviceTrackerCustomizer_create(activator, addingService, addedService, modifiedService, removedService, &activator->customizer);
+	serviceTrackerCustomizer_create(activator, NULL, addedService, NULL, removedService, &activator->customizer);
 
 	char filter[128];
 	sprintf(filter, "(&(objectClass=%s)(benchmark=%s))", MATH_SERVICE_NAME, benchmark_getName(activator->benchmark));
@@ -106,24 +104,12 @@ celix_status_t bundleActivator_destroy(void * userData, bundle_context_pt contex
 	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;

http://git-wip-us.apache.org/repos/asf/celix/blob/ab4f80ba/examples/locking/deploy.cmake
----------------------------------------------------------------------
diff --git a/examples/locking/deploy.cmake b/examples/locking/deploy.cmake
new file mode 100644
index 0000000..ddc784e
--- /dev/null
+++ b/examples/locking/deploy.cmake
@@ -0,0 +1,26 @@
+# 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.
+is_enabled(EXAMPLES)
+if (EXAMPLES)
+
+	#deploy("locking_example_reference" BUNDLES benchmark_runner reference_benchmark math_provider shell shell_tui log_service log_writer)
+	deploy("locking_example_mutex" BUNDLES benchmark_runner mutex_benchmark math_provider shell shell_tui log_service log_writer)
+
+	#deploy("locking_example_suspend" BUNDLES benchmark_runner start_stop_benchmark math_provider shell shell_tui log_service log_writer)
+	#deploy("locking_example_rcu" BUNDLES benchmark_runner rcu_benchmark mutex_benchmark math_provider shell shell_tui log_service log_writer)
+
+endif (EXAMPLES)

http://git-wip-us.apache.org/repos/asf/celix/blob/ab4f80ba/examples/locking/math_provider/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/examples/locking/math_provider/CMakeLists.txt b/examples/locking/math_provider/CMakeLists.txt
index 288d6ba..31be386 100644
--- a/examples/locking/math_provider/CMakeLists.txt
+++ b/examples/locking/math_provider/CMakeLists.txt
@@ -18,15 +18,16 @@
 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)
+
+bundle(math_provider SOURCES 
+	private/src/provider_activator 
+	private/src/math_component
+)
+
 target_link_libraries(math_provider celix_framework)

http://git-wip-us.apache.org/repos/asf/celix/blob/ab4f80ba/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
index 2937fee..3e51890 100644
--- a/examples/locking/math_provider/private/src/math_component.c
+++ b/examples/locking/math_provider/private/src/math_component.c
@@ -5,6 +5,7 @@
  *      Author: dl436
  */
 
+#include <stdlib.h>
 #include "math_component.h"
 
 struct math_component {
@@ -12,7 +13,7 @@ struct math_component {
 };
 
 celix_status_t mathComponent_create(math_component_pt *math) {
-	(*math) = malloc(sizeof(struct math_component));
+	(*math) = calloc(1, sizeof(struct math_component));
 	return CELIX_SUCCESS;
 }
 
@@ -21,7 +22,7 @@ celix_status_t mathComponent_destroy(math_component_pt math) {
 	return CELIX_SUCCESS;
 }
 
-int mathComponent_calc(math_component_pt math, int arg1, int arg2) {
+int mathComponent_calc(math_component_pt math __attribute__((unused)), int arg1, int arg2) {
 	return arg1 * arg2 + arg2;
 }
 

http://git-wip-us.apache.org/repos/asf/celix/blob/ab4f80ba/examples/locking/math_provider/private/src/provider_activator.c
----------------------------------------------------------------------
diff --git a/examples/locking/math_provider/private/src/provider_activator.c b/examples/locking/math_provider/private/src/provider_activator.c
index 0407005..3c0b2d7 100644
--- a/examples/locking/math_provider/private/src/provider_activator.c
+++ b/examples/locking/math_provider/private/src/provider_activator.c
@@ -25,12 +25,13 @@
  */
 #include <stdlib.h>
 #include <unistd.h>
-#include <stdbool.h>
-#include <sys/time.h>
+#include <string.h>
+#include <pthread.h>
+#include <signal.h>
+
+
 
 #include "bundle_activator.h"
-#include "bundle_context.h"
-#include "service_registration.h"
 
 #include "math_service.h"
 #include "frequency_service.h"
@@ -38,6 +39,7 @@
 
 typedef struct activator {
 	bundle_context_pt context;
+	bool isRunning;
 
 	frequency_service_pt freqService;
 	service_registration_pt freqRegistration;
@@ -47,19 +49,17 @@ typedef struct activator {
 	char *benchmarkName;
 	service_registration_pt registration;
 
-	uint updateFrequency;
+	double updateFrequency;
 	uint nrOfThreads;
 	pthread_t *threads;
 
 
-	volatile uint counter;
-	struct timeval beginMeasurement;
-	struct timeval endMeasurement;
+	uint counter;
 } activator_t;
 
-static int calc(int arg1, int arg2);
-static void run(activator_t *activator);
-static void setFrequency(activator_t *activator, uint freq);
+static int calc(int arg1, int arg2)  __attribute__((unused));
+static void* run(void *data);
+static void setFrequency(activator_t *activator, double freq);
 static void setNrOfThreads(activator_t *activator, uint nrOfThreads);
 static void resetCounter(activator_t *activator);
 static void stopThreads(activator_t *activator);
@@ -86,10 +86,11 @@ celix_status_t bundleActivator_create(bundle_context_pt context, void **userData
 	return CELIX_SUCCESS;
 }
 
-celix_status_t bundleActivator_start(void * userData, bundle_context_pt context) {
+celix_status_t bundleActivator_start(void * userData, bundle_context_pt context __attribute__((unused))) {
 	celix_status_t status = CELIX_SUCCESS;
 	struct activator * activator = userData;
 
+    activator->isRunning = true;
 	activator->mathService = malloc(sizeof(*activator->mathService));
 	activator->mathService->handle = activator->math;
 	activator->mathService->calc = (void *)mathComponent_calc;
@@ -109,7 +110,7 @@ celix_status_t bundleActivator_start(void * userData, bundle_context_pt context)
 	return status;
 }
 
-celix_status_t bundleActivator_stop(void * userData, bundle_context_pt context) {
+celix_status_t bundleActivator_stop(void * userData, bundle_context_pt context __attribute__((unused))) {
 	struct activator * activator = userData;
 
 	printf("Stopping service registration thread\n");
@@ -120,7 +121,7 @@ celix_status_t bundleActivator_stop(void * userData, bundle_context_pt context)
 	return CELIX_SUCCESS;
 }
 
-celix_status_t bundleActivator_destroy(void * userData, bundle_context_pt context) {
+celix_status_t bundleActivator_destroy(void * userData, bundle_context_pt context __attribute__((unused))) {
 	struct echoActivator * activator = userData;
 
 	//TODO free service & freqService struct
@@ -136,15 +137,17 @@ static int calc(int arg1, int arg2) {
 
 static void stopThreads(activator_t *activator) {
 	//cancel and join threads
+    activator->isRunning = false;
 	if (activator->threads != NULL) {
 		for (int i = 0 ; i < activator->nrOfThreads ; i += 1) {
-			pthread_cancel(activator->threads[i]);
+            pthread_kill(activator->threads[i], SIGUSR1);
 			pthread_join(activator->threads[i], NULL);
 		}
 	}
 }
 
 static void startThreads(activator_t *activator, uint nrOfThreads) {
+    activator->isRunning = true;
 	activator->threads = malloc(sizeof(pthread_t) * nrOfThreads);
 	for (int i = 0 ; i < nrOfThreads ; i += 1) {
 		pthread_create(&activator->threads[i], NULL, (void *)run, activator);
@@ -152,13 +155,15 @@ static void startThreads(activator_t *activator, uint nrOfThreads) {
 	activator->nrOfThreads = nrOfThreads;
 }
 
-static void run(activator_t *activator) {
+static void* run(void *data) {
+	activator_t *activator = data;
+
 	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
+
+	while (activator->isRunning) {
  		uint delayInMicroseconds =  activator->updateFrequency == 0 ? 0 : (1000 * 1000) / activator->updateFrequency;
 		if (delayInMicroseconds > 0) {
 			prevReg = currentReg;
@@ -174,6 +179,8 @@ static void run(activator_t *activator) {
 		}
 		usleep(delayInMicroseconds > 0 ? delayInMicroseconds : 1000000);
 	}
+
+    return NULL;
 }
 
 static math_service_pt registerMath(activator_t *activator, service_registration_pt *reg) {
@@ -201,13 +208,14 @@ static void setBenchmarkName(activator_t *activator, char *benchmark) {
 	}
 }
 
-static void setFrequency(activator_t *activator, uint freq) {
-	printf("Setting frequency to %i\n", freq);
+static void setFrequency(activator_t *activator, double freq) {
+	printf("Setting frequency to %f\n", freq);
 	activator->updateFrequency = freq;
 }
 
 static void setNrOfThreads(activator_t *activator, uint nrOfThreads) {
-	stopThreads(activator);
+    printf("Setting nr of update Threads to %d\n", nrOfThreads);
+    stopThreads(activator);
 	startThreads(activator, nrOfThreads);
 }
 

http://git-wip-us.apache.org/repos/asf/celix/blob/ab4f80ba/examples/locking/mutex_benchmark/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/examples/locking/mutex_benchmark/CMakeLists.txt b/examples/locking/mutex_benchmark/CMakeLists.txt
index b822ffa..11aa1f7 100644
--- a/examples/locking/mutex_benchmark/CMakeLists.txt
+++ b/examples/locking/mutex_benchmark/CMakeLists.txt
@@ -18,15 +18,16 @@
 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")
+
+bundle(mutex_benchmark SOURCES
+	../benchmark/public/src/benchmark_activator
+	private/src/mutex_benchmark 
+)
+
 target_link_libraries(mutex_benchmark celix_framework)
 

http://git-wip-us.apache.org/repos/asf/celix/blob/ab4f80ba/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
index 3cacfb8..740361f 100644
--- a/examples/locking/mutex_benchmark/private/src/mutex_benchmark.c
+++ b/examples/locking/mutex_benchmark/private/src/mutex_benchmark.c
@@ -7,8 +7,9 @@
 
 #include <stdlib.h>
 #include <pthread.h>
-#include <unistd.h>
 #include <sys/time.h>
+#include <stdio.h>
+#include <math.h>
 
 #include "benchmark.h"
 
@@ -26,7 +27,7 @@ typedef struct thread_info {
 	unsigned int result;
 	struct timeval begin;
 	struct timeval end;
-	int skips;
+	uint skips;
 } thread_info_t;
 
 static void benchmark_thread(thread_info_t *info);
@@ -66,10 +67,12 @@ benchmark_result_t benchmark_run(benchmark_pt benchmark, int nrOfThreads, int nr
 		result.skips += infos[i].skips;
 	}
 
-	result.averageCallTimeInNanoseconds = ((double)elapsedTime * 1000) / (nrOfSamples * nrOfThreads);
-	result.callFrequencyInMhz = ((double)(nrOfSamples * nrOfThreads) / elapsedTime);
+    uint actualSamples = (nrOfSamples * nrOfThreads) - result.skips;
+	result.averageCallTimeInNanoseconds = actualSamples == 0 ? NAN : ((double)elapsedTime * 1000) / (nrOfSamples * nrOfThreads);
+	result.callFrequencyInMhz = ((double)(actualSamples * nrOfThreads) / elapsedTime);
 	result.nrOfThreads = nrOfThreads;
-	result.nrOfsamples = nrOfSamples;
+	result.nrOfsamples = actualSamples;
+    result.requestedNrOfSamples = (nrOfSamples * nrOfThreads);
 
 	return result;
 }

http://git-wip-us.apache.org/repos/asf/celix/blob/ab4f80ba/examples/locking/services/benchmark_service.h
----------------------------------------------------------------------
diff --git a/examples/locking/services/benchmark_service.h b/examples/locking/services/benchmark_service.h
new file mode 100644
index 0000000..63ada04
--- /dev/null
+++ b/examples/locking/services/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/ab4f80ba/examples/locking/services/frequency_service.h
----------------------------------------------------------------------
diff --git a/examples/locking/services/frequency_service.h b/examples/locking/services/frequency_service.h
new file mode 100644
index 0000000..ceca17e
--- /dev/null
+++ b/examples/locking/services/frequency_service.h
@@ -0,0 +1,47 @@
+/**
+ *Licensed to the Apache Software Foundation (ASF) under one
+ *or more contributor license agreements.  See the NOTICE file
+ *distributed with this work for additional information
+ *regarding copyright ownership.  The ASF licenses this file
+ *to you under the Apache License, Version 2.0 (the
+ *"License"); you may not use this file except in compliance
+ *with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *Unless required by applicable law or agreed to in writing,
+ *software distributed under the License is distributed on an
+ *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ *specific language governing permissions and limitations
+ *under the License.
+ */
+/*
+ * frequence_service.h
+ *
+ *  \date       Feb 4, 2014
+ *  \author    	<a href="mailto:celix-dev@incubator.apache.org">Apache Celix Project Team</a>
+ *  \copyright	Apache License, Version 2.0
+ */
+
+//TODO change to math provider service ???
+
+#ifndef FREQUENCY_SERVICE_H
+#define FREQUENCY_SERVICE_H
+
+#define FREQUENCY_SERVICE_NAME "frequency_service"
+
+typedef struct frequency_hander frequence_handler_t;
+
+struct frequency_service {
+	frequence_handler_t *handle;
+	void (*setFrequency)(frequence_handler_t *handle, double 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/ab4f80ba/examples/locking/services/math_service.h
----------------------------------------------------------------------
diff --git a/examples/locking/services/math_service.h b/examples/locking/services/math_service.h
new file mode 100644
index 0000000..23de461
--- /dev/null
+++ b/examples/locking/services/math_service.h
@@ -0,0 +1,40 @@
+/**
+ *Licensed to the Apache Software Foundation (ASF) under one
+ *or more contributor license agreements.  See the NOTICE file
+ *distributed with this work for additional information
+ *regarding copyright ownership.  The ASF licenses this file
+ *to you under the Apache License, Version 2.0 (the
+ *"License"); you may not use this file except in compliance
+ *with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *Unless required by applicable law or agreed to in writing,
+ *software distributed under the License is distributed on an
+ *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ *specific language governing permissions and limitations
+ *under the License.
+ */
+/*
+ * echo_server.h
+ *
+ *  \date       Sep 21, 2010
+ *  \author    	<a href="mailto:celix-dev@incubator.apache.org">Apache Celix Project Team</a>
+ *  \copyright	Apache License, Version 2.0
+ */
+
+#ifndef MATH_SERVICE_H 
+#define MATH_SERVICE_H 
+
+#define MATH_SERVICE_NAME "math_service"
+
+
+struct math_service {
+	void *handle;
+	int (*calc)(void *handle, int arg1, int arg2);
+};
+
+typedef struct math_service *math_service_pt;
+
+#endif /* MATH_SERVICE_H */

http://git-wip-us.apache.org/repos/asf/celix/blob/ab4f80ba/framework/private/include/service_tracker_private.h
----------------------------------------------------------------------
diff --git a/framework/private/include/service_tracker_private.h b/framework/private/include/service_tracker_private.h
index 219e039..1d80ba1 100644
--- a/framework/private/include/service_tracker_private.h
+++ b/framework/private/include/service_tracker_private.h
@@ -37,7 +37,9 @@ struct serviceTracker {
 	service_tracker_pt tracker;
 	service_tracker_customizer_pt customizer;
 	service_listener_pt listener;
-	array_list_pt tracked;
+
+	celix_thread_rwlock_t lock; //projects trackedServices
+	array_list_pt trackedServices;
 };
 
 struct tracked {

http://git-wip-us.apache.org/repos/asf/celix/blob/ab4f80ba/framework/private/src/service_reference.c
----------------------------------------------------------------------
diff --git a/framework/private/src/service_reference.c b/framework/private/src/service_reference.c
index dfbafd0..0916a37 100644
--- a/framework/private/src/service_reference.c
+++ b/framework/private/src/service_reference.c
@@ -256,12 +256,18 @@ bool serviceReference_isAssignableTo(service_reference_pt reference __attribute_
 }
 
 celix_status_t serviceReference_equals(service_reference_pt reference, service_reference_pt compareTo, bool *equal) {
-    service_registration_pt reg1;
-    service_registration_pt reg2;
-    serviceReference_getServiceRegistration(reference, &reg1);
-    serviceReference_getServiceRegistration(compareTo, &reg2);
-	*equal = (reg1 == reg2);
-	return CELIX_SUCCESS;
+    celix_status_t status = CELIX_SUCCESS;
+    if (reference != NULL && compareTo != NULL) {
+        service_registration_pt reg1;
+        service_registration_pt reg2;
+        serviceReference_getServiceRegistration(reference, &reg1);
+        serviceReference_getServiceRegistration(compareTo, &reg2);
+        *equal = (reg1 == reg2);
+    } else {
+        status = CELIX_ILLEGAL_ARGUMENT;
+        *equal = false;
+    }
+	return status;
 }
 
 int serviceReference_equals2(void *reference1, void *reference2) {

http://git-wip-us.apache.org/repos/asf/celix/blob/ab4f80ba/framework/private/src/service_tracker.c
----------------------------------------------------------------------
diff --git a/framework/private/src/service_tracker.c b/framework/private/src/service_tracker.c
index 8234cce..4256c52 100644
--- a/framework/private/src/service_tracker.c
+++ b/framework/private/src/service_tracker.c
@@ -28,6 +28,7 @@
 #include <stdio.h>
 #include <service_reference_private.h>
 #include <framework_private.h>
+#include <assert.h>
 
 #include "service_tracker_private.h"
 #include "bundle_context.h"
@@ -74,8 +75,9 @@ celix_status_t serviceTracker_createWithFilter(bundle_context_pt context, char *
 		(*tracker)->filter = strdup(filter);
 
 		(*tracker)->tracker = *tracker;
-		(*tracker)->tracked = NULL;
-		arrayList_create(&(*tracker)->tracked);
+        celixThreadRwlock_create(&(*tracker)->lock, NULL);
+		(*tracker)->trackedServices = NULL;
+		arrayList_create(&(*tracker)->trackedServices);
 		(*tracker)->customizer = customizer;
 		(*tracker)->listener = NULL;
 	}
@@ -92,12 +94,18 @@ celix_status_t serviceTracker_destroy(service_tracker_pt tracker) {
 	if (tracker->customizer != NULL) {
 	    serviceTrackerCustomizer_destroy(tracker->customizer);
 	}
-	arrayList_destroy(tracker->tracked);
+
+    celixThreadRwlock_writeLock(&tracker->lock);
+	arrayList_destroy(tracker->trackedServices);
+    celixThreadRwlock_unlock(&tracker->lock);
+
 
 	if (tracker->listener != NULL) {
 		free (tracker->listener);
 	}
 
+    celixThreadRwlock_destroy(&tracker->lock);
+
 	free(tracker->filter);
 	free(tracker);
 
@@ -160,12 +168,18 @@ celix_status_t serviceTracker_close(service_tracker_pt tracker) {
 
 service_reference_pt serviceTracker_getServiceReference(service_tracker_pt tracker) {
 	tracked_pt tracked;
+    service_reference_pt result = NULL;
 	unsigned int i;
-	for (i = 0; i < arrayList_size(tracker->tracked); i++) {
-		tracked = (tracked_pt) arrayList_get(tracker->tracked, i);
-		return tracked->reference;
+
+    celixThreadRwlock_readLock(&tracker->lock);
+	for (i = 0; i < arrayList_size(tracker->trackedServices); i++) {
+		tracked = (tracked_pt) arrayList_get(tracker->trackedServices, i);
+		result = tracked->reference;
+        break;
 	}
-	return NULL;
+    celixThreadRwlock_unlock(&tracker->lock);
+
+	return result;
 }
 
 array_list_pt serviceTracker_getServiceReferences(service_tracker_pt tracker) {
@@ -173,22 +187,31 @@ array_list_pt serviceTracker_getServiceReferences(service_tracker_pt tracker) {
 	unsigned int i;
 	array_list_pt references = NULL;
 	arrayList_create(&references);
-	
-	for (i = 0; i < arrayList_size(tracker->tracked); i++) {
-		tracked = (tracked_pt) arrayList_get(tracker->tracked, i);
+
+    celixThreadRwlock_readLock(&tracker->lock);
+	for (i = 0; i < arrayList_size(tracker->trackedServices); i++) {
+		tracked = (tracked_pt) arrayList_get(tracker->trackedServices, i);
 		arrayList_add(references, tracked->reference);
 	}
+    celixThreadRwlock_unlock(&tracker->lock);
+
 	return references;
 }
 
 void *serviceTracker_getService(service_tracker_pt tracker) {
 	tracked_pt tracked;
+    void *service = NULL;
 	unsigned int i;
-	for (i = 0; i < arrayList_size(tracker->tracked); i++) {
-		tracked = (tracked_pt) arrayList_get(tracker->tracked, i);
-		return tracked->service;
+
+    celixThreadRwlock_readLock(&tracker->lock);
+    for (i = 0; i < arrayList_size(tracker->trackedServices); i++) {
+		tracked = (tracked_pt) arrayList_get(tracker->trackedServices, i);
+		service = tracked->service;
+        break;
 	}
-	return NULL;
+    celixThreadRwlock_unlock(&tracker->lock);
+
+    return service;
 }
 
 array_list_pt serviceTracker_getServices(service_tracker_pt tracker) {
@@ -196,26 +219,35 @@ array_list_pt serviceTracker_getServices(service_tracker_pt tracker) {
 	unsigned int i;
 	array_list_pt references = NULL;
 	arrayList_create(&references);
-	
-	for (i = 0; i < arrayList_size(tracker->tracked); i++) {
-		tracked = (tracked_pt) arrayList_get(tracker->tracked, i);
+
+    celixThreadRwlock_readLock(&tracker->lock);
+    for (i = 0; i < arrayList_size(tracker->trackedServices); i++) {
+		tracked = (tracked_pt) arrayList_get(tracker->trackedServices, i);
 		arrayList_add(references, tracked->service);
 	}
-	return references;
+    celixThreadRwlock_unlock(&tracker->lock);
+
+    return references;
 }
 
 void *serviceTracker_getServiceByReference(service_tracker_pt tracker, service_reference_pt reference) {
 	tracked_pt tracked;
+    void *service = NULL;
 	unsigned int i;
-	for (i = 0; i < arrayList_size(tracker->tracked); i++) {
+
+    celixThreadRwlock_readLock(&tracker->lock);
+	for (i = 0; i < arrayList_size(tracker->trackedServices); i++) {
 		bool equals = false;
-		tracked = (tracked_pt) arrayList_get(tracker->tracked, i);
+		tracked = (tracked_pt) arrayList_get(tracker->trackedServices, i);
 		serviceReference_equals(reference, tracked->reference, &equals);
 		if (equals) {
-			return tracked->service;
+			service = tracked->service;
+            break;
 		}
 	}
-	return NULL;
+    celixThreadRwlock_unlock(&tracker->lock);
+
+	return service;
 }
 
 void serviceTracker_serviceChanged(service_listener_pt listener, service_event_pt event) {
@@ -242,25 +274,32 @@ static celix_status_t serviceTracker_track(service_tracker_pt tracker, service_r
 	tracked_pt tracked = NULL;
 	bool found = false;
 	unsigned int i;
-	for (i = 0; i < arrayList_size(tracker->tracked); i++) {
+
+    celixThreadRwlock_writeLock(&tracker->lock);
+
+	for (i = 0; i < arrayList_size(tracker->trackedServices); i++) {
 		bool equals = false;
-		tracked = (tracked_pt) arrayList_get(tracker->tracked, i);
-		serviceReference_equals(reference, tracked->reference, &equals);
+		tracked = (tracked_pt) arrayList_get(tracker->trackedServices, i);
+		status = serviceReference_equals(reference, tracked->reference, &equals);
+        if (status != CELIX_SUCCESS) {
+            break;
+        }
 		if (equals) {
 			found = true;
 			break;
 		}
 	}
 
-	if (!found /*new*/) {
+	if (status == CELIX_SUCCESS && !found /*new*/) {
 		void * service = NULL;
 		status = serviceTracker_invokeAddingService(tracker, reference, &service);
 		if (status == CELIX_SUCCESS) {
 			if (service != NULL) {
 				tracked = (tracked_pt) calloc(1, sizeof(*tracked));
+				assert(reference != NULL);
 				tracked->reference = reference;
 				tracked->service = service;
-				arrayList_add(tracker->tracked, tracked);
+				arrayList_add(tracker->trackedServices, tracked);
                 serviceTracker_invokeAddService(tracker, reference, service);
 			}
 		}
@@ -268,6 +307,8 @@ static celix_status_t serviceTracker_track(service_tracker_pt tracker, service_r
         status = serviceTracker_invokeModifiedService(tracker, reference, tracked->service);
 	}
 
+    celixThreadRwlock_unlock(&tracker->lock);
+
 	framework_logIfError(logger, status, NULL, "Cannot track reference");
 
 	return status;
@@ -339,17 +380,19 @@ static celix_status_t serviceTracker_untrack(service_tracker_pt tracker, service
 	tracked_pt tracked = NULL;
 	unsigned int i;
 
-	for (i = 0; i < arrayList_size(tracker->tracked); i++) {
+    celixThreadRwlock_writeLock(&tracker->lock);
+    for (i = 0; i < arrayList_size(tracker->trackedServices); i++) {
 		bool equals;
-		tracked = (tracked_pt) arrayList_get(tracker->tracked, i);
+		tracked = (tracked_pt) arrayList_get(tracker->trackedServices, i);
 		serviceReference_equals(reference, tracked->reference, &equals);
 		if (equals) {
-			arrayList_remove(tracker->tracked, i);
+			arrayList_remove(tracker->trackedServices, i);
             serviceTracker_invokeRemovingService(tracker, tracked->reference, tracked->service);
 			free(tracked);
             break;
 		}
 	}
+    celixThreadRwlock_unlock(&tracker->lock);
 
 	framework_logIfError(logger, status, NULL, "Cannot untrack reference");
 


Mime
View raw message