celix-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From pnol...@apache.org
Subject [43/60] [abbrv] [partial] celix git commit: CELIX-424: Cleans up the directory structure. Moves all libraries to the libs subdir and all bundles to the bundles subdir
Date Sun, 27 May 2018 18:52:51 GMT
http://git-wip-us.apache.org/repos/asf/celix/blob/3bce889b/bundles/event_admin/event_admin/private/src/event_admin_impl.c
----------------------------------------------------------------------
diff --git a/bundles/event_admin/event_admin/private/src/event_admin_impl.c b/bundles/event_admin/event_admin/private/src/event_admin_impl.c
new file mode 100644
index 0000000..a7eeb49
--- /dev/null
+++ b/bundles/event_admin/event_admin/private/src/event_admin_impl.c
@@ -0,0 +1,212 @@
+/**
+ *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.
+ */
+/*
+ * event_admin_impl.c
+ *
+ *  Created on: Jul 24, 2013
+ *  \author    	<a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
+ *  \copyright	Apache License, Version 2.0
+ */
+#include <stdlib.h>
+
+#include "event_admin.h"
+#include "event_admin_impl.h"
+#include "event_handler.h"
+#include "hash_map.h"
+#include "utils.h"
+#include "celix_log.h"
+
+
+celix_status_t eventAdmin_create(bundle_context_pt context, event_admin_pt *event_admin){
+	celix_status_t status = CELIX_SUCCESS;
+	*event_admin = calloc(1,sizeof(**event_admin));
+	if (!*event_admin) {
+        status = CELIX_ENOMEM;
+    } else {
+        (*event_admin)->channels = hashMap_create(utils_stringHash, utils_stringHash, utils_stringEquals, utils_stringEquals);
+        (*event_admin)->context =context;
+        status = arrayList_create(&(*event_admin)->event_handlers);
+    }
+	return status;
+}
+
+celix_status_t eventAdmin_destroy(event_admin_pt *event_admin)
+{
+	celix_status_t status = CELIX_SUCCESS;
+	//free(*event_admin);
+	return status;
+}
+
+celix_status_t eventAdmin_getEventHandlersByChannel(bundle_context_pt context, const char * serviceName, array_list_pt *eventHandlers) {
+	celix_status_t status = CELIX_SUCCESS;
+	//celix_status_t status = bundleContext_getServiceReferences(context, serviceName, NULL, eventHandlers);
+	return status;
+}
+
+celix_status_t eventAdmin_postEvent(event_admin_pt event_admin, event_pt event) {
+	celix_status_t status = CELIX_SUCCESS;
+
+	const char *topic;
+
+    eventAdmin_getTopic(&event, &topic);
+
+	array_list_pt event_handlers;
+	arrayList_create(&event_handlers);
+	eventAdmin_lockHandlersList(event_admin, topic);
+	eventAdmin_findHandlersByTopic(event_admin, topic, event_handlers);
+    // TODO make this async!
+	array_list_iterator_pt handlers_iterator = arrayListIterator_create(event_handlers);
+	while (arrayListIterator_hasNext(handlers_iterator)) {
+		event_handler_service_pt event_handler_service = (event_handler_service_pt) arrayListIterator_next(handlers_iterator);
+		logHelper_log(*event_admin->loghelper, OSGI_LOGSERVICE_INFO, "handler found (POST EVENT) for %s", topic);
+		event_handler_service->handle_event(&event_handler_service->event_handler, event);
+	}
+	eventAdmin_releaseHandersList(event_admin, topic);
+	return status;
+}
+
+celix_status_t eventAdmin_sendEvent(event_admin_pt event_admin, event_pt event) {
+	celix_status_t status = CELIX_SUCCESS;
+
+	const char *topic;
+	eventAdmin_getTopic(&event, &topic);
+
+	array_list_pt event_handlers;
+	arrayList_create(&event_handlers);
+	eventAdmin_lockHandlersList(event_admin, topic);
+	eventAdmin_findHandlersByTopic(event_admin, topic, event_handlers);
+	array_list_iterator_pt handlers_iterator = arrayListIterator_create(event_handlers);
+	while (arrayListIterator_hasNext(handlers_iterator)) {
+		event_handler_service_pt event_handler_service = (event_handler_service_pt) arrayListIterator_next(handlers_iterator);
+		logHelper_log(*event_admin->loghelper, OSGI_LOGSERVICE_INFO, "handler found (SEND EVENT) for %s", topic);
+		event_handler_service->handle_event(&event_handler_service->event_handler, event);
+	}
+	eventAdmin_releaseHandersList(event_admin, topic);
+	return status;
+}
+
+celix_status_t eventAdmin_findHandlersByTopic(event_admin_pt event_admin, const char *topic,
+											  array_list_pt event_handlers) {
+	celix_status_t status = CELIX_SUCCESS;
+	hash_map_pt channels = event_admin->channels;
+    channel_t channel = hashMap_get(channels, topic);
+	if (channel != NULL) {
+		logHelper_log(*event_admin->loghelper, OSGI_LOGSERVICE_INFO, "found channel: %s", topic);
+		if (channel->eventHandlers != NULL && !hashMap_isEmpty(channel->eventHandlers)) {
+			// iterate throught the handlers and add them to the array list for result.
+			hash_map_iterator_pt hashmap_iterator =  hashMapIterator_create(channel->eventHandlers);
+			while (hashMapIterator_hasNext(hashmap_iterator)) {
+				arrayList_add(event_handlers, (event_handler_service_pt) hashMapIterator_nextValue(hashmap_iterator));
+			}
+		}
+	} else {
+		logHelper_log(*event_admin->loghelper, OSGI_LOGSERVICE_WARNING, "no such channel: %s", topic);
+	}
+	return status;
+}
+
+celix_status_t eventAdmin_createEventChannels(event_admin_pt *event_admin, const char *topic,
+											  event_handler_service_pt event_handler_service) {
+	celix_status_t status = CELIX_SUCCESS;
+    channel_t channel = hashMap_get((*event_admin)->channels, topic);
+	if (channel == NULL) {
+		//create channel
+		logHelper_log(*(*event_admin)->loghelper, OSGI_LOGSERVICE_ERROR, "Creating channel: %s", topic);
+
+
+
+		channel = calloc(1, sizeof(*channel));
+		if (!channel) {
+            status = CELIX_ENOMEM;
+        } else {
+            char *channel_name = strdup(topic);
+			channel->topic = channel_name;
+			channel->eventHandlers = hashMap_create(NULL,NULL,NULL,NULL);
+			//channel->channelLock = NULL;
+          //  apr_thread_mutex_create(&channel->channelLock, APR_THREAD_MUTEX_NESTED, subPool);
+			hashMap_put((*event_admin)->channels, channel_name, channel);
+		}
+    }
+    if (channel) {
+        hashMap_put(channel->eventHandlers, &event_handler_service, event_handler_service);
+    }
+	return status;
+
+
+}
+
+celix_status_t eventAdmin_lockHandlersList(event_admin_pt event_admin, const char *topic) {
+	celix_status_t status = CELIX_SUCCESS;
+    /*channel_t channel = hashMap_get(event_admin->channels, topic);
+	if (channel != NULL) {
+        // TODO verify this will never deadlock...
+       // apr_status_t status;
+        do {
+         //   status = apr_thread_mutex_trylock(channel->channelLock);
+        } while (status != 0 && !APR_STATUS_IS_EBUSY(status));
+        logHelper_log(*event_admin->loghelper, OSGI_LOGSERVICE_DEBUG, "LOCK: %s!", topic);
+    }*/
+	return status;
+}
+
+celix_status_t eventAdmin_releaseHandersList(event_admin_pt event_admin, const char *topic) {
+	celix_status_t status = CELIX_SUCCESS;
+    channel_t channel = hashMap_get(event_admin->channels, topic);
+	if (channel != NULL) {
+        // TODO check the result value...
+       // apr_thread_mutex_unlock(channel->channelLock);
+		logHelper_log(*event_admin->loghelper, OSGI_LOGSERVICE_ERROR, "UNLOCK: %s!", topic);
+    }
+	return status;
+}
+
+celix_status_t eventAdmin_addingService(void * handle, service_reference_pt ref, void **service) {
+	celix_status_t status = CELIX_SUCCESS;
+	event_admin_pt  event_admin = handle;
+	status = bundleContext_getService(event_admin->context, ref, service);
+	logHelper_log(*event_admin->loghelper, OSGI_LOGSERVICE_ERROR, "test");
+	printf("eventadmin adding service \n");
+  	return status;
+}
+
+celix_status_t eventAdmin_addedService(void * handle, service_reference_pt ref, void * service) {
+	celix_status_t status = CELIX_SUCCESS;
+	event_admin_pt event_admin = handle;
+	event_handler_service_pt event_handler_service = NULL;
+	event_handler_service = (event_handler_service_pt) service;
+	const char *topic = NULL;
+	serviceReference_getProperty(ref, (char*)EVENT_TOPIC, &topic);
+	logHelper_log(*event_admin->loghelper, OSGI_LOGSERVICE_ERROR, "Original TOPIC: %s", topic);
+	printf("original topic: %s\n", topic);
+	eventAdmin_createEventChannels(&event_admin,topic,event_handler_service);
+	return status;
+}
+
+celix_status_t eventAdmin_modifiedService(void * handle, service_reference_pt ref, void * service) {
+	event_admin_pt event_admin = (event_admin_pt) handle;
+	logHelper_log(*event_admin->loghelper, OSGI_LOGSERVICE_ERROR, "Event admin Modified");
+	return CELIX_SUCCESS;
+}
+
+celix_status_t eventAdmin_removedService(void * handle, service_reference_pt ref, void * service) {
+	event_admin_pt event_admin = (event_admin_pt) handle;
+	logHelper_log(*event_admin->loghelper, OSGI_LOGSERVICE_ERROR, "Event admin Removed %p", service);
+	printf("Event admin Removed %p", service);
+	return CELIX_SUCCESS;
+}

http://git-wip-us.apache.org/repos/asf/celix/blob/3bce889b/bundles/event_admin/event_admin/private/src/event_impl.c
----------------------------------------------------------------------
diff --git a/bundles/event_admin/event_admin/private/src/event_impl.c b/bundles/event_admin/event_admin/private/src/event_impl.c
new file mode 100644
index 0000000..aad9877
--- /dev/null
+++ b/bundles/event_admin/event_admin/private/src/event_impl.c
@@ -0,0 +1,136 @@
+/**
+ *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.
+ */
+/*
+ * event_impl.c
+ *
+ *  \Created on: Aug 22, 2013
+ *  \author    	<a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
+ *  \copyright	Apache License, Version 2.0
+ *
+ */
+#include <stdlib.h>
+
+#include "event_admin.h"
+#include "event_admin_impl.h"
+#include "event_constants.h"
+#include "celix_errno.h"
+#include "stddef.h"
+
+
+
+celix_status_t eventAdmin_createEvent(event_admin_pt event_admin, const char *topic, properties_pt properties,
+									  event_pt *event) {
+	celix_status_t status = CELIX_SUCCESS;
+
+	logHelper_log(*event_admin->loghelper, OSGI_LOGSERVICE_DEBUG, "create event event admin pointer: %p",event_admin);
+
+
+	*event = calloc(1, sizeof(**event));
+	if(!*event){
+	       status = CELIX_ENOMEM;
+	       logHelper_log(*event_admin->loghelper, OSGI_LOGSERVICE_ERROR, "No MEM");
+	}else {
+		logHelper_log(*event_admin->loghelper, OSGI_LOGSERVICE_INFO, "Event created : %s", topic);
+		(*event)->topic = topic;
+		(*event)->properties = properties;
+		properties_set((*event)->properties, (char *)EVENT_TOPIC, topic);
+	}
+	return status;
+}
+
+celix_status_t eventAdmin_containsProperty( event_pt *event, char *property, bool *result){
+	celix_status_t status = CELIX_SUCCESS;
+	if((*event)==NULL || property == NULL){
+		status = CELIX_BUNDLE_EXCEPTION;
+	}else {
+		const char *propertyValue = properties_get((*event)->properties, property);
+		if(propertyValue == NULL){
+			(*result)= false;
+		}else {
+			(*result) = true;
+		}
+	}
+	return status;
+}
+
+celix_status_t eventAdmin_event_equals( event_pt *event, event_pt *compare, bool *result){
+	celix_status_t status = CELIX_SUCCESS;
+	if(event == compare){
+		(*result) = true;
+	}else {
+		int sizeofEvent = hashMap_size((*event)->properties);
+		int sizeofCompare = hashMap_size((*compare)->properties);
+		if(sizeofEvent == sizeofCompare){
+			(*result) = true;
+		}else {
+
+		}
+	}
+	return status;
+}
+
+celix_status_t eventAdmin_getProperty(event_pt *event, char *propertyKey, const char **propertyValue) {
+	celix_status_t status = CELIX_SUCCESS;
+	*propertyValue = properties_get((*event)->properties,propertyKey);
+
+	return status;
+}
+
+celix_status_t eventAdmin_getPropertyNames( event_pt *event, array_list_pt *names){
+	celix_status_t status = CELIX_SUCCESS;
+	properties_pt properties =  (*event)->properties;
+	if (hashMap_size(properties) > 0) {
+		hash_map_iterator_pt iterator = hashMapIterator_create(properties);
+		while (hashMapIterator_hasNext(iterator)) {
+			hash_map_entry_pt entry = hashMapIterator_nextEntry(iterator);
+			char * key =hashMapEntry_getKey(entry);
+			arrayList_add((*names),key);
+		}
+	}
+	return status;
+}
+
+celix_status_t eventAdmin_getTopic(event_pt *event, const char **topic) {
+	celix_status_t status = CELIX_SUCCESS;
+	const char *value;
+	value = properties_get((*event)->properties,(char*) EVENT_TOPIC);
+	*topic = value;
+
+	return status;
+}
+
+celix_status_t eventAdmin_hashCode( event_pt *event, int *hashCode){
+	celix_status_t status = CELIX_SUCCESS;
+	return status;
+}
+
+celix_status_t eventAdmin_matches( event_pt *event){
+	celix_status_t status = CELIX_SUCCESS;
+	return status;
+}
+
+celix_status_t eventAdmin_toString( event_pt *event, char *eventString){
+	celix_status_t status = CELIX_SUCCESS;
+	return status;
+}
+
+
+
+
+

http://git-wip-us.apache.org/repos/asf/celix/blob/3bce889b/bundles/event_admin/event_admin/public/include/event_admin.h
----------------------------------------------------------------------
diff --git a/bundles/event_admin/event_admin/public/include/event_admin.h b/bundles/event_admin/event_admin/public/include/event_admin.h
new file mode 100644
index 0000000..4955b54
--- /dev/null
+++ b/bundles/event_admin/event_admin/public/include/event_admin.h
@@ -0,0 +1,70 @@
+/**
+ *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.
+ */
+/*
+ * event_admin.h
+ *
+ *  Created on: Jul 9, 2013
+ *  \author    	<a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
+ *  \copyright	Apache License, Version 2.0
+ */
+
+#ifndef EVENT_ADMIN_H_
+#define EVENT_ADMIN_H_
+#include "celix_errno.h"
+
+#include "listener_hook_service.h"
+
+#define EVENT_ADMIN_NAME "event_admin"
+typedef struct event_admin *event_admin_pt;
+typedef struct event_admin_service *event_admin_service_pt;
+
+struct event {
+	const char *topic;
+	properties_pt properties;
+};
+typedef struct event *event_pt;
+
+/**
+ * @desc service description for the event admin.
+ * @param event_admin_pt eventAdmin. incomplete type for the event admin instance.
+ * @param celix_status_t postEvent. Pointer to the post event function. For async sending
+ * @param celix_status_t sendEvent. Pointer to the send event function. for Sync sending
+ */
+struct event_admin_service {
+	event_admin_pt eventAdmin;
+	celix_status_t (*postEvent)(event_admin_pt event_admin, event_pt event);
+	celix_status_t (*sendEvent)(event_admin_pt event_admin, event_pt event);
+
+	celix_status_t (*createEvent)(event_admin_pt event_admin, const char *topic, properties_pt properties,
+								  event_pt *event);
+	celix_status_t (*containsProperty)(event_pt *event, char *property, bool *result);
+	celix_status_t (*event_equals)(event_pt *event, event_pt *compare, bool *result);
+
+	celix_status_t (*getProperty)(event_pt *event, char *propertyKey, const char **propertyValue);
+	celix_status_t (*getPropertyNames)(event_pt *event, array_list_pt *names);
+
+	celix_status_t (*getTopic)(event_pt *event, const char **topic);
+	celix_status_t (*hashCode)(event_pt *event, int *hashCode);
+	celix_status_t (*matches)( event_pt *event);
+	celix_status_t (*toString)( event_pt *event, char *eventString);
+
+};
+
+
+#endif /* EVENT_ADMIN_H_ */

http://git-wip-us.apache.org/repos/asf/celix/blob/3bce889b/bundles/event_admin/event_admin/public/include/event_constants.h
----------------------------------------------------------------------
diff --git a/bundles/event_admin/event_admin/public/include/event_constants.h b/bundles/event_admin/event_admin/public/include/event_constants.h
new file mode 100644
index 0000000..80b093a
--- /dev/null
+++ b/bundles/event_admin/event_admin/public/include/event_constants.h
@@ -0,0 +1,60 @@
+/**
+ *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.
+ */
+/*
+ * event_constants.h
+ *
+ *  Created on: Aug 11, 2013
+ *  \author    	<a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
+ *  \copyright	Apache License, Version 2.0
+ */
+
+#ifndef EVENT_CONSTANTS_H_
+#define EVENT_CONSTANTS_H_
+
+static const char * const EVENT_BUNDLE = "bundle";
+static const char * const EVENT_BUNDLE_ID = "bundle.id";
+static const char * const EVENT_BUNDLE_SIGNER = "bundle.signer";
+
+static const char * const EVENT_BUNDLE_SYMBOLICNAME = "bundle.symbolicName";
+
+
+static const char * const EVENT_BUNDLE_VERSION = "bundle.version";
+
+static const char * const EVENT_DELIVERY_ASYNC_ORDERED = "async.ordered";
+static const char * const EVENT_DELIVERY_ASYNC_UNORDERED = "async.unordered";
+static const char * const EVENT = "event";
+static const char * const EVENT_DELIVERY = "event.delivery";
+static const char * const EVENT_FILTER = "event.filter";
+static const char * const EVENT_TOPIC = "event.topic";
+static const char * const EVENT_EXCEPTION = "exception";
+static const char * const EVENT_EXCEPTION_CLASS = "exception.class";
+static const char * const EVENT_EXCEPTION_MESSAGE = "exception.message";
+static const char * const MESSAGE = "message";
+
+static const char * const EVENT_SERVICE = "service";
+
+static const char * const EVENT_SERVICE_ID = "async.ordered";
+
+static const char * const EVENT_SERVICE_OBJECTCLASS = "service.objectClass";
+
+static const char * const EVENT_SERVICE_PID = "service.pid";
+
+static const char * const EVENT_TIMESTAMP = "timestamp";
+
+#endif /* EVENT_CONSTANTS_H_ */

http://git-wip-us.apache.org/repos/asf/celix/blob/3bce889b/bundles/event_admin/event_admin/public/include/event_handler.h
----------------------------------------------------------------------
diff --git a/bundles/event_admin/event_admin/public/include/event_handler.h b/bundles/event_admin/event_admin/public/include/event_handler.h
new file mode 100644
index 0000000..5f76c6d
--- /dev/null
+++ b/bundles/event_admin/event_admin/public/include/event_handler.h
@@ -0,0 +1,48 @@
+/**
+ *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.
+ */
+/*
+ * event_handler.h
+ *
+ *  Created on: Jul 22, 2013
+ *  \author    	<a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
+ *  \copyright	Apache License, Version 2.0
+ */
+
+#ifndef EVENT_HANDLER_H_
+#define EVENT_HANDLER_H_
+#include "event_admin.h"
+#include "properties.h"
+static const char * const EVENT_HANDLER_SERVICE = "service.event.handler";
+
+typedef struct event_handler_service *event_handler_service_pt;
+typedef struct event_handler *event_handler_pt; //ADT
+
+
+
+/**
+ * @desc description of the event handler service
+ * @param event_handler_pt event_handler incomplete type pointer for the event_handler instance
+ * @param celix_status_t handle event. pointer to the handle event method.
+ */
+struct event_handler_service {
+		event_handler_pt event_handler;
+        celix_status_t (*handle_event)(event_handler_pt *event_handler, event_pt event);
+};
+
+#endif /* EVENT_HANDLER_H_ */

http://git-wip-us.apache.org/repos/asf/celix/blob/3bce889b/bundles/event_admin/event_handler/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/bundles/event_admin/event_handler/CMakeLists.txt b/bundles/event_admin/event_handler/CMakeLists.txt
new file mode 100644
index 0000000..92813a7
--- /dev/null
+++ b/bundles/event_admin/event_handler/CMakeLists.txt
@@ -0,0 +1,35 @@
+# 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.
+
+
+include_directories("${PROJECT_SOURCE_DIR}/utils/public/include")
+include_directories(private/include)
+include_directories(${PROJECT_SOURCE_DIR}/event_admin/event_admin/public/include)
+include_directories("${PROJECT_SOURCE_DIR}/log_service/public/include")
+
+
+add_celix_bundle(event_handler
+    VERSION 0.0.0
+	SOURCES 
+		private/src/event_handler_activator.c
+		private/src/event_handler_impl.c
+		${PROJECT_SOURCE_DIR}/log_service/public/src/log_helper.c
+)
+
+install_celix_bundle(event_handler)
+
+target_link_libraries(event_handler Celix::framework)

http://git-wip-us.apache.org/repos/asf/celix/blob/3bce889b/bundles/event_admin/event_handler/private/include/event_handler_impl.h
----------------------------------------------------------------------
diff --git a/bundles/event_admin/event_handler/private/include/event_handler_impl.h b/bundles/event_admin/event_handler/private/include/event_handler_impl.h
new file mode 100644
index 0000000..44fc671
--- /dev/null
+++ b/bundles/event_admin/event_handler/private/include/event_handler_impl.h
@@ -0,0 +1,57 @@
+/**
+ *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.
+ */
+/*
+ * event_handler_impl.h
+ *
+ *  Created on: Aug 20, 2013
+  *  \author    	<a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
+ *  \copyright	Apache License, Version 2.0
+ */
+
+#ifndef EVENT_HANDLER_IMPL_H_
+#define EVENT_HANDLER_IMPL_H_
+#include "event_admin.h"
+#include "event_constants.h"
+#include "event_handler.h"
+
+#include "bundle_activator.h"
+#include "bundle_context.h"
+#include "service_tracker.h"
+#include "service_listener.h"
+#include "service_registration.h"
+#include "listener_hook_service.h"
+#include "event_constants.h"
+/**
+ * @desc handle the event send to the event handler
+ * @param event_handler_pt *instance the instance of the event handlers
+ * @param event_pt event. the event to be handled.
+ */
+celix_status_t eventHandlerHandleEvent(event_handler_pt *instance, event_pt event) ;
+
+/**
+ * @desc create the event handler
+ * @param apr_pool_t *pool the apr pool to contain the handler
+ * @param event_handler_pt *event_handler. the event handler to be made.
+ */
+celix_status_t eventHandlerCreate(bundle_context_pt context, event_handler_pt *event_handler);
+celix_status_t  eventHandlerRemovedService(void * handle, service_reference_pt ref, void * service) ;
+celix_status_t  eventHandlerModifiedService(void * handle, service_reference_pt ref, void * service) ;
+celix_status_t  eventHandlerAddedService(void * handle, service_reference_pt ref, void * service) ;
+celix_status_t  eventHandlerAddingService(void * handle, service_reference_pt ref, void **service) ;
+#endif /* EVENT_HANDLER_IMPL_H_ */

http://git-wip-us.apache.org/repos/asf/celix/blob/3bce889b/bundles/event_admin/event_handler/private/src/event_handler_activator.c
----------------------------------------------------------------------
diff --git a/bundles/event_admin/event_handler/private/src/event_handler_activator.c b/bundles/event_admin/event_handler/private/src/event_handler_activator.c
new file mode 100644
index 0000000..d39cfd9
--- /dev/null
+++ b/bundles/event_admin/event_handler/private/src/event_handler_activator.c
@@ -0,0 +1,104 @@
+/**
+ *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.
+ */
+/*
+ * event_handler_activator.c
+ *
+ * Created on: Jul 9, 2013
+ * \author    	<a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
+ * \copyright	Apache License, Version 2.0
+ */
+#include <stdlib.h>
+
+
+
+#include "event_handler_impl.h"
+
+static const char * const EVENT_HANDLER_NAME = "demo";
+struct activator {
+	event_handler_service_pt event_handler_service;
+	service_registration_pt registration;
+	service_tracker_pt eventAdminTracker;
+};
+
+celix_status_t bundleActivator_create(bundle_context_pt context, void **userData) {
+	celix_status_t status = CELIX_SUCCESS;
+	struct activator *activator;
+
+    activator = calloc(1, sizeof(*activator));
+    activator->registration = NULL;
+    *userData = activator;
+
+    event_handler_pt event_handler = NULL;
+    event_handler_service_pt event_handler_service = NULL;
+
+    status = eventHandlerCreate(context, &event_handler);
+    if (status == CELIX_SUCCESS) {
+        event_handler_service = calloc(1, sizeof(event_handler_service));
+        if (!event_handler_service) {
+            status = CELIX_ENOMEM;
+        } else {
+            event_handler_service->event_handler = event_handler;
+            event_handler_service->handle_event = eventHandlerHandleEvent;
+		}
+	}
+    activator->event_handler_service = event_handler_service;
+
+
+    return status;
+}
+
+celix_status_t bundleActivator_start(void * userData, bundle_context_pt context) {
+	celix_status_t status = CELIX_SUCCESS;
+	struct activator *activator = userData;
+
+	properties_pt properties = NULL;
+	properties = properties_create();
+    properties_set(properties, (char *) EVENT_HANDLER_SERVICE, (const char *) EVENT_HANDLER_NAME);
+    properties_set(properties, (char *) EVENT_TOPIC, (const char *) "log/error/eventpublishers/event");
+
+	event_handler_service_pt event_handler_service = activator->event_handler_service;
+    bundleContext_registerService(context, (const char *) EVENT_HANDLER_SERVICE, event_handler_service, properties,
+                                  &activator->registration);
+
+    /*if (status == CELIX_SUCCESS) {
+        service_tracker_customizer_pt customizer = NULL;
+        service_tracker_pt tracker = NULL;
+        serviceTrackerCustomizer_create(activator->event_handler_service->event_handler, eventHandlerAddingService, eventHandlerAddedService, eventHandlerModifiedService, eventHandlerRemovedService, &customizer);
+        serviceTracker_create(context, (const char *) EVENT_ADMIN_NAME, customizer, &tracker);
+        activator->eventAdminTracker = tracker;
+        serviceTracker_open(tracker);
+    }*/
+	return status;
+}
+
+celix_status_t bundleActivator_stop(void * userData, bundle_context_pt context) {
+	celix_status_t status = CELIX_SUCCESS;
+    struct activator *data = userData;
+    serviceRegistration_unregister(data->registration);
+    //serviceTracker_close(data->tracker);
+    //status = logHelper_stop(data->loghelper);
+    //logHelper_destroy(&data->loghelper);
+	return status;
+}
+
+
+celix_status_t bundleActivator_destroy(void * userData, bundle_context_pt context) {
+	celix_status_t status = CELIX_SUCCESS;
+	return status;
+}

http://git-wip-us.apache.org/repos/asf/celix/blob/3bce889b/bundles/event_admin/event_handler/private/src/event_handler_impl.c
----------------------------------------------------------------------
diff --git a/bundles/event_admin/event_handler/private/src/event_handler_impl.c b/bundles/event_admin/event_handler/private/src/event_handler_impl.c
new file mode 100644
index 0000000..52ff1b7
--- /dev/null
+++ b/bundles/event_admin/event_handler/private/src/event_handler_impl.c
@@ -0,0 +1,111 @@
+/**
+ *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.
+ */
+/*
+ * event_admin_impl.c
+ *
+ *  Created on: Jul 24, 2013
+ *  \author    	<a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
+ *  \copyright	Apache License, Version 2.0
+ */
+#include <stdlib.h>
+#include "event_handler.h"
+#include "log_helper.h"
+#include "log_service.h"
+
+struct event_handler {
+	event_admin_service_pt event_admin_service;
+	bundle_context_pt context;
+	log_helper_pt loghelper;
+
+};
+
+celix_status_t eventHandlerCreate(bundle_context_pt context, event_handler_pt *event_handler) {
+	celix_status_t status = CELIX_SUCCESS;
+    *event_handler = calloc(1, sizeof(**event_handler));
+	if (!*event_handler) {
+        status = CELIX_ENOMEM;
+	} else {
+        (*event_handler)->event_admin_service = NULL;
+        (*event_handler)->context = context;
+
+        if (logHelper_create(context, &(*event_handler)->loghelper) == CELIX_SUCCESS) {
+        	logHelper_start((*event_handler)->loghelper);
+        }
+	}
+	return status;
+}
+
+celix_status_t eventHandlerHandleEvent(event_handler_pt *event_handler, event_pt event) {
+	celix_status_t status = CELIX_SUCCESS;
+	if (event != NULL) {
+        const char *topic = event->topic;
+        //status = (*event_handler)->event_admin_service->getTopic(&event, &topic);
+		logHelper_log((*event_handler)->loghelper, OSGI_LOGSERVICE_INFO, "[SUB] topic of event: %s.", topic);
+
+		array_list_pt propertyNames;
+		arrayList_create(&propertyNames);
+        properties_pt properties = event->properties;
+        if (hashMap_size(properties) > 0) {
+            hash_map_iterator_pt iterator = hashMapIterator_create(properties);
+            while (hashMapIterator_hasNext(iterator)) {
+                hash_map_entry_pt entry = hashMapIterator_nextEntry(iterator);
+                char *key = hashMapEntry_getKey(entry);
+                arrayList_add(propertyNames, key);
+            }
+        }
+		array_list_iterator_pt propertyIter = arrayListIterator_create(propertyNames);
+		while (arrayListIterator_hasNext(propertyIter)) {
+            char *key = arrayListIterator_next(propertyIter);
+            const char *value = NULL;
+            value = properties_get((*event).properties, key);
+
+
+			logHelper_log((*event_handler)->loghelper, OSGI_LOGSERVICE_INFO, "[SUB] Key: %s value: %s.", key, value);
+		}
+	}
+	return status;
+}
+
+
+celix_status_t eventHandlerAddingService(void * handle, service_reference_pt ref, void **service) {
+	celix_status_t status = CELIX_SUCCESS;
+	event_handler_pt event_handler = handle;
+	status = bundleContext_getService(event_handler->context, ref, service);
+	return status;
+}
+
+celix_status_t eventHandlerAddedService(void * handle, service_reference_pt ref, void * service) {
+	event_handler_pt data = (event_handler_pt) handle;
+	logHelper_log(data->loghelper, OSGI_LOGSERVICE_DEBUG, "[SUB] Event admin added.");
+	data->event_admin_service = (event_admin_service_pt) service;
+	return CELIX_SUCCESS;
+}
+
+celix_status_t eventHandlerModifiedService(void * handle, service_reference_pt ref, void * service) {
+	event_handler_pt data = (event_handler_pt) handle;
+	logHelper_log(data->loghelper, OSGI_LOGSERVICE_DEBUG, "[SUB] Event admin modified.");
+	return CELIX_SUCCESS;
+}
+
+celix_status_t eventHandlerRemovedService(void * handle, service_reference_pt ref, void * service) {
+	event_handler_pt data = (event_handler_pt) handle;
+    logHelper_log(data->loghelper, OSGI_LOGSERVICE_DEBUG, "[SUB] Event admin removed.");
+	data->event_admin_service = NULL;
+	return CELIX_SUCCESS;
+}

http://git-wip-us.apache.org/repos/asf/celix/blob/3bce889b/bundles/event_admin/event_publisher/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/bundles/event_admin/event_publisher/CMakeLists.txt b/bundles/event_admin/event_publisher/CMakeLists.txt
new file mode 100644
index 0000000..4dd314a
--- /dev/null
+++ b/bundles/event_admin/event_publisher/CMakeLists.txt
@@ -0,0 +1,34 @@
+# 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.
+
+
+include_directories("${PROJECT_SOURCE_DIR}/utils/public/include")
+include_directories(private/include)
+include_directories(${PROJECT_SOURCE_DIR}/event_admin/event_admin/public/include)
+include_directories(${PROJECT_SOURCE_DIR}/log_service/public/include)
+
+add_celix_bundle(event_publisher
+    VERSION 0.0.0
+		SOURCES
+		private/src/event_publisher_activator.c
+		private/src/event_publisher_impl.c
+		${PROJECT_SOURCE_DIR}/log_service/public/src/log_helper.c
+)
+
+install_celix_bundle(event_publisher)
+
+target_link_libraries(event_publisher Celix::framework)

http://git-wip-us.apache.org/repos/asf/celix/blob/3bce889b/bundles/event_admin/event_publisher/private/include/event_publisher_impl.h
----------------------------------------------------------------------
diff --git a/bundles/event_admin/event_publisher/private/include/event_publisher_impl.h b/bundles/event_admin/event_publisher/private/include/event_publisher_impl.h
new file mode 100644
index 0000000..a2cab83
--- /dev/null
+++ b/bundles/event_admin/event_publisher/private/include/event_publisher_impl.h
@@ -0,0 +1,83 @@
+/**
+ *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.
+ */
+/*
+ * event_publisher.h
+ *
+ *  Created on: Aug 9, 2013
+ *  \author    	<a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
+ *  \copyright	Apache License, Version 2.0
+ */
+
+#ifndef EVENT_PUBLISHER_H_
+#define EVENT_PUBLISHER_H_
+#include "celix_errno.h"
+#include "event_admin.h"
+
+#include "listener_hook_service.h"
+#include "service_tracker.h"
+#include "bundle_activator.h"
+#include "bundle_context.h"
+#include "service_tracker.h"
+#include "service_listener.h"
+#include "service_registration.h"
+#include "event_constants.h"
+#include "log_helper.h"
+#include "log_service.h"
+
+
+typedef struct event_publisher *event_publisher_pt;
+struct event_publisher {
+	event_admin_service_pt event_admin_service;
+	bool running;
+	bool eventAdminAdded;
+	celix_thread_t sender;
+	bundle_context_pt context;
+	log_helper_pt loghelper;
+};
+/**
+ * @desc create the event publisher
+ * @param apr_pool_t *pool. the memory pool to store the publisher
+ * @param bundle_context_pt context the bundle context
+ * @param event_publisher_pt *event_publisher. The publisher to be made.
+ */
+celix_status_t eventPublisherCreate(bundle_context_pt context, event_publisher_pt *event_publisher);
+/**
+ * @desc start the event publisher. Starts the threads and trackers.
+ * @param event_publisher_pt *event_publisher the publisher to start
+ */
+celix_status_t eventPublisherStart(event_publisher_pt *event_publisher);
+
+/**
+ * @desc functions used by the event admin tracker
+ * @param void *handle, pointer to the event publisher
+ * @param service_reference_pt ref. pointer to the reference of the event admin
+ * @param void **service. pointer to the event admin service.
+ */
+celix_status_t eventPublisherAddingService(void * handle, service_reference_pt ref, void **service);
+celix_status_t eventPublisherAddedService(void * handle, service_reference_pt ref, void * service);
+celix_status_t eventPublisherModifiedService(void * handle, service_reference_pt ref, void * service);
+celix_status_t eventPublisherRemovedService(void * handle, service_reference_pt ref, void * service);
+/**
+ * @desc stop the event publisher. stopping threads and tracker
+ * @param event_publisher_pt *event_publisher. pointer to the publisher.
+ */
+celix_status_t eventPublisherStop(event_publisher_pt *event_publisher);
+
+void *produceEvents(void *handle);
+#endif /* EVENT_PUBLISHER_H_ */

http://git-wip-us.apache.org/repos/asf/celix/blob/3bce889b/bundles/event_admin/event_publisher/private/src/event_publisher_activator.c
----------------------------------------------------------------------
diff --git a/bundles/event_admin/event_publisher/private/src/event_publisher_activator.c b/bundles/event_admin/event_publisher/private/src/event_publisher_activator.c
new file mode 100644
index 0000000..279942f
--- /dev/null
+++ b/bundles/event_admin/event_publisher/private/src/event_publisher_activator.c
@@ -0,0 +1,86 @@
+/**
+ *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.
+ */
+/*
+ * activator.c
+ *
+ *  Created on: Jul 9, 2013
+ *  \author    	<a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
+ *  \copyright	Apache License, Version 2.0
+ */
+#include <stdlib.h>
+
+
+#include "event_publisher_impl.h"
+
+struct activator {
+	bundle_context_pt context;
+	event_publisher_pt event_publisher;
+	service_tracker_pt tracker;
+};
+
+celix_status_t bundleActivator_create(bundle_context_pt context, void **userData) {
+	celix_status_t status = CELIX_SUCCESS;
+
+	struct activator *activator = NULL;
+
+	activator = calloc(1, sizeof(*activator));
+	activator->context = context;
+	*userData = activator;
+
+	event_publisher_pt eventpublisher;
+	status = eventPublisherCreate(context, &eventpublisher);
+	if(status == CELIX_SUCCESS) {
+		activator->event_publisher = eventpublisher;
+
+	}
+
+	return status;
+}
+
+celix_status_t bundleActivator_start(void * userData, bundle_context_pt context) {
+	celix_status_t status = CELIX_SUCCESS;
+	struct activator * data = (struct activator *) userData;
+
+
+	service_tracker_customizer_pt cust = NULL;
+		service_tracker_pt tracker = NULL;
+		data->context = context;
+		serviceTrackerCustomizer_create(data->event_publisher, eventPublisherAddingService, eventPublisherAddedService, eventPublisherModifiedService, eventPublisherRemovedService, &cust);
+		serviceTracker_create(context, (char *) EVENT_ADMIN_NAME, cust, &tracker);
+		data->tracker = tracker;
+
+		serviceTracker_open(tracker);
+
+	eventPublisherStart(&data->event_publisher);
+	return status;
+}
+
+celix_status_t bundleActivator_stop(void * userData, bundle_context_pt context) {
+	celix_status_t status = CELIX_SUCCESS;
+	struct activator * data = (struct activator *) userData;
+	eventPublisherStop(&data->event_publisher);
+	serviceTracker_close(data->tracker);
+	return status;
+}
+
+celix_status_t bundleActivator_destroy(void * userData, bundle_context_pt context) {
+	celix_status_t status = CELIX_SUCCESS;
+
+	return status;
+}

http://git-wip-us.apache.org/repos/asf/celix/blob/3bce889b/bundles/event_admin/event_publisher/private/src/event_publisher_impl.c
----------------------------------------------------------------------
diff --git a/bundles/event_admin/event_publisher/private/src/event_publisher_impl.c b/bundles/event_admin/event_publisher/private/src/event_publisher_impl.c
new file mode 100644
index 0000000..6a8bc00
--- /dev/null
+++ b/bundles/event_admin/event_publisher/private/src/event_publisher_impl.c
@@ -0,0 +1,141 @@
+/**
+ *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.
+ */
+/*
+ * event_publisher_impl.c
+ *
+ * Created on: Jul 24, 2013
+ * \author    	<a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
+ * \copyright	Apache License, Version 2.0
+ */
+#include <stdlib.h>
+
+#include <unistd.h>
+#include <sys/time.h>
+#include "event_publisher_impl.h"
+
+celix_thread_start_t eventPublisherSendEventThread(celix_thread_t *thd, void *handle);
+
+celix_status_t eventPublisherCreate(bundle_context_pt context, event_publisher_pt *event_publisher) {
+    celix_status_t status = CELIX_SUCCESS;
+    *event_publisher = calloc(1, sizeof(**event_publisher));
+    if (!*event_publisher) {
+        status = CELIX_ENOMEM;
+    } else {
+        (*event_publisher)->event_admin_service = NULL;
+
+        (*event_publisher)->eventAdminAdded = false;
+        (*event_publisher)->running = false;
+        (*event_publisher)->context = context;
+        (*event_publisher)->sender = celix_thread_default;
+        logHelper_create(context, &(*event_publisher)->loghelper);
+    }
+    return status;
+}
+
+celix_status_t eventPublisherStart(event_publisher_pt *event_publisher) {
+    celix_status_t status = CELIX_SUCCESS;
+	(*event_publisher)->running = true;
+    logHelper_start((*event_publisher)->loghelper);
+    // celixThread_create((*event_publisher)->sender, NULL, eventPublisherSendEventThread, event_publisher);
+    status = celixThread_create(&(*event_publisher)->sender, NULL, produceEvents, &(*event_publisher));
+    return status;
+}
+
+celix_status_t eventPublisherStop(event_publisher_pt *event_publisher) {
+	(*event_publisher)->running = false;
+    //void * status;
+    // celixThread_join((*event_publisher)->sender, &status);
+	logHelper_stop((*event_publisher)->loghelper);
+	logHelper_destroy(&(*event_publisher)->loghelper);
+	return CELIX_SUCCESS;
+}
+
+void *produceEvents(void *handle) {
+    event_publisher_pt *event_publisher = handle;
+    while ((*event_publisher)->running && (*event_publisher)->eventAdminAdded) {
+        //   sleep(1000000); // 1 sec.
+        event_admin_service_pt *event_admin_service = &(*event_publisher)->event_admin_service;
+        event_admin_pt event_admin = (*event_admin_service)->eventAdmin;
+        if (event_admin_service != NULL) {
+            event_pt event;
+            properties_pt props = properties_create();
+            properties_set(props, "This is a key", "this is a value");
+            (*event_admin_service)->createEvent(event_admin, "log/error/eventpublishers/event", props, &event);
+            (*event_admin_service)->postEvent(event_admin, event);
+            (*event_admin_service)->sendEvent(event_admin, event);
+            printf("send event\n");
+        }
+    }
+    return CELIX_SUCCESS;
+}
+
+/*celix_thread_start_t eventPublisherSendEventThread(celix_thread_t *thd, void *handle) {
+    event_publisher_pt *client = (event_publisher_pt *) handle;
+
+    while ((*client)->running && (*client)->eventAdminAdded) {
+        apr_sleep(1000000); // 1 sec.
+
+        event_admin_service_pt *event_admin_service = &(*client)->event_admin_service;
+        event_admin_pt event_admin = (*event_admin_service)->eventAdmin;
+        if (event_admin_service != NULL) {
+            event_pt event;
+            properties_pt props = properties_create();
+            properties_set(props, "This is a key", "this is a value");
+            (*event_admin_service)->createEvent(event_admin, "log/error/eventpublishers/event", props, &event);
+            (*event_admin_service)->postEvent(event_admin, event);
+            (*event_admin_service)->sendEvent(event_admin, event);
+        }
+    }
+    celixThread_exit( APR_SUCCESS);
+	return NULL;*
+}*/
+
+celix_status_t eventPublisherAddingService(void * handle, service_reference_pt ref, void **service) {
+	celix_status_t status = CELIX_SUCCESS;
+	event_publisher_pt event_publisher = handle;
+	status = bundleContext_getService(event_publisher->context, ref, service);
+
+    return status;
+}
+
+celix_status_t eventPublisherAddedService(void * handle, service_reference_pt ref, void * service) {
+    event_publisher_pt data = (event_publisher_pt) handle;
+	logHelper_log(data->loghelper, OSGI_LOGSERVICE_DEBUG, "[PUB] Event admin added.");
+    printf(" added event admin");
+    data->event_admin_service = (event_admin_service_pt) service;
+    data->eventAdminAdded = true;
+	return CELIX_SUCCESS;
+}
+
+celix_status_t eventPublisherModifiedService(void * handle, service_reference_pt ref, void * service) {
+	event_publisher_pt data = (event_publisher_pt) handle;
+	logHelper_log(data->loghelper, OSGI_LOGSERVICE_DEBUG, "[PUB] Event admin modified.");
+	return CELIX_SUCCESS;
+}
+
+celix_status_t eventPublisherRemovedService(void * handle, service_reference_pt ref, void * service) {
+	event_publisher_pt data = (event_publisher_pt) handle;
+	logHelper_log(data->loghelper, OSGI_LOGSERVICE_DEBUG, "[PUB] Event admin removed.");
+
+    data->event_admin_service = NULL;
+    data->eventAdminAdded = false;
+	return CELIX_SUCCESS;
+}
+
+

http://git-wip-us.apache.org/repos/asf/celix/blob/3bce889b/bundles/log_service/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/bundles/log_service/CMakeLists.txt b/bundles/log_service/CMakeLists.txt
new file mode 100644
index 0000000..a67ff1a
--- /dev/null
+++ b/bundles/log_service/CMakeLists.txt
@@ -0,0 +1,59 @@
+# 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.
+
+celix_subproject(LOG_SERVICE "Option to enable building the Log Service bundles" ON DEPS framework)
+if (LOG_SERVICE)
+
+	add_library(log_service_api INTERFACE)
+	target_include_directories(log_service_api INTERFACE
+			$<BUILD_INTERFACE:${CMAKE_CURRENT_LIST_DIR}/include>
+			$<INSTALL_INTERFACE:include/celix/log_service>
+	)
+	install(TARGETS log_service_api EXPORT celix)
+	install(DIRECTORY include/ DESTINATION include/celix/log_service)
+
+	add_library(log_helper STATIC src/log_helper.c)
+	set_target_properties(log_helper PROPERTIES OUTPUT_NAME "celix_log_helper")
+	target_include_directories(log_helper PUBLIC
+			$<BUILD_INTERFACE:${CMAKE_CURRENT_LIST_DIR}/loghelper_include>
+			$<INSTALL_INTERFACE:include/celix/log_helper>
+	)
+	target_link_libraries(log_helper PUBLIC Celix::framework log_service_api)
+	install(TARGETS log_helper EXPORT celix DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT log_service)
+	install(DIRECTORY loghelper_include/ DESTINATION include/celix/log_helper COMPONENT log_service)
+
+    add_celix_bundle(log_service
+    	SYMBOLIC_NAME "apache_celix_log_service"
+    	NAME "Apache Celix Log Service"
+    	VERSION "1.1.0"
+    	SOURCES
+			src/log
+			src/log_entry
+			src/log_factory
+			src/log_service_impl
+			src/log_service_activator
+			src/log_reader_service_impl
+    )
+    target_include_directories(log_service PRIVATE src)
+    target_link_libraries(log_service PRIVATE log_service_api)
+    install_celix_bundle(log_service EXPORT celix COMPONENT log_service)
+
+    #Setup target aliases to match external usage
+    add_library(Celix::log_service_api ALIAS log_service_api)
+    add_library(Celix::log_service ALIAS log_service)
+    add_library(Celix::log_helper ALIAS log_helper)
+endif (LOG_SERVICE)

http://git-wip-us.apache.org/repos/asf/celix/blob/3bce889b/bundles/log_service/README.md
----------------------------------------------------------------------
diff --git a/bundles/log_service/README.md b/bundles/log_service/README.md
new file mode 100644
index 0000000..53d2c3b
--- /dev/null
+++ b/bundles/log_service/README.md
@@ -0,0 +1,19 @@
+# Log Service
+
+The Celix Log Service realizes an adapted implementation of the OSGi Compendium Log Service. This is a very simple implementation which only stores the log in memory. It can be combined with one of the available Log Writers to forward the buffered entries to e.g. stdout or syslog.
+
+To ease the use of the Log Service, the [Log Helper](public/include/log_helper.h) can be used. It wraps and therefore simplifies the log service usage.
+
+## Properties
+    LOGHELPER_ENABLE_STDOUT_FALLBACK      If set to any value and in case no Log Service is found the logs
+                                          are still printed on stdout. 
+
+## CMake option
+    BUILD_LOG_SERVICE=ON
+
+## Using info
+
+If the Celix Log Service is installed, 'find_package(Celix)' will set:
+ - The `Celix::log_service_api` interface (i.e. header only) library target
+ - The `Celix::log_service` bundle target
+ - The `Celix::log_helper` static library target

http://git-wip-us.apache.org/repos/asf/celix/blob/3bce889b/bundles/log_service/include/log_entry.h
----------------------------------------------------------------------
diff --git a/bundles/log_service/include/log_entry.h b/bundles/log_service/include/log_entry.h
new file mode 100644
index 0000000..e588774
--- /dev/null
+++ b/bundles/log_service/include/log_entry.h
@@ -0,0 +1,55 @@
+/**
+ *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.
+ */
+/*
+ * log_entry.h
+ *
+ *  \date       Jun 26, 2011
+ *  \author    	<a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
+ *  \copyright	Apache License, Version 2.0
+ */
+
+#ifndef LOG_ENTRY_H_
+#define LOG_ENTRY_H_
+
+#include "log_service.h"
+
+struct log_entry {
+    int errorCode;
+    log_level_t level;
+    char *message;
+    time_t time;
+
+    long bundleId;
+    char* bundleSymbolicName;
+};
+
+typedef struct log_entry * log_entry_pt;
+
+celix_status_t logEntry_create(long bundleId, const char* bundleSymbolicName , service_reference_pt reference,
+        log_level_t level, char *message, int errorCode,
+        log_entry_pt *entry);
+celix_status_t logEntry_destroy(log_entry_pt *entry);
+celix_status_t logEntry_getBundleSymbolicName(log_entry_pt entry, const char** bundleSymbolicName);
+celix_status_t logEntry_getBundleId(log_entry_pt entry, long *bundleId);
+celix_status_t logEntry_getErrorCode(log_entry_pt entry, int *errorCode);
+celix_status_t logEntry_getLevel(log_entry_pt entry, log_level_t *level);
+celix_status_t logEntry_getMessage(log_entry_pt entry, const char** message);
+celix_status_t logEntry_getTime(log_entry_pt entry, time_t *time);
+
+#endif /* LOG_ENTRY_H_ */

http://git-wip-us.apache.org/repos/asf/celix/blob/3bce889b/bundles/log_service/include/log_listener.h
----------------------------------------------------------------------
diff --git a/bundles/log_service/include/log_listener.h b/bundles/log_service/include/log_listener.h
new file mode 100644
index 0000000..b726994
--- /dev/null
+++ b/bundles/log_service/include/log_listener.h
@@ -0,0 +1,43 @@
+/**
+ *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.
+ */
+/*
+ * log_listener.h
+ *
+ *  \date       Jul 4, 2011
+ *  \author    	<a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
+ *  \copyright	Apache License, Version 2.0
+ */
+
+#ifndef LOG_LISTENER_H_
+#define LOG_LISTENER_H_
+
+#include "log_entry.h"
+#include "celix_errno.h"
+
+struct log_listener {
+    void *handle;
+    celix_status_t (*logged)(struct log_listener *listener, log_entry_pt entry);
+};
+
+typedef struct log_listener log_listener_t;
+typedef log_listener_t* log_listener_pt;
+
+celix_status_t logListener_logged(log_listener_pt listener, log_entry_pt entry);
+
+#endif /* LOG_LISTENER_H_ */

http://git-wip-us.apache.org/repos/asf/celix/blob/3bce889b/bundles/log_service/include/log_reader_service.h
----------------------------------------------------------------------
diff --git a/bundles/log_service/include/log_reader_service.h b/bundles/log_service/include/log_reader_service.h
new file mode 100644
index 0000000..6815123
--- /dev/null
+++ b/bundles/log_service/include/log_reader_service.h
@@ -0,0 +1,50 @@
+/**
+ *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.
+ */
+/*
+ * log_reader_service.h
+ *
+ *  \date       Jun 26, 2011
+ *  \author    	<a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
+ *  \copyright	Apache License, Version 2.0
+ */
+
+#ifndef LOG_READER_SERVICE_H_
+#define LOG_READER_SERVICE_H_
+
+
+#include "celix_errno.h"
+#include "linked_list.h"
+#include "log_listener.h"
+
+static const char * const OSGI_LOGSERVICE_READER_SERVICE_NAME = "log_reader_service";
+
+typedef struct log_reader_data log_reader_data_t;
+typedef log_reader_data_t* log_reader_data_pt;
+
+struct log_reader_service {
+    log_reader_data_pt reader;
+    celix_status_t (*getLog)(log_reader_data_pt reader, linked_list_pt *list);
+    celix_status_t (*addLogListener)(log_reader_data_pt reader, log_listener_pt listener);
+    celix_status_t (*removeLogListener)(log_reader_data_pt reader, log_listener_pt listener);
+    celix_status_t (*removeAllLogListener)(log_reader_data_pt reader);
+};
+
+typedef struct log_reader_service * log_reader_service_pt;
+
+#endif /* LOG_READER_SERVICE_H_ */

http://git-wip-us.apache.org/repos/asf/celix/blob/3bce889b/bundles/log_service/include/log_service.h
----------------------------------------------------------------------
diff --git a/bundles/log_service/include/log_service.h b/bundles/log_service/include/log_service.h
new file mode 100644
index 0000000..2691e35
--- /dev/null
+++ b/bundles/log_service/include/log_service.h
@@ -0,0 +1,58 @@
+/**
+ *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.
+ */
+/*
+ * log_service.h
+ *
+ *  \date       Jun 22, 2011
+ *  \author    	<a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
+ *  \copyright	Apache License, Version 2.0
+ */
+
+#ifndef LOG_SERVICE_H_
+#define LOG_SERVICE_H_
+
+#include "celix_errno.h"
+#include "service_reference.h"
+
+static const char * const OSGI_LOGSERVICE_NAME = "log_service";
+
+typedef struct log_service_data *log_service_data_pt;
+
+enum log_level
+{
+    OSGI_LOGSERVICE_ERROR = 0x00000001,
+    OSGI_LOGSERVICE_WARNING = 0x00000002,
+    OSGI_LOGSERVICE_INFO = 0x00000003,
+    OSGI_LOGSERVICE_DEBUG = 0x00000004,
+};
+
+typedef enum log_level log_level_t;
+
+struct log_service {
+    log_service_data_pt logger;
+    celix_status_t (*log)(log_service_data_pt logger, log_level_t level, char * message);
+    celix_status_t (*logSr)(log_service_data_pt logger, service_reference_pt reference, log_level_t level, char * message);
+};
+
+typedef struct log_service log_service_t;
+typedef log_service_t* log_service_pt;
+
+
+
+#endif /* LOG_SERVICE_H_ */

http://git-wip-us.apache.org/repos/asf/celix/blob/3bce889b/bundles/log_service/loghelper_include/log_helper.h
----------------------------------------------------------------------
diff --git a/bundles/log_service/loghelper_include/log_helper.h b/bundles/log_service/loghelper_include/log_helper.h
new file mode 100644
index 0000000..2ae9d83
--- /dev/null
+++ b/bundles/log_service/loghelper_include/log_helper.h
@@ -0,0 +1,36 @@
+/**
+ *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.
+ */
+
+
+#ifndef LOGHELPER_H_
+#define LOGHELPER_H_
+
+#include "bundle_context.h"
+#include "log_service.h"
+
+typedef struct log_helper log_helper_t;
+typedef struct log_helper* log_helper_pt;
+
+celix_status_t logHelper_create(bundle_context_pt context, log_helper_pt* log_helper);
+celix_status_t logHelper_start(log_helper_pt loghelper);
+celix_status_t logHelper_stop(log_helper_pt loghelper);
+celix_status_t logHelper_destroy(log_helper_pt* loghelper);
+celix_status_t logHelper_log(log_helper_pt loghelper, log_level_t level, char* message, ... );
+
+#endif /* LOGHELPER_H_ */

http://git-wip-us.apache.org/repos/asf/celix/blob/3bce889b/bundles/log_service/src/log.c
----------------------------------------------------------------------
diff --git a/bundles/log_service/src/log.c b/bundles/log_service/src/log.c
new file mode 100644
index 0000000..5b29318
--- /dev/null
+++ b/bundles/log_service/src/log.c
@@ -0,0 +1,375 @@
+/**
+ *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.
+ */
+/*
+ * log.c
+ *
+ *  \date       Jun 26, 2011
+ *  \author    	<a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
+ *  \copyright	Apache License, Version 2.0
+ */
+#include <stdlib.h>
+
+#include "log.h"
+#include "linked_list_iterator.h"
+#include "array_list.h"
+
+struct log {
+	linked_list_pt entries;
+	celix_thread_mutex_t lock;
+
+	array_list_pt listeners;
+	array_list_pt listenerEntries;
+
+	celix_thread_t listenerThread;
+	bool running;
+
+	celix_thread_cond_t entriesToDeliver;
+	celix_thread_mutex_t deliverLock;
+	celix_thread_mutex_t listenerLock;
+
+	int max_size;
+	bool store_debug;
+};
+
+static celix_status_t log_startListenerThread(log_pt logger);
+static celix_status_t log_stopListenerThread(log_pt logger);
+
+
+static void *log_listenerThread(void *data);
+
+celix_status_t log_create(int max_size, bool store_debug, log_pt *logger) {
+	celix_status_t status = CELIX_ENOMEM;
+
+	*logger = calloc(1, sizeof(**logger));
+
+	if (*logger != NULL) {
+		linkedList_create(&(*logger)->entries);
+
+		status = celixThreadMutex_create(&(*logger)->lock, NULL);
+
+		(*logger)->listeners = NULL;
+		(*logger)->listenerEntries = NULL;
+		(*logger)->listenerThread = celix_thread_default;
+		(*logger)->running = false;
+
+		(*logger)->max_size = max_size;
+		(*logger)->store_debug = store_debug;
+
+		arrayList_create(&(*logger)->listeners);
+		arrayList_create(&(*logger)->listenerEntries);
+
+		if (celixThreadCondition_init(&(*logger)->entriesToDeliver, NULL) != CELIX_SUCCESS) {
+			status = CELIX_INVALID_SYNTAX;
+		}
+		else if (celixThreadMutex_create(&(*logger)->deliverLock, NULL) != CELIX_SUCCESS) {
+			status = CELIX_INVALID_SYNTAX;
+		}
+		else if (celixThreadMutex_create(&(*logger)->listenerLock, NULL) != CELIX_SUCCESS) {
+			status = CELIX_INVALID_SYNTAX;
+		}
+		else {
+			status = CELIX_SUCCESS;
+		}
+	}
+
+	return status;
+}
+
+celix_status_t log_destroy(log_pt logger) {
+	celix_status_t status = CELIX_SUCCESS;
+
+	celixThreadMutex_destroy(&logger->listenerLock);
+	celixThreadMutex_destroy(&logger->deliverLock);
+	celixThreadCondition_destroy(&logger->entriesToDeliver);
+
+	arrayList_destroy(logger->listeners);
+	linked_list_iterator_pt iter = linkedListIterator_create(logger->entries, 0);
+	while (linkedListIterator_hasNext(iter)) {
+        	log_entry_pt entry = linkedListIterator_next(iter);
+        	if (arrayList_contains(logger->listenerEntries, entry)) {
+            		arrayList_removeElement(logger->listenerEntries, entry);
+        	}
+        	logEntry_destroy(&entry);
+    	}
+    	linkedListIterator_destroy(iter);
+
+    	array_list_iterator_pt entryIter = arrayListIterator_create(logger->listenerEntries);
+
+    	while (arrayListIterator_hasNext(entryIter)) {
+        	log_entry_pt entry = arrayListIterator_next(entryIter);
+        	logEntry_destroy(&entry);
+    	}
+    	arrayListIterator_destroy(entryIter);
+
+    	arrayList_destroy(logger->listenerEntries);
+	linkedList_destroy(logger->entries);
+
+	celixThreadMutex_destroy(&logger->lock);
+
+	free(logger);
+
+	return status;
+}
+
+celix_status_t log_addEntry(log_pt log, log_entry_pt entry) {
+	celixThreadMutex_lock(&log->lock);
+
+	if (log->max_size != 0) {
+		if (log->store_debug || entry->level != OSGI_LOGSERVICE_DEBUG) {
+			linkedList_addElement(log->entries, entry);
+		}
+	}
+
+	celixThreadMutex_lock(&log->deliverLock);
+	arrayList_add(log->listenerEntries, entry);
+	celixThreadMutex_unlock(&log->deliverLock);
+
+	celixThreadCondition_signal(&log->entriesToDeliver);
+
+	if (log->max_size != 0) {
+		if (log->max_size != -1) {
+			if (linkedList_size(log->entries) > log->max_size) {
+				log_entry_pt rentry = linkedList_removeFirst(log->entries);
+				if (rentry) {
+					celixThreadMutex_lock(&log->deliverLock);
+					arrayList_removeElement(log->listenerEntries, rentry);
+					logEntry_destroy(&rentry);
+					celixThreadMutex_unlock(&log->deliverLock);
+				}
+			}
+		}
+	}
+
+	celixThreadMutex_unlock(&log->lock);
+
+	return CELIX_SUCCESS;
+}
+
+celix_status_t log_getEntries(log_pt log, linked_list_pt *list) {
+	linked_list_pt entries = NULL;
+	if (linkedList_create(&entries) == CELIX_SUCCESS) {
+		linked_list_iterator_pt iter = NULL;
+
+		celixThreadMutex_lock(&log->lock);
+
+		iter = linkedListIterator_create(log->entries, 0);
+		while (linkedListIterator_hasNext(iter)) {
+			linkedList_addElement(entries, linkedListIterator_next(iter));
+		}
+		linkedListIterator_destroy(iter);
+
+		*list = entries;
+
+		celixThreadMutex_unlock(&log->lock);
+
+		return CELIX_SUCCESS;
+	} else {
+		return CELIX_ENOMEM;
+	}
+}
+
+celix_status_t log_bundleChanged(void *listener, bundle_event_pt event) {
+	celix_status_t status = CELIX_SUCCESS;
+	log_pt logger = ((bundle_listener_pt) listener)->handle;
+	log_entry_pt entry = NULL;
+
+	int messagesLength = 10;
+	char *messages[] = {
+		"BUNDLE_EVENT_INSTALLED",
+		"BUNDLE_EVENT_STARTED",
+		"BUNDLE_EVENT_STOPPED",
+		"BUNDLE_EVENT_UPDATED",
+		"BUNDLE_EVENT_UNINSTALLED",
+		"BUNDLE_EVENT_RESOLVED",
+		"BUNDLE_EVENT_UNRESOLVED",
+		"BUNDLE_EVENT_STARTING",
+		"BUNDLE_EVENT_STOPPING",
+		"BUNDLE_EVENT_LAZY_ACTIVATION"
+	};
+
+	char *message = NULL;
+	int i = 0;
+	for (i = 0; i < messagesLength; i++) {
+		if (event->type >> i == 1) {
+			message = messages[i];
+		}
+	}
+
+	if (message != NULL) {
+		status = logEntry_create(event->bundleId, event->bundleSymbolicName, NULL, OSGI_LOGSERVICE_INFO, message, 0, &entry);
+		if (status == CELIX_SUCCESS) {
+			status = log_addEntry(logger, entry);
+		}
+	}
+
+	return status;
+}
+
+celix_status_t log_frameworkEvent(void *listener, framework_event_pt event) {
+	celix_status_t status;
+	log_pt logger = ((framework_listener_pt) listener)->handle;
+	log_entry_pt entry = NULL;
+
+	status = logEntry_create(event->bundleId, event->bundleSymbolicName, NULL, (event->type == OSGI_FRAMEWORK_EVENT_ERROR) ? OSGI_LOGSERVICE_ERROR : OSGI_LOGSERVICE_INFO, event->error, event->errorCode, &entry);
+	if (status == CELIX_SUCCESS) {
+		status = log_addEntry(logger, entry);
+	}
+
+	return status;
+}
+
+celix_status_t log_addLogListener(log_pt logger, log_listener_pt listener) {
+	celix_status_t status;
+
+	status = celixThreadMutex_lock(&logger->listenerLock);
+
+	if (status == CELIX_SUCCESS) {
+		arrayList_add(logger->listeners, listener);
+		log_startListenerThread(logger);
+
+		status = celixThreadMutex_unlock(&logger->listenerLock);
+	}
+
+	return status;
+}
+
+celix_status_t log_removeLogListener(log_pt logger, log_listener_pt listener) {
+	celix_status_t status = CELIX_SUCCESS;
+
+    status += celixThreadMutex_lock(&logger->deliverLock);
+    status += celixThreadMutex_lock(&logger->listenerLock);
+
+	if (status == CELIX_SUCCESS) {
+	    bool last = false;
+
+		arrayList_removeElement(logger->listeners, listener);
+		if (arrayList_size(logger->listeners) == 0) {
+			status = log_stopListenerThread(logger);
+			last = true;
+		}
+
+        status += celixThreadMutex_unlock(&logger->listenerLock);
+        status += celixThreadMutex_unlock(&logger->deliverLock);
+
+		if (last) {
+		    status += celixThread_join(logger->listenerThread, NULL);
+		}
+	}
+
+	if (status != CELIX_SUCCESS) {
+		status = CELIX_SERVICE_EXCEPTION;
+	}
+
+	return status;
+}
+
+celix_status_t log_removeAllLogListener(log_pt logger) {
+	celix_status_t status;
+
+	status = celixThreadMutex_lock(&logger->listenerLock);
+
+    if (status == CELIX_SUCCESS) {
+    	arrayList_clear(logger->listeners);
+
+    	status = celixThreadMutex_unlock(&logger->listenerLock);
+    }
+
+	return status;
+}
+
+static celix_status_t log_startListenerThread(log_pt logger) {
+	celix_status_t status;
+
+	logger->running = true;
+    logger->running = true;
+    status = celixThread_create(&logger->listenerThread, NULL, log_listenerThread, logger);
+
+	return status;
+}
+
+static celix_status_t log_stopListenerThread(log_pt logger) {
+	celix_status_t status;
+
+	logger->running = false;
+
+	status = celixThreadCondition_signal(&logger->entriesToDeliver);
+
+	return status;
+}
+
+static void * log_listenerThread(void *data) {
+	celix_status_t status = CELIX_SUCCESS;
+
+	log_pt logger = data;
+
+	while (logger->running) {
+
+		status = celixThreadMutex_lock(&logger->deliverLock);
+
+		if ( status != CELIX_SUCCESS) {
+			logger->running = false;
+		}
+		else {
+			if (!arrayList_isEmpty(logger->listenerEntries)) {
+				log_entry_pt entry = (log_entry_pt) arrayList_remove(logger->listenerEntries, 0);
+
+				if (entry) {
+					status = celixThreadMutex_lock(&logger->listenerLock);
+					if (status != CELIX_SUCCESS) {
+						logger->running = false;
+						break;
+					} else {
+						array_list_iterator_pt it = arrayListIterator_create(logger->listeners);
+						while (arrayListIterator_hasNext(it)) {
+							log_listener_pt listener = arrayListIterator_next(it);
+							listener->logged(listener, entry);
+						}
+						arrayListIterator_destroy(it);
+
+						// destroy not-stored entries
+						if (!(logger->store_debug || entry->level != OSGI_LOGSERVICE_DEBUG)) {
+							logEntry_destroy(&entry);
+						}
+
+						status = celixThreadMutex_unlock(&logger->listenerLock);
+						if (status != CELIX_SUCCESS) {
+							logger->running = false;
+							break;
+						}
+					}
+				}
+			}
+
+			if (arrayList_isEmpty(logger->listenerEntries) && logger->running) {
+				celixThreadCondition_wait(&logger->entriesToDeliver, &logger->deliverLock);
+			}
+
+			status = celixThreadMutex_unlock(&logger->deliverLock);
+
+			if (status != CELIX_SUCCESS) {
+				logger->running = false;
+				break;
+			}
+		}
+
+	}
+
+    celixThread_exit(NULL);
+    return NULL;
+}

http://git-wip-us.apache.org/repos/asf/celix/blob/3bce889b/bundles/log_service/src/log.h
----------------------------------------------------------------------
diff --git a/bundles/log_service/src/log.h b/bundles/log_service/src/log.h
new file mode 100644
index 0000000..e0d7b87
--- /dev/null
+++ b/bundles/log_service/src/log.h
@@ -0,0 +1,48 @@
+/**
+ *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.
+ */
+/*
+ * log.h
+ *
+ *  \date       Jun 26, 2011
+ *  \author    	<a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
+ *  \copyright	Apache License, Version 2.0
+ */
+
+#ifndef LOG_H_
+#define LOG_H_
+
+#include "linked_list.h"
+#include "log_entry.h"
+#include "log_listener.h"
+
+typedef struct log * log_pt;
+
+celix_status_t log_create(int max_size, bool store_debug, log_pt *logger);
+celix_status_t log_destroy(log_pt logger);
+celix_status_t log_addEntry(log_pt log, log_entry_pt entry);
+celix_status_t log_getEntries(log_pt log, linked_list_pt *list);
+
+celix_status_t log_bundleChanged(void *listener, bundle_event_pt event);
+celix_status_t log_frameworkEvent(void *listener, framework_event_pt event);
+
+celix_status_t log_addLogListener(log_pt logger, log_listener_pt listener);
+celix_status_t log_removeLogListener(log_pt logger, log_listener_pt listener);
+celix_status_t log_removeAllLogListener(log_pt logger);
+
+#endif /* LOG_H_ */

http://git-wip-us.apache.org/repos/asf/celix/blob/3bce889b/bundles/log_service/src/log_entry.c
----------------------------------------------------------------------
diff --git a/bundles/log_service/src/log_entry.c b/bundles/log_service/src/log_entry.c
new file mode 100644
index 0000000..3a8603a
--- /dev/null
+++ b/bundles/log_service/src/log_entry.c
@@ -0,0 +1,94 @@
+/**
+ *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.
+ */
+/*
+ * log_entry.c
+ *
+ *  \date       Jun 26, 2011
+ *  \author    	<a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
+ *  \copyright	Apache License, Version 2.0
+ */
+
+#include <stddef.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "celix_errno.h"
+#include "log_service.h"
+#include "log_entry.h"
+
+celix_status_t logEntry_create(long bundleId, const char* bundleSymbolicName , service_reference_pt reference,
+        log_level_t level, char *message, int errorCode,
+        log_entry_pt *entry) {
+    celix_status_t status = CELIX_SUCCESS;
+
+    *entry = malloc(sizeof(**entry));
+    if (*entry == NULL) {
+        status = CELIX_ENOMEM;
+    } else {
+        (*entry)->level = level;
+        (*entry)->message = strdup(message);
+        (*entry)->errorCode = errorCode;
+        (*entry)->time = time(NULL);
+
+        (*entry)->bundleSymbolicName = strdup(bundleSymbolicName);
+        (*entry)->bundleId = bundleId;
+    }
+
+    return status;
+}
+
+celix_status_t logEntry_destroy(log_entry_pt *entry) {
+    if (*entry) {
+    	free((*entry)->bundleSymbolicName);
+        free((*entry)->message);
+        free(*entry);
+        *entry = NULL;
+    }
+    return CELIX_SUCCESS;
+}
+
+celix_status_t logEntry_getBundleSymbolicName(log_entry_pt entry, const char** bundleSymbolicName) {
+    *bundleSymbolicName = entry->bundleSymbolicName;
+    return CELIX_SUCCESS;
+}
+
+celix_status_t logEntry_getBundleId(log_entry_pt entry, long *bundleId) {
+    *bundleId = entry->bundleId;
+    return CELIX_SUCCESS;
+}
+
+celix_status_t logEntry_getErrorCode(log_entry_pt entry, int *errorCode) {
+    *errorCode = entry->errorCode;
+    return CELIX_SUCCESS;
+}
+
+celix_status_t logEntry_getLevel(log_entry_pt entry, log_level_t *level) {
+    *level = entry->level;
+    return CELIX_SUCCESS;
+}
+
+celix_status_t logEntry_getMessage(log_entry_pt entry, const char **message) {
+    *message = entry->message;
+    return CELIX_SUCCESS;
+}
+
+celix_status_t logEntry_getTime(log_entry_pt entry, time_t *time) {
+    *time = entry->time;
+    return CELIX_SUCCESS;
+}

http://git-wip-us.apache.org/repos/asf/celix/blob/3bce889b/bundles/log_service/src/log_factory.c
----------------------------------------------------------------------
diff --git a/bundles/log_service/src/log_factory.c b/bundles/log_service/src/log_factory.c
new file mode 100644
index 0000000..1c0a17a
--- /dev/null
+++ b/bundles/log_service/src/log_factory.c
@@ -0,0 +1,100 @@
+/**
+ *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.
+ */
+/*
+ * log_factory.c
+ *
+ *  \date       Jun 26, 2011
+ *  \author    	<a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
+ *  \copyright	Apache License, Version 2.0
+ */
+
+#include <stddef.h>
+#include <stdlib.h>
+
+
+#include "service_factory.h"
+#include "log_factory.h"
+#include "log_service_impl.h"
+
+struct log_service_factory {
+    log_pt log;
+};
+
+celix_status_t logFactory_create(log_pt log, service_factory_pt *factory) {
+    celix_status_t status = CELIX_SUCCESS;
+
+    *factory = calloc(1, sizeof(**factory));
+    if (*factory == NULL) {
+        status = CELIX_ENOMEM;
+    } else {
+        log_service_factory_pt factoryData = calloc(1, sizeof(*factoryData));
+        if (factoryData == NULL) {
+            status = CELIX_ENOMEM;
+        } else {
+            factoryData->log = log;
+
+            (*factory)->handle = factoryData;
+            (*factory)->getService = logFactory_getService;
+            (*factory)->ungetService = logFactory_ungetService;
+        }
+    }
+
+    return status;
+}
+
+celix_status_t logFactory_destroy(service_factory_pt *factory) {
+    celix_status_t status = CELIX_SUCCESS;
+
+
+    free((*factory)->handle);
+    free(*factory);
+
+    factory = NULL;
+
+    return status;
+}
+
+
+celix_status_t logFactory_getService(void *factory, bundle_pt bundle, service_registration_pt registration, void **service) {
+    log_service_factory_pt log_factory = factory;
+    log_service_pt log_service = NULL;
+    log_service_data_pt log_service_data = NULL;
+
+    logService_create(log_factory->log, bundle, &log_service_data);
+
+    log_service = calloc(1, sizeof(*log_service));
+    log_service->logger = log_service_data;
+    log_service->log = logService_log;
+  //  log_service->logSr = logService_logSr;
+
+    (*service) = log_service;
+
+    return CELIX_SUCCESS;
+}
+
+celix_status_t logFactory_ungetService(void *factory, bundle_pt bundle, service_registration_pt registration, void **service) {
+	log_service_pt log_service = *service;
+
+	logService_destroy(&log_service->logger);
+
+	free(*service);
+	*service = NULL;
+
+    return CELIX_SUCCESS;
+}

http://git-wip-us.apache.org/repos/asf/celix/blob/3bce889b/bundles/log_service/src/log_factory.h
----------------------------------------------------------------------
diff --git a/bundles/log_service/src/log_factory.h b/bundles/log_service/src/log_factory.h
new file mode 100644
index 0000000..8ebe5f8
--- /dev/null
+++ b/bundles/log_service/src/log_factory.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.
+ */
+/*
+ * log_factory.h
+ *
+ *  \date       Jun 26, 2011
+ *  \author    	<a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
+ *  \copyright	Apache License, Version 2.0
+ */
+
+#ifndef LOG_FACTORY_H_
+#define LOG_FACTORY_H_
+
+#include "log.h"
+
+typedef struct log_service_factory * log_service_factory_pt;
+
+celix_status_t logFactory_create(log_pt log, service_factory_pt *factory);
+celix_status_t logFactory_destroy(service_factory_pt *factory);
+celix_status_t logFactory_getService(void *factory, bundle_pt bundle, service_registration_pt registration, void **service);
+celix_status_t logFactory_ungetService(void *factory, bundle_pt bundle, service_registration_pt registration, void **service);
+
+
+#endif /* LOG_FACTORY_H_ */


Mime
View raw message