You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@celix.apache.org by pn...@apache.org on 2018/10/12 09:03:46 UTC

[29/34] celix git commit: CELIX-454: Refactors bundle locking handling in the framework. The current situation can lead to deadlocks. This is still wip.

CELIX-454: Refactors bundle locking handling in the framework. The current situation can lead to deadlocks. This is still wip.


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

Branch: refs/heads/develop
Commit: 4d33bcd1d484be071a341b08f0490e7f6df5e40d
Parents: 535bb88
Author: Pepijn Noltes <pe...@gmail.com>
Authored: Wed Oct 10 21:37:06 2018 +0200
Committer: Pepijn Noltes <pe...@gmail.com>
Committed: Wed Oct 10 21:37:06 2018 +0200

----------------------------------------------------------------------
 libs/framework/include/bundle.h             |    8 -
 libs/framework/include/constants.h          |    1 +
 libs/framework/include/framework_event.h    |    1 +
 libs/framework/private/mock/bundle_mock.c   |    6 +
 libs/framework/private/test/bundle_test.cpp |   51 -
 libs/framework/src/bundle.c                 |  115 ---
 libs/framework/src/bundle_cache.c           |    5 +-
 libs/framework/src/bundle_private.h         |    4 -
 libs/framework/src/framework.c              | 1152 +++++++++-------------
 libs/framework/src/framework_private.h      |   38 +-
 10 files changed, 504 insertions(+), 877 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/celix/blob/4d33bcd1/libs/framework/include/bundle.h
----------------------------------------------------------------------
diff --git a/libs/framework/include/bundle.h b/libs/framework/include/bundle.h
index fdc438b..676c8b4 100644
--- a/libs/framework/include/bundle.h
+++ b/libs/framework/include/bundle.h
@@ -102,14 +102,6 @@ FRAMEWORK_EXPORT int compareTo(service_reference_pt a, service_reference_pt b);
 
 FRAMEWORK_EXPORT celix_status_t bundle_getState(bundle_pt bundle, bundle_state_e *state);
 
-FRAMEWORK_EXPORT celix_status_t bundle_isLockable(bundle_pt bundle, bool *lockable);
-
-FRAMEWORK_EXPORT celix_status_t bundle_getLockingThread(bundle_pt bundle, celix_thread_t *thread);
-
-FRAMEWORK_EXPORT celix_status_t bundle_lock(bundle_pt bundle, bool *locked);
-
-FRAMEWORK_EXPORT celix_status_t bundle_unlock(bundle_pt bundle, bool *unlocked);
-
 FRAMEWORK_EXPORT celix_status_t bundle_closeAndDelete(bundle_pt bundle);
 
 FRAMEWORK_EXPORT celix_status_t bundle_close(bundle_pt bundle);

http://git-wip-us.apache.org/repos/asf/celix/blob/4d33bcd1/libs/framework/include/constants.h
----------------------------------------------------------------------
diff --git a/libs/framework/include/constants.h b/libs/framework/include/constants.h
index b9be0bd..c54f0cb 100644
--- a/libs/framework/include/constants.h
+++ b/libs/framework/include/constants.h
@@ -67,6 +67,7 @@ static const char *const OSGI_FRAMEWORK_EXPORT_LIBRARY = "Export-Library";
 static const char *const OSGI_FRAMEWORK_IMPORT_LIBRARY = "Import-Library";
 
 static const char *const OSGI_FRAMEWORK_FRAMEWORK_STORAGE = "org.osgi.framework.storage";
+static const char *const OSGI_FRAMEWORK_STORAGE_USE_TMP_DIR = "org.osgi.framework.storage.use.tmp.dir";
 static const char *const OSGI_FRAMEWORK_FRAMEWORK_STORAGE_CLEAN = "org.osgi.framework.storage.clean";
 static const char *const OSGI_FRAMEWORK_FRAMEWORK_STORAGE_CLEAN_ONFIRSTINIT = "onFirstInit";
 static const char *const OSGI_FRAMEWORK_FRAMEWORK_UUID = "org.osgi.framework.uuid";

http://git-wip-us.apache.org/repos/asf/celix/blob/4d33bcd1/libs/framework/include/framework_event.h
----------------------------------------------------------------------
diff --git a/libs/framework/include/framework_event.h b/libs/framework/include/framework_event.h
index d48e64c..ba3958e 100644
--- a/libs/framework/include/framework_event.h
+++ b/libs/framework/include/framework_event.h
@@ -46,6 +46,7 @@ enum framework_event_type {
 
 typedef enum framework_event_type framework_event_type_e;
 typedef struct framework_event *framework_event_pt;
+typedef struct framework_event framework_event_t;
 #ifdef __cplusplus
 }
 #endif

http://git-wip-us.apache.org/repos/asf/celix/blob/4d33bcd1/libs/framework/private/mock/bundle_mock.c
----------------------------------------------------------------------
diff --git a/libs/framework/private/mock/bundle_mock.c b/libs/framework/private/mock/bundle_mock.c
index c64a97b..f51dd88 100644
--- a/libs/framework/private/mock/bundle_mock.c
+++ b/libs/framework/private/mock/bundle_mock.c
@@ -157,6 +157,12 @@ celix_status_t bundle_setPersistentStateUninstalled(bundle_pt bundle) {
 	return mock_c()->returnValue().value.intValue;
 }
 
+celix_status_t bundle_getBundleLocation(bundle_pt bundle, const char **location) {
+	mock_c()->actualCall("bundle_getBundleLocation")
+	    ->withPointerParameters("bundle", bundle)
+	    ->withOutputParameter("location", location);
+	return mock_c()->returnValue().value.intValue;
+}
 
 void uninstallBundle(bundle_pt bundle) {
 	mock_c()->actualCall("uninstallBundle");

http://git-wip-us.apache.org/repos/asf/celix/blob/4d33bcd1/libs/framework/private/test/bundle_test.cpp
----------------------------------------------------------------------
diff --git a/libs/framework/private/test/bundle_test.cpp b/libs/framework/private/test/bundle_test.cpp
index f11b34d..43507c2 100644
--- a/libs/framework/private/test/bundle_test.cpp
+++ b/libs/framework/private/test/bundle_test.cpp
@@ -97,9 +97,6 @@ TEST(bundle, create) {
 	POINTERS_EQUAL(archive, actual->archive);
 	CHECK(actual->modules);
 	POINTERS_EQUAL(NULL, actual->manifest);
-	//	CHECK(actual->lock)
-	LONGS_EQUAL(0, actual->lockCount);
-	POINTERS_EQUAL(NULL, actual->lockThread.thread);
 	POINTERS_EQUAL(NULL, actual->framework);
 
 	mock().expectOneCall("module_destroy");
@@ -166,9 +163,6 @@ TEST(bundle, createFromArchive) {
 	POINTERS_EQUAL(archive, actual->archive);
 	CHECK(actual->modules);
 	POINTERS_EQUAL(NULL, actual->manifest);
-	//	CHECK(actual->lock)
-	LONGS_EQUAL(0, actual->lockCount);
-	POINTERS_EQUAL(NULL, actual->lockThread.thread);
 	POINTERS_EQUAL(framework, actual->framework);
 
 	arrayList_destroy(actual->modules);
@@ -706,51 +700,6 @@ TEST(bundle, revise) {
 	free(actual_manifest);
 }
 
-TEST(bundle, isLockable) {
-	bundle_pt bundle = (bundle_pt) malloc(sizeof(*bundle));
-	celixThreadMutex_create(&bundle->lock, NULL);
-	bundle->lockCount = 0;
-
-	bool lockable = false;
-	celix_status_t status = bundle_isLockable(bundle, &lockable);
-	LONGS_EQUAL(CELIX_SUCCESS, status);
-	//	FAIL("Test not fully implemented");
-
-	free(bundle);
-}
-
-
-TEST(bundle, lockingThread) {
-	bundle_pt bundle = (bundle_pt) malloc(sizeof(*bundle));
-	celixThreadMutex_create(&bundle->lock, NULL);
-	celix_thread_t thread;
-
-	bundle->lockCount = 0;
-
-	bool locked = false;
-	LONGS_EQUAL(CELIX_SUCCESS, bundle_lock(bundle, &locked));
-	CHECK(locked);
-	LONGS_EQUAL(1, bundle->lockCount);
-
-	LONGS_EQUAL(CELIX_SUCCESS, bundle_getLockingThread(bundle, &thread));
-	bool equals;
-	thread_equalsSelf(thread, &equals);
-	CHECK(equals);
-
-	bool unlocked;
-	bundle->lockCount = 1;
-	LONGS_EQUAL(CELIX_SUCCESS, bundle_unlock(bundle, &unlocked));
-	CHECK(unlocked);
-	LONGS_EQUAL(0, bundle->lockCount);
-
-	//try to unlock unlocked lock
-	LONGS_EQUAL(CELIX_SUCCESS, bundle_unlock(bundle, &unlocked));
-	CHECK_FALSE(unlocked);
-	LONGS_EQUAL(0, bundle->lockCount);
-
-	celixThreadMutex_destroy(&bundle->lock);
-	free(bundle);
-}
 
 TEST(bundle, close) {
 	bundle_pt bundle = (bundle_pt) malloc(sizeof(*bundle));

http://git-wip-us.apache.org/repos/asf/celix/blob/4d33bcd1/libs/framework/src/bundle.c
----------------------------------------------------------------------
diff --git a/libs/framework/src/bundle.c b/libs/framework/src/bundle.c
index ebaa870..6d605d7 100644
--- a/libs/framework/src/bundle.c
+++ b/libs/framework/src/bundle.c
@@ -53,13 +53,6 @@ celix_status_t bundle_create(bundle_pt * bundle) {
         module = module_createFrameworkModule((*bundle));
         bundle_addModule(*bundle, module);
 
-        status = celixThreadMutex_create(&(*bundle)->lock, NULL);
-        if (status != CELIX_SUCCESS) {
-        	status = CELIX_ILLEGAL_STATE;
-        } else {
-			(*bundle)->lockCount = 0;
-			(*bundle)->lockThread = celix_thread_default;
-        }
 	}
 	framework_logIfError(logger, status, NULL, "Failed to create bundle");
 
@@ -88,13 +81,6 @@ celix_status_t bundle_createFromArchive(bundle_pt * bundle, framework_pt framewo
 	status = bundle_createModule(*bundle, &module);
 	if (status == CELIX_SUCCESS) {
 		bundle_addModule(*bundle, module);
-        status = celixThreadMutex_create(&(*bundle)->lock, NULL);
-        if (status != CELIX_SUCCESS) {
-			status = CELIX_ILLEGAL_STATE;
-		} else {
-			(*bundle)->lockCount = 0;
-			(*bundle)->lockThread = celix_thread_default;
-		}
 	} else {
 	    status = CELIX_FILE_IO_EXCEPTION;
 	}
@@ -112,7 +98,6 @@ celix_status_t bundle_destroy(bundle_pt bundle) {
 	}
 	arrayListIterator_destroy(iter);
 	arrayList_destroy(bundle->modules);
-	celixThreadMutex_destroy(&bundle->lock);
 
 	free(bundle);
 
@@ -431,106 +416,6 @@ celix_status_t bundle_isSystemBundle(bundle_pt bundle, bool *systemBundle) {
 	return status;
 }
 
-celix_status_t bundle_isLockable(bundle_pt bundle, bool *lockable) {
-	celix_status_t status;
-
-	status = celixThreadMutex_lock(&bundle->lock);
-	if (status != CELIX_SUCCESS) {
-		status = CELIX_BUNDLE_EXCEPTION;
-	} else {
-		bool equals;
-		status = thread_equalsSelf(bundle->lockThread, &equals);
-		if (status == CELIX_SUCCESS) {
-			*lockable = (bundle->lockCount == 0) || (equals);
-		}
-
-		status = celixThreadMutex_unlock(&bundle->lock);
-		if (status != CELIX_SUCCESS) {
-			status = CELIX_BUNDLE_EXCEPTION;
-		}
-	}
-
-	framework_logIfError(logger, status, NULL, "Failed to check if bundle is lockable");
-
-	return status;
-}
-
-celix_status_t bundle_getLockingThread(bundle_pt bundle, celix_thread_t *thread) {
-	celix_status_t status;
-
-	status = celixThreadMutex_lock(&bundle->lock);
-	if (status != CELIX_SUCCESS) {
-		status = CELIX_BUNDLE_EXCEPTION;
-	} else {
-		*thread = bundle->lockThread;
-
-		status = celixThreadMutex_unlock(&bundle->lock);
-		if (status != CELIX_SUCCESS) {
-			status = CELIX_BUNDLE_EXCEPTION;
-		}
-	}
-
-	framework_logIfError(logger, status, NULL, "Failed to get locking thread");
-
-	return status;
-}
-
-celix_status_t bundle_lock(bundle_pt bundle, bool *locked) {
-	celix_status_t status;
-	bool equals;
-
-	celixThreadMutex_lock(&bundle->lock);
-
-	status = thread_equalsSelf(bundle->lockThread, &equals);
-	if (status == CELIX_SUCCESS) {
-		if ((bundle->lockCount > 0) && !equals) {
-			*locked = false;
-		} else {
-			bundle->lockCount++;
-			bundle->lockThread = celixThread_self();
-			*locked = true;
-		}
-	}
-
-	celixThreadMutex_unlock(&bundle->lock);
-
-	framework_logIfError(logger, status, NULL, "Failed to lock bundle");
-
-	return status;
-}
-
-celix_status_t bundle_unlock(bundle_pt bundle, bool *unlocked) {
-	celix_status_t status = CELIX_SUCCESS;
-
-	bool equals;
-
-	celixThreadMutex_lock(&bundle->lock);
-
-	if (bundle->lockCount == 0) {
-		*unlocked = false;
-	} else {
-		status = thread_equalsSelf(bundle->lockThread, &equals);
-		if (status == CELIX_SUCCESS) {
-			if ((bundle->lockCount > 0) && !equals) {
-				*unlocked = false;
-			}
-			else{
-			   bundle->lockCount--;
-			   if (bundle->lockCount == 0) {
-			   	bundle->lockThread = celix_thread_default;
-			   }
-			   *unlocked = true;
-		   }
-	   }
-	}
-
-	celixThreadMutex_unlock(&bundle->lock);
-
-	framework_logIfError(logger, status, NULL, "Failed to unlock bundle");
-
-	return status;
-}
-
 celix_status_t bundle_close(bundle_pt bundle) {
 	bundle_archive_pt archive = NULL;
 	

http://git-wip-us.apache.org/repos/asf/celix/blob/4d33bcd1/libs/framework/src/bundle_cache.c
----------------------------------------------------------------------
diff --git a/libs/framework/src/bundle_cache.c b/libs/framework/src/bundle_cache.c
index 054aa80..489bd59 100644
--- a/libs/framework/src/bundle_cache.c
+++ b/libs/framework/src/bundle_cache.c
@@ -55,9 +55,10 @@ celix_status_t bundleCache_create(const char *fwUUID, celix_properties_t *config
 	if (cache == NULL) {
 		status = CELIX_ENOMEM;
 	} else {
-		char* cacheDir = (char*)properties_get(configurationMap, (char *) OSGI_FRAMEWORK_FRAMEWORK_STORAGE);
+		const char* cacheDir = celix_properties_get(configurationMap, OSGI_FRAMEWORK_FRAMEWORK_STORAGE, ".cache");
+		bool useTmpDir = celix_properties_getAsBool(configurationMap, OSGI_FRAMEWORK_STORAGE_USE_TMP_DIR, false);
 		cache->configurationMap = configurationMap;
-		if (cacheDir == NULL) {
+		if (cacheDir == NULL || useTmpDir) {
 			//Using /tmp dir for cache, so that multiple frameworks can be launched
 			//instead of cacheDir = ".cache";
 			const char *pg = bundleCache_progamName();

http://git-wip-us.apache.org/repos/asf/celix/blob/4d33bcd1/libs/framework/src/bundle_private.h
----------------------------------------------------------------------
diff --git a/libs/framework/src/bundle_private.h b/libs/framework/src/bundle_private.h
index 1c295c3..82bf391 100644
--- a/libs/framework/src/bundle_private.h
+++ b/libs/framework/src/bundle_private.h
@@ -35,10 +35,6 @@ struct bundle {
 	array_list_pt modules;
 	manifest_pt manifest;
 
-	celix_thread_mutex_t lock;
-	int lockCount;
-	celix_thread_t lockThread;
-
 	struct framework * framework;
 };
 

http://git-wip-us.apache.org/repos/asf/celix/blob/4d33bcd1/libs/framework/src/framework.c
----------------------------------------------------------------------
diff --git a/libs/framework/src/framework.c b/libs/framework/src/framework.c
index 4284f9a..9ce3fdb 100644
--- a/libs/framework/src/framework.c
+++ b/libs/framework/src/framework.c
@@ -60,17 +60,97 @@ struct celix_bundle_activator {
     destroy_function_fp destroy;
 };
 
-celix_status_t framework_setBundleStateAndNotify(framework_pt framework, bundle_pt bundle, int state);
-celix_status_t framework_markBundleResolved(framework_pt framework, module_pt module);
+typedef struct celix_framework_bundle_entry {
+    celix_bundle_t *bnd;
+    long bndId;
+
+    celix_thread_mutex_t useMutex; //protects useCount
+    celix_thread_cond_t useCond;
+    size_t useCount;
+} celix_framework_bundle_entry_t;
+
+
+static inline celix_framework_bundle_entry_t* fw_bundleEntry_create(celix_bundle_t *bnd) {
+    celix_framework_bundle_entry_t *entry = calloc(1, sizeof(*entry));
+    entry->bnd = bnd;
+
+    entry->bndId = celix_bundle_getId(bnd);
+    entry->useCount = 0;
+    celixThreadMutex_create(&entry->useMutex, NULL);
+    celixThreadCondition_init(&entry->useCond, NULL);
+    return entry;
+}
+
+static inline void fw_bundleEntry_destroy(celix_framework_bundle_entry_t *entry, bool wait) {
+    celixThreadMutex_lock(&entry->useMutex);
+    while (wait && entry->useCount != 0) {
+        celixThreadCondition_wait(&entry->useCond, &entry->useMutex);
+    }
+    celixThreadMutex_unlock(&entry->useMutex);
+
+    //destroy
+    celixThreadMutex_destroy(&entry->useMutex);
+    celixThreadCondition_destroy(&entry->useCond);
+    free(entry);
+}
+
 
-celix_status_t framework_acquireBundleLock(framework_pt framework, bundle_pt bundle, int desiredStates);
-bool framework_releaseBundleLock(framework_pt framework, bundle_pt bundle);
+static inline void fw_bundleEntry_increaseUseCount(framework_t *fw, long bndId) {
+    assert(bndId >= 0);
+    if (bndId > 0) { //note not in/decreasing framework bundle use count, to prevent that the framework is waiting on it self
+        celixThreadMutex_lock(&fw->installedBundles.mutex);
+        int size = celix_arrayList_size(fw->installedBundles.entries);
+        for (int i = 0; i < size; ++i) {
+            celix_framework_bundle_entry_t *entry = celix_arrayList_get(fw->installedBundles.entries, i);
+            if (entry != NULL && entry->bndId == bndId) {
+                celixThreadMutex_lock(&entry->useMutex);
+                entry->useCount += 1;
+                celixThreadMutex_unlock(&entry->useMutex);
+            }
+        }
+        celixThreadMutex_unlock(&fw->installedBundles.mutex);
+    }
+}
 
-bool framework_acquireGlobalLock(framework_pt framework);
-celix_status_t framework_releaseGlobalLock(framework_pt framework);
+static inline size_t fw_bundleEntry_getUseCount(framework_t *fw, long bndId) {
+    size_t count = 0;
+    celixThreadMutex_lock(&fw->installedBundles.mutex);
+    int size = celix_arrayList_size(fw->installedBundles.entries);
+    for (int i = 0; i < size; ++i) {
+        celix_framework_bundle_entry_t *entry = celix_arrayList_get(fw->installedBundles.entries, i);
+        if (entry != NULL && entry->bndId == bndId) {
+            celixThreadMutex_lock(&entry->useMutex);
+            count = entry->useCount;
+            celixThreadMutex_unlock(&entry->useMutex);
+        }
+    }
+    celixThreadMutex_unlock(&fw->installedBundles.mutex);
+    return count;
+}
+
+static inline void fw_bundleEntry_decreaseUseCount(framework_t *fw, long bndId) {
+    assert(bndId >= 0);
+    if (bndId > 0) { //note not in/decreasing framework bundle use count, to prevent that the framework is waiting on it self
+        celixThreadMutex_lock(&fw->installedBundles.mutex);
+        int size = celix_arrayList_size(fw->installedBundles.entries);
+        for (int i = 0; i < size; ++i) {
+            celix_framework_bundle_entry_t *entry = celix_arrayList_get(fw->installedBundles.entries, i);
+            if (entry != NULL && entry->bndId == bndId) {
+                celixThreadMutex_lock(&entry->useMutex);
+                assert(entry->useCount > 0);
+                entry->useCount -= 1;
+                if (entry->useCount == 0) {
+                    celixThreadCondition_broadcast(&entry->useCond);
+                }
+                celixThreadMutex_unlock(&entry->useMutex);
+            }
+        }
+        celixThreadMutex_unlock(&fw->installedBundles.mutex);
+    }
+}
 
-celix_status_t framework_acquireInstallLock(framework_pt framework, const char* location);
-celix_status_t framework_releaseInstallLock(framework_pt framework, const char* location);
+celix_status_t framework_setBundleStateAndNotify(framework_pt framework, bundle_pt bundle, int state);
+celix_status_t framework_markBundleResolved(framework_pt framework, module_pt module);
 
 long framework_getNextBundleId(framework_pt framework);
 
@@ -274,38 +354,33 @@ celix_status_t framework_create(framework_pt *framework, properties_pt config) {
         celixThreadMutexAttr_create(&attr);
         celixThreadMutexAttr_settype(&attr, CELIX_THREAD_MUTEX_RECURSIVE);
 
-        status = CELIX_DO_IF(status, celixThreadCondition_init(&(*framework)->condition, NULL));
-        status = CELIX_DO_IF(status, celixThreadMutex_create(&(*framework)->mutex, NULL));
-        status = CELIX_DO_IF(status, celixThreadMutex_create(&(*framework)->installedBundleMapLock, NULL));  //TODO refactor to use use count with condition (see serviceListeners)
-        status = CELIX_DO_IF(status, celixThreadMutex_create(&(*framework)->bundleLock, NULL));  //TODO refactor to use use count with condition (see serviceListeners)
-        status = CELIX_DO_IF(status, celixThreadMutex_create(&(*framework)->installRequestLock, NULL));  //TODO refactor to use use count with condition (see serviceListeners)
-        status = CELIX_DO_IF(status, celixThreadMutex_create(&(*framework)->dispatcherLock, NULL));  //TODO refactor to use use count with condition (see serviceListeners)
+        status = CELIX_DO_IF(status, celixThreadCondition_init(&(*framework)->shutdown.cond, NULL));
+        status = CELIX_DO_IF(status, celixThreadMutex_create(&(*framework)->shutdown.mutex, NULL));
+        status = CELIX_DO_IF(status, celixThreadMutex_create(&(*framework)->dispatcher.mutex, NULL));  //TODO refactor to use use count with condition (see serviceListeners)
         status = CELIX_DO_IF(status, celixThreadMutex_create(&(*framework)->serviceListenersLock, &attr));
         status = CELIX_DO_IF(status, celixThreadMutex_create(&(*framework)->frameworkListenersLock, &attr));  //TODO refactor to use use count with condition (see serviceListeners)
         status = CELIX_DO_IF(status, celixThreadMutex_create(&(*framework)->bundleListenerLock, NULL));  //TODO refactor to use use count with condition (see serviceListeners)
-        status = CELIX_DO_IF(status, celixThreadCondition_init(&(*framework)->dispatcher, NULL));
+        status = CELIX_DO_IF(status, celixThreadMutex_create(&(*framework)->installedBundles.mutex, NULL));  //TODO refactor to use use count with condition (see serviceListeners)
+        status = CELIX_DO_IF(status, celixThreadCondition_init(&(*framework)->dispatcher.cond, NULL));
         if (status == CELIX_SUCCESS) {
             (*framework)->bundle = NULL;
-            (*framework)->installedBundleMap = NULL;
             (*framework)->registry = NULL;
-            (*framework)->interrupted = false;
-            (*framework)->shutdown = false;
-            (*framework)->globalLockWaitersList = NULL;
-            (*framework)->globalLockCount = 0;
-            (*framework)->globalLockThread = celix_thread_default;
+            (*framework)->shutdown.done = false;
+            (*framework)->dispatcher.active = true;
             (*framework)->nextBundleId = 1L; //system bundle is 0
             (*framework)->cache = NULL;
             (*framework)->installRequestMap = hashMap_create(utils_stringHash, utils_stringHash, utils_stringEquals, utils_stringEquals);
+            (*framework)->installedBundles.entries = celix_arrayList_create();
             (*framework)->serviceListeners = NULL;
             (*framework)->bundleListeners = NULL;
             (*framework)->frameworkListeners = NULL;
-            (*framework)->requests = NULL;
+            (*framework)->dispatcher.requests = NULL;
             (*framework)->configurationMap = config;
             (*framework)->logger = logger;
 
 
             status = CELIX_DO_IF(status, bundle_create(&(*framework)->bundle));
-            status = CELIX_DO_IF(status, arrayList_create(&(*framework)->globalLockWaitersList));
+            status = CELIX_DO_IF(status, bundle_getBundleId((*framework)->bundle, &(*framework)->bundleId));
             status = CELIX_DO_IF(status, bundle_setFramework((*framework)->bundle, (*framework)));
             if (status == CELIX_SUCCESS) {
                 //
@@ -328,55 +403,63 @@ celix_status_t framework_create(framework_pt *framework, properties_pt config) {
 
 celix_status_t framework_destroy(framework_pt framework) {
     celix_status_t status = CELIX_SUCCESS;
-    celixThreadMutex_lock(&framework->installedBundleMapLock);
-
-    if (framework->installedBundleMap != NULL) {
-        hash_map_iterator_pt iterator = hashMapIterator_create(framework->installedBundleMap);
-        while (hashMapIterator_hasNext(iterator)) {
-            hash_map_entry_pt entry = hashMapIterator_nextEntry(iterator);
-            bundle_pt bundle = (bundle_pt) hashMapEntry_getValue(entry);
-            char * key = hashMapEntry_getKey(entry);
-            bundle_archive_pt archive = NULL;
 
-            bool systemBundle = false;
-            bundle_isSystemBundle(bundle, &systemBundle);
-            if (systemBundle) {
-                bundle_context_t *context = NULL;
-                bundle_getContext(framework->bundle, &context);
-                bundleContext_destroy(context);
-            }
+    //Note the shutdown thread can not be joined on the framework_shutdown (which is normally more logical),
+    //because a shutdown can be initiated from a bundle.
+    //A bundle cannot be stopped when it is waiting for a framework shutdown -> hence a shutdown thread which
+    //has not been joined yet.
+    celixThread_join(framework->shutdown.thread, NULL);
+
+
+    celixThreadMutex_lock(&framework->installedBundles.mutex);
+    for (int i = 0; i < celix_arrayList_size(framework->installedBundles.entries); ++i) {
+        celix_framework_bundle_entry_t *entry = celix_arrayList_get(framework->installedBundles.entries, i);
+        celixThreadMutex_lock(&entry->useMutex);
+        size_t count = entry->useCount;
+        celixThreadMutex_unlock(&entry->useMutex);
+        bundle_t *bnd = entry->bnd;
+        if (count > 0) {
+            fw_log(framework->logger, OSGI_FRAMEWORK_LOG_WARNING, "Cannot destroy framework (yet), a bundle use count is not 0 (%ui)", count);
+        }
+        fw_bundleEntry_destroy(entry, true);
 
-            if (bundle_getArchive(bundle, &archive) == CELIX_SUCCESS) {
-                if (!systemBundle) {
-                    bundle_revision_pt revision = NULL;
-                    array_list_pt handles = NULL;
-                    status = CELIX_DO_IF(status, bundleArchive_getCurrentRevision(archive, &revision));
-                    status = CELIX_DO_IF(status, bundleRevision_getHandles(revision, &handles));
-                    if (handles != NULL) {
-                        for (int i = arrayList_size(handles) - 1; i >= 0; i--) {
-                            void *handle = arrayList_get(handles, i);
-                            fw_closeLibrary(handle);
-                        }
+        bool systemBundle = false;
+        bundle_isSystemBundle(bnd, &systemBundle);
+        if (systemBundle) {
+            bundle_context_t *context = NULL;
+            bundle_getContext(framework->bundle, &context);
+            bundleContext_destroy(context);
+        }
+
+        bundle_archive_t *archive = NULL;
+        if (bundle_getArchive(bnd, &archive) == CELIX_SUCCESS) {
+            if (!systemBundle) {
+                bundle_revision_pt revision = NULL;
+                array_list_pt handles = NULL;
+                status = CELIX_DO_IF(status, bundleArchive_getCurrentRevision(archive, &revision));
+                status = CELIX_DO_IF(status, bundleRevision_getHandles(revision, &handles));
+                if (handles != NULL) {
+                    for (int i = arrayList_size(handles) - 1; i >= 0; i--) {
+                        void *handle = arrayList_get(handles, i);
+                        fw_closeLibrary(handle);
                     }
                 }
-
-                bundleArchive_destroy(archive);
             }
-            bundle_destroy(bundle);
-            hashMapIterator_remove(iterator);
-            free(key);
+
+            bundleArchive_destroy(archive);
         }
-        hashMapIterator_destroy(iterator);
+        bundle_destroy(bnd);
+
     }
+    celix_arrayList_destroy(framework->installedBundles.entries);
+    celixThreadMutex_destroy(&framework->installedBundles.mutex);
+
 
-    celixThreadMutex_unlock(&framework->installedBundleMapLock);
 
 	hashMap_destroy(framework->installRequestMap, false, false);
 
 	serviceRegistry_destroy(framework->registry);
 
-	arrayList_destroy(framework->globalLockWaitersList);
-
     if (framework->serviceListeners != NULL) {
         arrayList_destroy(framework->serviceListeners);
     }
@@ -387,31 +470,25 @@ celix_status_t framework_destroy(framework_pt framework) {
         arrayList_destroy(framework->frameworkListeners);
     }
 
-	if(framework->requests){
+	if(framework->dispatcher.requests){
 	    int i;
-	    for (i = 0; i < arrayList_size(framework->requests); i++) {
-	        request_pt request = arrayList_get(framework->requests, i);
+	    for (i = 0; i < arrayList_size(framework->dispatcher.requests); i++) {
+	        request_pt request = arrayList_get(framework->dispatcher.requests, i);
 	        free(request->bundleSymbolicName);
 	        free(request);
 	    }
-	    arrayList_destroy(framework->requests);
-	}
-	if(framework->installedBundleMap!=NULL){
-		hashMap_destroy(framework->installedBundleMap, true, false);
+	    arrayList_destroy(framework->dispatcher.requests);
 	}
 
 	bundleCache_destroy(&framework->cache);
 
-	celixThreadCondition_destroy(&framework->dispatcher);
+	celixThreadCondition_destroy(&framework->dispatcher.cond);
     celixThreadMutex_destroy(&framework->serviceListenersLock);
     celixThreadMutex_destroy(&framework->frameworkListenersLock);
 	celixThreadMutex_destroy(&framework->bundleListenerLock);
-	celixThreadMutex_destroy(&framework->dispatcherLock);
-	celixThreadMutex_destroy(&framework->installRequestLock);
-	celixThreadMutex_destroy(&framework->bundleLock);
-	celixThreadMutex_destroy(&framework->installedBundleMapLock);
-	celixThreadMutex_destroy(&framework->mutex);
-	celixThreadCondition_destroy(&framework->condition);
+	celixThreadMutex_destroy(&framework->dispatcher.mutex);
+	celixThreadMutex_destroy(&framework->shutdown.mutex);
+	celixThreadCondition_destroy(&framework->shutdown.cond);
 
     logger = hashMap_get(framework->configurationMap, "logger");
     if (logger == NULL) {
@@ -443,12 +520,11 @@ celix_status_t fw_init(framework_pt framework) {
     properties_set(framework->configurationMap, (char*) OSGI_FRAMEWORK_FRAMEWORK_UUID, uuid);
 
 	celix_status_t status = CELIX_SUCCESS;
-	status = CELIX_DO_IF(status, framework_acquireBundleLock(framework, framework->bundle, OSGI_FRAMEWORK_BUNDLE_INSTALLED|OSGI_FRAMEWORK_BUNDLE_RESOLVED|OSGI_FRAMEWORK_BUNDLE_STARTING|OSGI_FRAMEWORK_BUNDLE_ACTIVE));
 	status = CELIX_DO_IF(status, arrayList_create(&framework->serviceListeners)); //entry is celix_fw_service_listener_entry_t
 	status = CELIX_DO_IF(status, arrayList_create(&framework->bundleListeners));
 	status = CELIX_DO_IF(status, arrayList_create(&framework->frameworkListeners));
-	status = CELIX_DO_IF(status, arrayList_create(&framework->requests));
-	status = CELIX_DO_IF(status, celixThread_create(&framework->dispatcherThread, NULL, fw_eventDispatcher, framework));
+	status = CELIX_DO_IF(status, arrayList_create(&framework->dispatcher.requests));
+	status = CELIX_DO_IF(status, celixThread_create(&framework->dispatcher.thread, NULL, fw_eventDispatcher, framework));
 	status = CELIX_DO_IF(status, bundle_getState(framework->bundle, &state));
 	if (status == CELIX_SUCCESS) {
 	    if ((state == OSGI_FRAMEWORK_BUNDLE_INSTALLED) || (state == OSGI_FRAMEWORK_BUNDLE_RESOLVED)) {
@@ -466,14 +542,15 @@ celix_status_t fw_init(framework_pt framework) {
         }
 	}
 
-	if (status == CELIX_SUCCESS) {
-        framework->installedBundleMap = hashMap_create(utils_stringHash, NULL, utils_stringEquals, NULL);
-	}
-
     status = CELIX_DO_IF(status, bundle_getArchive(framework->bundle, &archive));
     status = CELIX_DO_IF(status, bundleArchive_getLocation(archive, &location));
     if (status == CELIX_SUCCESS) {
-        hashMap_put(framework->installedBundleMap, strdup(location), framework->bundle);
+        long bndId = -1L;
+        bundle_getBundleId(framework->bundle, &bndId);
+        celix_framework_bundle_entry_t *entry = fw_bundleEntry_create(framework->bundle);
+        celixThreadMutex_lock(&framework->installedBundles.mutex);
+        celix_arrayList_add(framework->installedBundles.entries, entry);
+        celixThreadMutex_unlock(&framework->installedBundles.mutex);
     }
     status = CELIX_DO_IF(status, bundle_getCurrentModule(framework->bundle, &module));
     if (status == CELIX_SUCCESS) {
@@ -511,7 +588,6 @@ celix_status_t fw_init(framework_pt framework) {
 
     status = CELIX_DO_IF(status, serviceRegistry_create(framework, fw_serviceChanged, &framework->registry));
     status = CELIX_DO_IF(status, framework_setBundleStateAndNotify(framework, framework->bundle, OSGI_FRAMEWORK_BUNDLE_STARTING));
-    status = CELIX_DO_IF(status, celixThreadCondition_init(&framework->shutdownGate, NULL));
 
     bundle_context_t *context = NULL;
     status = CELIX_DO_IF(status, bundleContext_create(framework, framework->logger, framework->bundle, &context));
@@ -558,8 +634,6 @@ celix_status_t fw_init(framework_pt framework) {
        fw_logCode(framework->logger, OSGI_FRAMEWORK_LOG_ERROR, status, "Could not init framework");
     }
 
-    framework_releaseBundleLock(framework, framework->bundle);
-
 	return status;
 }
 
@@ -567,7 +641,6 @@ celix_status_t framework_start(framework_pt framework) {
 	celix_status_t status = CELIX_SUCCESS;
 	bundle_state_e state = OSGI_FRAMEWORK_BUNDLE_UNKNOWN;
 
-	status = CELIX_DO_IF(status, framework_acquireBundleLock(framework, framework->bundle, OSGI_FRAMEWORK_BUNDLE_INSTALLED|OSGI_FRAMEWORK_BUNDLE_RESOLVED|OSGI_FRAMEWORK_BUNDLE_STARTING|OSGI_FRAMEWORK_BUNDLE_ACTIVE));
 	status = CELIX_DO_IF(status, bundle_getState(framework->bundle, &state));
 	if (status == CELIX_SUCCESS) {
 	    if ((state == OSGI_FRAMEWORK_BUNDLE_INSTALLED) || (state == OSGI_FRAMEWORK_BUNDLE_RESOLVED)) {
@@ -580,12 +653,10 @@ celix_status_t framework_start(framework_pt framework) {
 	    if (state == OSGI_FRAMEWORK_BUNDLE_STARTING) {
 	        status = CELIX_DO_IF(status, framework_setBundleStateAndNotify(framework, framework->bundle, OSGI_FRAMEWORK_BUNDLE_ACTIVE));
 	    }
-
-	    framework_releaseBundleLock(framework, framework->bundle);
 	}
 
 	status = CELIX_DO_IF(status, fw_fireBundleEvent(framework, OSGI_FRAMEWORK_BUNDLE_EVENT_STARTED, framework->bundle));
-	status = CELIX_DO_IF(status, fw_fireFrameworkEvent(framework, OSGI_FRAMEWORK_EVENT_STARTED, framework->bundle, 0));
+	status = CELIX_DO_IF(status, fw_fireFrameworkEvent(framework, OSGI_FRAMEWORK_EVENT_STARTED, framework->bundle, framework->bundleId));
 
 	if (status != CELIX_SUCCESS) {
        status = CELIX_BUNDLE_EXCEPTION;
@@ -691,16 +762,15 @@ celix_status_t fw_installBundle(framework_pt framework, bundle_pt * bundle, cons
 
 celix_status_t fw_installBundle2(framework_pt framework, bundle_pt * bundle, long id, const char * location, const char *inputFile, bundle_archive_pt archive) {
     celix_status_t status = CELIX_SUCCESS;
-//    bundle_archive_pt bundle_archive = NULL;
     bundle_state_e state = OSGI_FRAMEWORK_BUNDLE_UNKNOWN;
-  	bool locked;
 
-  	status = CELIX_DO_IF(status, framework_acquireInstallLock(framework, location));
+    //increase use count of framework bundle to prevent a stop. TODO is concurrent installing of bundles supported? -> else need another lock
+    fw_bundleEntry_increaseUseCount(framework, framework->bundleId);
+
   	status = CELIX_DO_IF(status, bundle_getState(framework->bundle, &state));
   	if (status == CELIX_SUCCESS) {
         if (state == OSGI_FRAMEWORK_BUNDLE_STOPPING || state == OSGI_FRAMEWORK_BUNDLE_UNINSTALLED) {
             fw_log(framework->logger, OSGI_FRAMEWORK_LOG_INFO,  "The framework is being shutdown");
-            status = CELIX_DO_IF(status, framework_releaseInstallLock(framework, location));
             status = CELIX_FRAMEWORK_SHUTDOWN;
         }
   	}
@@ -708,7 +778,7 @@ celix_status_t fw_installBundle2(framework_pt framework, bundle_pt * bundle, lon
     if (status == CELIX_SUCCESS) {
         *bundle = framework_getBundle(framework, location);
         if (*bundle != NULL) {
-            framework_releaseInstallLock(framework, location);
+            fw_bundleEntry_decreaseUseCount(framework, framework->bundleId);
             return CELIX_SUCCESS;
         }
 
@@ -726,27 +796,24 @@ celix_status_t fw_installBundle2(framework_pt framework, bundle_pt * bundle, lon
         }
 
         if (status == CELIX_SUCCESS) {
-            locked = framework_acquireGlobalLock(framework);
-            if (!locked) {
-                status = CELIX_BUNDLE_EXCEPTION;
-            } else {
-                status = CELIX_DO_IF(status, bundle_createFromArchive(bundle, framework, archive));
+            status = bundle_createFromArchive(bundle, framework, archive);
+        }
 
-                framework_releaseGlobalLock(framework);
-                if (status == CELIX_SUCCESS) {
-                    celixThreadMutex_lock(&framework->installedBundleMapLock);
-                    hashMap_put(framework->installedBundleMap, strdup(location), *bundle);
-                    celixThreadMutex_unlock(&framework->installedBundleMapLock);
+        if (status == CELIX_SUCCESS) {
+            long bndId = -1L;
+            bundle_getBundleId(*bundle, &bndId);
+            celix_framework_bundle_entry_t *entry = fw_bundleEntry_create(*bundle);
+            celixThreadMutex_lock(&framework->installedBundles.mutex);
+            celix_arrayList_add(framework->installedBundles.entries, entry);
+            celixThreadMutex_unlock(&framework->installedBundles.mutex);
 
-                } else {
-                    status = CELIX_BUNDLE_EXCEPTION;
-                    status = CELIX_DO_IF(status, bundleArchive_closeAndDelete(archive));
-                }
-            }
+        } else {
+            status = CELIX_BUNDLE_EXCEPTION;
+            status = CELIX_DO_IF(status, bundleArchive_closeAndDelete(archive));
         }
     }
 
-    framework_releaseInstallLock(framework, location);
+    fw_bundleEntry_decreaseUseCount(framework, framework->bundleId);
 
     if (status != CELIX_SUCCESS) {
     	fw_logCode(framework->logger, OSGI_FRAMEWORK_LOG_ERROR, status, "Could not install bundle");
@@ -798,7 +865,9 @@ celix_status_t fw_startBundle(framework_pt framework, bundle_pt bundle, int opti
 	char *error = NULL;
 	const char *name = NULL;
 
-	status = CELIX_DO_IF(status, framework_acquireBundleLock(framework, bundle, OSGI_FRAMEWORK_BUNDLE_INSTALLED|OSGI_FRAMEWORK_BUNDLE_RESOLVED|OSGI_FRAMEWORK_BUNDLE_STARTING|OSGI_FRAMEWORK_BUNDLE_ACTIVE));
+	long bndId = celix_bundle_getId(bundle);
+    fw_bundleEntry_increaseUseCount(framework, bndId);
+
 	status = CELIX_DO_IF(status, bundle_getState(bundle, &state));
 
 	if (status == CELIX_SUCCESS) {
@@ -827,7 +896,6 @@ celix_status_t fw_startBundle(framework_pt framework, bundle_pt bundle, int opti
                 if (!module_isResolved(module)) {
                     wires = resolver_resolve(module);
                     if (wires == NULL) {
-                        framework_releaseBundleLock(framework, bundle);
                         return CELIX_BUNDLE_EXCEPTION;
                     }
                     framework_markResolvedModules(framework, wires);
@@ -901,7 +969,7 @@ celix_status_t fw_startBundle(framework_pt framework, bundle_pt bundle, int opti
         }
 	}
 
-	framework_releaseBundleLock(framework, bundle);
+    fw_bundleEntry_decreaseUseCount(framework, bndId);
 
 	if (status != CELIX_SUCCESS) {
 	    module_pt module = NULL;
@@ -930,7 +998,9 @@ celix_status_t framework_updateBundle(framework_pt framework, bundle_pt bundle,
 	bundle_archive_pt archive = NULL;
 	char *error = NULL;
 
-	status = CELIX_DO_IF(status, framework_acquireBundleLock(framework, bundle, OSGI_FRAMEWORK_BUNDLE_INSTALLED|OSGI_FRAMEWORK_BUNDLE_RESOLVED|OSGI_FRAMEWORK_BUNDLE_ACTIVE));
+    long bndId = celix_bundle_getId(bundle);
+    fw_bundleEntry_increaseUseCount(framework, bndId);
+
 	status = CELIX_DO_IF(status, bundle_getState(bundle, &oldState));
 	if (status == CELIX_SUCCESS) {
         if (oldState == OSGI_FRAMEWORK_BUNDLE_ACTIVE) {
@@ -940,16 +1010,7 @@ celix_status_t framework_updateBundle(framework_pt framework, bundle_pt bundle,
 	status = CELIX_DO_IF(status, bundle_getArchive(bundle, &archive));
 	status = CELIX_DO_IF(status, bundleArchive_getLocation(archive, &location));
 
-	if (status == CELIX_SUCCESS) {
-	    bool locked = framework_acquireGlobalLock(framework);
-	    if (!locked) {
-	        status = CELIX_BUNDLE_EXCEPTION;
-	        error = "Unable to acquire the global lock to update the bundle";
-	    }
-	}
-
 	status = CELIX_DO_IF(status, bundle_revise(bundle, location, inputFile));
-	status = CELIX_DO_IF(status, framework_releaseGlobalLock(framework));
 
 	status = CELIX_DO_IF(status, bundleArchive_setLastModified(archive, time(NULL)));
 	status = CELIX_DO_IF(status, framework_setBundleStateAndNotify(framework, bundle, OSGI_FRAMEWORK_BUNDLE_INSTALLED));
@@ -978,7 +1039,8 @@ celix_status_t framework_updateBundle(framework_pt framework, bundle_pt bundle,
 	    }
 	}
 
-	framework_releaseBundleLock(framework, bundle);
+
+    fw_bundleEntry_decreaseUseCount(framework, bndId);
 
 	if (status != CELIX_SUCCESS) {
 	    module_pt module = NULL;
@@ -1006,7 +1068,9 @@ celix_status_t fw_stopBundle(framework_pt framework, bundle_pt bundle, bool reco
     long id = 0;
     char *error = NULL;
 
-	status = CELIX_DO_IF(status, framework_acquireBundleLock(framework, bundle, OSGI_FRAMEWORK_BUNDLE_INSTALLED|OSGI_FRAMEWORK_BUNDLE_RESOLVED|OSGI_FRAMEWORK_BUNDLE_STARTING|OSGI_FRAMEWORK_BUNDLE_ACTIVE));
+    long bndId = celix_bundle_getId(bundle);
+    fw_bundleEntry_increaseUseCount(framework, bndId);
+
 
 	if (record) {
 	    status = CELIX_DO_IF(status, bundle_setPersistentStateInactive(bundle));
@@ -1094,7 +1158,9 @@ celix_status_t fw_stopBundle(framework_pt framework, bundle_pt bundle, bool reco
 	    }
 	}
 
-	framework_releaseBundleLock(framework, bundle);
+
+    fw_bundleEntry_decreaseUseCount(framework, bndId);
+
 
 	if (status != CELIX_SUCCESS) {
 	    module_pt module = NULL;
@@ -1118,56 +1184,38 @@ celix_status_t fw_stopBundle(framework_pt framework, bundle_pt bundle, bool reco
 }
 
 celix_status_t fw_uninstallBundle(framework_pt framework, bundle_pt bundle) {
-    celix_status_t status = CELIX_SUCCESS;
-    bool locked;
-    bundle_archive_pt archive = NULL;
-    const char * location = NULL;
-    bundle_pt target = NULL;
-    char *error = NULL;
+    celix_status_t status;
 
-    status = CELIX_DO_IF(status, framework_acquireBundleLock(framework, bundle, OSGI_FRAMEWORK_BUNDLE_INSTALLED|OSGI_FRAMEWORK_BUNDLE_RESOLVED|OSGI_FRAMEWORK_BUNDLE_STARTING|OSGI_FRAMEWORK_BUNDLE_ACTIVE|OSGI_FRAMEWORK_BUNDLE_STOPPING));
-    status = CELIX_DO_IF(status, fw_stopBundle(framework, bundle, true));
+    celix_framework_bundle_entry_t *entry = NULL;
+    long bndId = -1L;
+    status = bundle_getBundleId(bundle, &bndId);
     if (status == CELIX_SUCCESS) {
-        locked = framework_acquireGlobalLock(framework);
-        if (!locked) {
-            status = CELIX_ILLEGAL_STATE;
-            error = "Unable to acquire the global lock to uninstall the bundle";
-        }
-    }
-
-    status = CELIX_DO_IF(status, bundle_getArchive(bundle, &archive));
-    status = CELIX_DO_IF(status, bundleArchive_getLocation(archive, &location));
-    if (status == CELIX_SUCCESS) {
-
-        celixThreadMutex_lock(&framework->installedBundleMapLock);
-
-        hash_map_entry_pt entry = hashMap_getEntry(framework->installedBundleMap, location);
-        char* entryLocation = hashMapEntry_getKey(entry);
-
-        target = (bundle_pt) hashMap_remove(framework->installedBundleMap, location);
-
-        free(entryLocation);
-        if (target != NULL) {
-            status = CELIX_DO_IF(status, bundle_setPersistentStateUninstalled(target));
-            // fw_rememberUninstalledBundle(framework, target);
+        celixThreadMutex_lock(&framework->installedBundles.mutex);
+        int size = celix_arrayList_size(framework->installedBundles.entries);
+        for (int i = 0; i < size; ++i) {
+            celix_framework_bundle_entry_t *visit = celix_arrayList_get(framework->installedBundles.entries, i);
+            if (visit != NULL && visit->bndId == bndId) {
+                entry = visit;
+                break;
+            }
         }
-        celixThreadMutex_unlock(&framework->installedBundleMapLock);
-
+        celixThreadMutex_unlock(&framework->installedBundles.mutex);
+        status = entry != NULL ? CELIX_SUCCESS : CELIX_ILLEGAL_ARGUMENT;
     }
 
-    framework_releaseGlobalLock(framework);
-
-    if (status == CELIX_SUCCESS) {
-        if (target == NULL) {
-            fw_log(framework->logger, OSGI_FRAMEWORK_LOG_ERROR, "Could not remove bundle from installed map");
-        }
+    if (entry != NULL) {
+        //NOTE wait outside installedBundles.mutex
+        fw_bundleEntry_destroy(entry, true); //wait till use count is 0 -> e.g. not used
     }
 
-    status = CELIX_DO_IF(status, framework_setBundleStateAndNotify(framework, bundle, OSGI_FRAMEWORK_BUNDLE_INSTALLED));
+    status = CELIX_DO_IF(status, fw_stopBundle(framework, bundle, true));
 
     // TODO Unload all libraries for transition to unresolved
-    bundle_revision_pt revision = NULL;
+    bundle_archive_t *archive = NULL;
+    bundle_revision_t *revision = NULL;
 	array_list_pt handles = NULL;
+	status = CELIX_DO_IF(status, bundle_getArchive(bundle, &archive));
+    status = CELIX_DO_IF(status, bundleArchive_setPersistentState(archive, OSGI_FRAMEWORK_BUNDLE_UNINSTALLED)); //set state to uninstalled, so that next framework start will not start bundle.
 	status = CELIX_DO_IF(status, bundleArchive_getCurrentRevision(archive, &revision));
 	status = CELIX_DO_IF(status, bundleRevision_getHandles(revision, &handles));
 	if(handles != NULL){
@@ -1182,23 +1230,16 @@ celix_status_t fw_uninstallBundle(framework_pt framework, bundle_pt bundle) {
     status = CELIX_DO_IF(status, framework_setBundleStateAndNotify(framework, bundle, OSGI_FRAMEWORK_BUNDLE_UNINSTALLED));
     status = CELIX_DO_IF(status, bundleArchive_setLastModified(archive, time(NULL)));
 
-    framework_releaseBundleLock(framework, bundle);
-
     status = CELIX_DO_IF(status, fw_fireBundleEvent(framework, OSGI_FRAMEWORK_BUNDLE_EVENT_UNINSTALLED, bundle));
 
     if (status == CELIX_SUCCESS) {
-        locked = framework_acquireGlobalLock(framework);
-        if (locked) {
-            bundle_pt bundles[] = { bundle };
-            celix_status_t refreshStatus = fw_refreshBundles(framework, bundles, 1);
-            if (refreshStatus != CELIX_SUCCESS) {
-                printf("Could not refresh bundle");
-            } else {
-                bundleArchive_destroy(archive);
-                status = CELIX_DO_IF(status, bundle_destroy(bundle));
-            }
-
-            status = CELIX_DO_IF(status, framework_releaseGlobalLock(framework));
+        bundle_pt bundles[] = { bundle };
+        celix_status_t refreshStatus = fw_refreshBundles(framework, bundles, 1);
+        if (refreshStatus != CELIX_SUCCESS) {
+            printf("Could not refresh bundle");
+        } else {
+            bundleArchive_destroy(archive);
+            status = CELIX_DO_IF(status, bundle_destroy(bundle));
         }
     }
 
@@ -1211,7 +1252,7 @@ celix_status_t fw_uninstallBundle(framework_pt framework, bundle_pt bundle) {
 //        module_getSymbolicName(module, &symbolicName);
 //        bundle_getBundleId(bundle, &id);
 
-        framework_logIfError(framework->logger, status, error, "Cannot uninstall bundle");
+        framework_logIfError(framework->logger, status, "", "Cannot uninstall bundle");
     }
 
     return status;
@@ -1220,65 +1261,57 @@ celix_status_t fw_uninstallBundle(framework_pt framework, bundle_pt bundle) {
 celix_status_t fw_refreshBundles(framework_pt framework, bundle_pt bundles[], int size) {
     celix_status_t status = CELIX_SUCCESS;
 
-    bool locked = framework_acquireGlobalLock(framework);
-    if (!locked) {
-        framework_releaseGlobalLock(framework);
-        status = CELIX_ILLEGAL_STATE;
-    } else {
-		hash_map_values_pt values;
-        bundle_pt *newTargets;
-        unsigned int nrofvalues;
-		bool restart = false;
-        hash_map_pt map = hashMap_create(NULL, NULL, NULL, NULL);
-        int targetIdx = 0;
-        for (targetIdx = 0; targetIdx < size; targetIdx++) {
-            bundle_pt bundle = bundles[targetIdx];
-            hashMap_put(map, bundle, bundle);
-            fw_populateDependentGraph(framework, bundle, &map);
-        }
-        values = hashMapValues_create(map);
-        hashMapValues_toArray(values, (void ***) &newTargets, &nrofvalues);
-        hashMapValues_destroy(values);
-
-        hashMap_destroy(map, false, false);
-
-        if (newTargets != NULL) {
-            int i = 0;
-			struct fw_refreshHelper * helpers;
-            for (i = 0; i < nrofvalues && !restart; i++) {
-                bundle_pt bundle = (bundle_pt) newTargets[i];
-                if (framework->bundle == bundle) {
-                    restart = true;
-                }
-            }
-
-            helpers = (struct fw_refreshHelper * )malloc(nrofvalues * sizeof(struct fw_refreshHelper));
-            for (i = 0; i < nrofvalues && !restart; i++) {
-                bundle_pt bundle = (bundle_pt) newTargets[i];
-                helpers[i].framework = framework;
-                helpers[i].bundle = bundle;
-                helpers[i].oldState = OSGI_FRAMEWORK_BUNDLE_INSTALLED;
+    hash_map_values_pt values;
+    bundle_pt *newTargets;
+    unsigned int nrofvalues;
+    bool restart = false;
+    hash_map_pt map = hashMap_create(NULL, NULL, NULL, NULL);
+    int targetIdx = 0;
+    for (targetIdx = 0; targetIdx < size; targetIdx++) {
+        bundle_pt bundle = bundles[targetIdx];
+        hashMap_put(map, bundle, bundle);
+        fw_populateDependentGraph(framework, bundle, &map);
+    }
+    values = hashMapValues_create(map);
+    hashMapValues_toArray(values, (void ***) &newTargets, &nrofvalues);
+    hashMapValues_destroy(values);
+
+    hashMap_destroy(map, false, false);
+
+    if (newTargets != NULL) {
+        int i = 0;
+        struct fw_refreshHelper * helpers;
+        for (i = 0; i < nrofvalues && !restart; i++) {
+            bundle_pt bundle = (bundle_pt) newTargets[i];
+            if (framework->bundle == bundle) {
+                restart = true;
             }
+        }
 
-            for (i = 0; i < nrofvalues; i++) {
-                struct fw_refreshHelper helper = helpers[i];
-                fw_refreshHelper_stop(&helper);
-                fw_refreshHelper_refreshOrRemove(&helper);
-            }
+        helpers = (struct fw_refreshHelper * )malloc(nrofvalues * sizeof(struct fw_refreshHelper));
+        for (i = 0; i < nrofvalues && !restart; i++) {
+            bundle_pt bundle = (bundle_pt) newTargets[i];
+            helpers[i].framework = framework;
+            helpers[i].bundle = bundle;
+            helpers[i].oldState = OSGI_FRAMEWORK_BUNDLE_INSTALLED;
+        }
 
-            for (i = 0; i < nrofvalues; i++) {
-                struct fw_refreshHelper helper = helpers[i];
-                fw_refreshHelper_restart(&helper);
-            }
+        for (i = 0; i < nrofvalues; i++) {
+            struct fw_refreshHelper helper = helpers[i];
+            fw_refreshHelper_stop(&helper);
+            fw_refreshHelper_refreshOrRemove(&helper);
+        }
 
-            if (restart) {
-                bundle_update(framework->bundle, NULL);
-            }
-			free(helpers);
-			free(newTargets);
+        for (i = 0; i < nrofvalues; i++) {
+            struct fw_refreshHelper helper = helpers[i];
+            fw_refreshHelper_restart(&helper);
         }
 
-        framework_releaseGlobalLock(framework);
+        if (restart) {
+            bundle_update(framework->bundle, NULL);
+        }
+        free(helpers);
+        free(newTargets);
     }
 
     framework_logIfError(framework->logger, status, NULL, "Cannot refresh bundles");
@@ -1290,24 +1323,24 @@ celix_status_t fw_refreshBundle(framework_pt framework, bundle_pt bundle) {
     celix_status_t status = CELIX_SUCCESS;
     bundle_state_e state;
 
-    status = framework_acquireBundleLock(framework, bundle, OSGI_FRAMEWORK_BUNDLE_INSTALLED | OSGI_FRAMEWORK_BUNDLE_RESOLVED);
-    if (status != CELIX_SUCCESS) {
-        printf("Cannot refresh bundle");
-        framework_releaseBundleLock(framework, bundle);
-    } else {
-    	bool fire;
-		bundle_getState(bundle, &state);
-        fire = (state != OSGI_FRAMEWORK_BUNDLE_INSTALLED);
-        bundle_refresh(bundle);
+    long bndId = celix_bundle_getId(bundle);
+    fw_bundleEntry_increaseUseCount(framework, bndId);
+
 
-        if (fire) {
-            framework_setBundleStateAndNotify(framework, bundle, OSGI_FRAMEWORK_BUNDLE_INSTALLED);
-            fw_fireBundleEvent(framework, OSGI_FRAMEWORK_BUNDLE_EVENT_UNRESOLVED, bundle);
-        }
 
-        framework_releaseBundleLock(framework, bundle);
+    bool fire;
+    bundle_getState(bundle, &state);
+    fire = (state != OSGI_FRAMEWORK_BUNDLE_INSTALLED);
+    bundle_refresh(bundle);
+
+    if (fire) {
+        framework_setBundleStateAndNotify(framework, bundle, OSGI_FRAMEWORK_BUNDLE_INSTALLED);
+        fw_fireBundleEvent(framework, OSGI_FRAMEWORK_BUNDLE_EVENT_UNRESOLVED, bundle);
     }
 
+
+    fw_bundleEntry_decreaseUseCount(framework, bndId);
+
     framework_logIfError(framework->logger, status, NULL, "Cannot refresh bundle");
 
     return status;
@@ -1407,13 +1440,11 @@ celix_status_t fw_registerService(framework_pt framework, service_registration_p
 	    error = "ServiceName and SvcObj cannot be null";
 	}
 
-	status = CELIX_DO_IF(status, framework_acquireBundleLock(framework, bundle, OSGI_FRAMEWORK_BUNDLE_STARTING|OSGI_FRAMEWORK_BUNDLE_ACTIVE));
+	long bndId = celix_bundle_getId(bundle);
+    fw_bundleEntry_increaseUseCount(framework, bndId);
+
+
 	status = CELIX_DO_IF(status, serviceRegistry_registerService(framework->registry, bundle, serviceName, svcObj, properties, registration));
-	bool res = framework_releaseBundleLock(framework, bundle);
-	if (!res) {
-	    status = CELIX_ILLEGAL_STATE;
-	    error = "Could not release bundle lock";
-	}
 
 	if (status == CELIX_SUCCESS) {
 	    // If this is a listener hook, invoke the callback with all current listeners
@@ -1479,6 +1510,10 @@ celix_status_t fw_registerService(framework_pt framework, service_registration_p
         }
 	}
 
+
+    fw_bundleEntry_decreaseUseCount(framework, bndId);
+
+
     framework_logIfError(framework->logger, status, error, "Cannot register service: %s", serviceName);
 
 	return status;
@@ -1492,12 +1527,14 @@ celix_status_t fw_registerServiceFactory(framework_pt framework, service_registr
         error = "Service name and factory cannot be null";
     }
 
-	status = CELIX_DO_IF(status, framework_acquireBundleLock(framework, bundle, OSGI_FRAMEWORK_BUNDLE_STARTING|OSGI_FRAMEWORK_BUNDLE_ACTIVE));
+    long bndId = celix_bundle_getId(bundle);
+    fw_bundleEntry_increaseUseCount(framework, bndId);
+
+
 	status = CELIX_DO_IF(status, serviceRegistry_registerServiceFactory(framework->registry, bundle, serviceName, factory, properties, registration));
-    if (!framework_releaseBundleLock(framework, bundle)) {
-        status = CELIX_ILLEGAL_STATE;
-        error = "Could not release bundle lock";
-    }
+
+
+    fw_bundleEntry_decreaseUseCount(framework, bndId);
 
     framework_logIfError(framework->logger, status, error, "Cannot register service factory: %s", serviceName);
 
@@ -1954,7 +1991,10 @@ celix_status_t framework_markBundleResolved(framework_pt framework, module_pt mo
 	char *error = NULL;
 
 	if (bundle != NULL) {
-		framework_acquireBundleLock(framework, bundle, OSGI_FRAMEWORK_BUNDLE_INSTALLED|OSGI_FRAMEWORK_BUNDLE_RESOLVED|OSGI_FRAMEWORK_BUNDLE_ACTIVE);
+
+	    long bndId = celix_bundle_getId(bundle);
+        fw_bundleEntry_increaseUseCount(framework, bndId);
+
 		bundle_getState(bundle, &state);
 		if (state != OSGI_FRAMEWORK_BUNDLE_INSTALLED) {
 			printf("Trying to resolve a resolved bundle");
@@ -1984,355 +2024,134 @@ celix_status_t framework_markBundleResolved(framework_pt framework, module_pt mo
             }
         }
 
-		framework_releaseBundleLock(framework, bundle);
+
+        fw_bundleEntry_decreaseUseCount(framework, bndId);
 	}
 
 	return CELIX_SUCCESS;
 }
 
 array_list_pt framework_getBundles(framework_pt framework) {
+    //FIXME Note that this does not increase the use count of the bundle, which can lead to race conditions.
+    //promote to use the celix_bundleContext_useBundle(s) functions and deprecated this one
 	array_list_pt bundles = NULL;
-	hash_map_iterator_pt iterator;
 	arrayList_create(&bundles);
 
-	celixThreadMutex_lock(&framework->installedBundleMapLock);
-
-	iterator = hashMapIterator_create(framework->installedBundleMap);
-	while (hashMapIterator_hasNext(iterator)) {
-		bundle_pt bundle = (bundle_pt) hashMapIterator_nextValue(iterator);
-		arrayList_add(bundles, bundle);
+	celixThreadMutex_lock(&framework->installedBundles.mutex);
+	int size = celix_arrayList_size(framework->installedBundles.entries);
+	for (int i = 0; i < size; ++i) {
+        celix_framework_bundle_entry_t *entry = celix_arrayList_get(framework->installedBundles.entries, i);
+        celix_arrayList_add(bundles, entry->bnd);
 	}
-	hashMapIterator_destroy(iterator);
-
-	celixThreadMutex_unlock(&framework->installedBundleMapLock);
+	celixThreadMutex_unlock(&framework->installedBundles.mutex);
 
 	return bundles;
 }
 
 bundle_pt framework_getBundle(framework_pt framework, const char* location) {
-	celixThreadMutex_lock(&framework->installedBundleMapLock);
-	bundle_pt bundle = (bundle_pt) hashMap_get(framework->installedBundleMap, location);
-	celixThreadMutex_unlock(&framework->installedBundleMapLock);
-	return bundle;
-}
+    //FIXME Note that this does not increase the use count of the bundle, which can lead to race conditions.
+    //promote to use the celix_bundleContext_useBundle(s) functions and deprecated this one
+	bundle_t *bnd = NULL;
+
+    celixThreadMutex_lock(&framework->installedBundles.mutex);
+    int size = celix_arrayList_size(framework->installedBundles.entries);
+    for (int i = 0; i < size; ++i) {
+        celix_framework_bundle_entry_t *entry = celix_arrayList_get(framework->installedBundles.entries, i);
+        const char *loc = NULL;
+        bundle_getBundleLocation(entry->bnd, &loc);
+        if (loc != NULL && location != NULL && strncmp(loc, location, strlen(loc)) == 0) {
+            bnd = entry->bnd;
+            break;
+        }
+    }
+    celixThreadMutex_unlock(&framework->installedBundles.mutex);
 
-bundle_pt framework_getBundleById(framework_pt framework, long id) {
-	celixThreadMutex_lock(&framework->installedBundleMapLock);
-	hash_map_iterator_pt iter = hashMapIterator_create(framework->installedBundleMap);
-	bundle_pt bundle = NULL;
-	while (hashMapIterator_hasNext(iter)) {
-		bundle_pt b = (bundle_pt) hashMapIterator_nextValue(iter);
-		bundle_archive_pt archive = NULL;
-		long bid;
-		bundle_getArchive(b, &archive);
-		bundleArchive_getId(archive, &bid);
-		if (bid == id) {
-			bundle = b;
-			break;
-		}
-	}
-	hashMapIterator_destroy(iter);
-	celixThreadMutex_unlock(&framework->installedBundleMapLock);
 
-	return bundle;
+	return bnd;
 }
 
-celix_status_t framework_acquireInstallLock(framework_pt framework, const char * location) {
-    celixThreadMutex_lock(&framework->installRequestLock);
-
-	while (hashMap_get(framework->installRequestMap, location) != NULL) {
-	    celixThreadCondition_wait(&framework->condition, &framework->installRequestLock);
+bundle_pt framework_getBundleById(framework_pt framework, long id) {
+    bundle_t *bnd = NULL;
+
+	celixThreadMutex_lock(&framework->installedBundles.mutex);
+	int size = celix_arrayList_size(framework->installedBundles.entries);
+	for (int i = 0; i < size; ++i) {
+        celix_framework_bundle_entry_t *entry = celix_arrayList_get(framework->installedBundles.entries, i);
+        if (entry != NULL && entry->bndId == id) {
+            bnd = entry->bnd;
+            break;
+        }
 	}
-	hashMap_put(framework->installRequestMap, (char*)location, (char*)location);
-
-	celixThreadMutex_unlock(&framework->installRequestLock);
+	celixThreadMutex_unlock(&framework->installedBundles.mutex);
 
-	return CELIX_SUCCESS;
-}
-
-celix_status_t framework_releaseInstallLock(framework_pt framework, const char* location) {
-    celixThreadMutex_lock(&framework->installRequestLock);
-
-	hashMap_remove(framework->installRequestMap, location);
-	celixThreadCondition_broadcast(&framework->condition);
-
-	celixThreadMutex_unlock(&framework->installRequestLock);
-
-	return CELIX_SUCCESS;
+	return bnd;
 }
 
 celix_status_t framework_setBundleStateAndNotify(framework_pt framework, bundle_pt bundle, int state) {
 	int ret = CELIX_SUCCESS;
-
-	int err = celixThreadMutex_lock(&framework->bundleLock);
-	if (err != 0) {
-		fw_log(framework->logger, OSGI_FRAMEWORK_LOG_ERROR,  "Failed to lock");
-		return CELIX_BUNDLE_EXCEPTION;
-	}
-
 	bundle_setState(bundle, state);
-	err = celixThreadCondition_broadcast(&framework->condition);
-	if (err != 0) {
-		fw_log(framework->logger, OSGI_FRAMEWORK_LOG_ERROR,  "Failed to broadcast");
-		ret = CELIX_BUNDLE_EXCEPTION;
-	}
-
-	err = celixThreadMutex_unlock(&framework->bundleLock);
-	if (err != 0) {
-		fw_log(framework->logger, OSGI_FRAMEWORK_LOG_ERROR,  "Failed to unlock");
-		return CELIX_BUNDLE_EXCEPTION;
-	}
 	return ret;
 }
 
-celix_status_t framework_acquireBundleLock(framework_pt framework, bundle_pt bundle, int desiredStates) {
-	celix_status_t status = CELIX_SUCCESS;
-
-	bool locked;
-	celix_thread_t lockingThread = celix_thread_default;
-
-	int err = celixThreadMutex_lock(&framework->bundleLock);
-	if (err != CELIX_SUCCESS) {
-		fw_log(framework->logger, OSGI_FRAMEWORK_LOG_ERROR,  "Failed to lock");
-		status = CELIX_BUNDLE_EXCEPTION;
-	} else {
-		bool lockable = false;
-		bool isSelf = false;
-
-		bundle_isLockable(bundle, &lockable);
-		thread_equalsSelf(framework->globalLockThread, &isSelf);
-
-		while (!lockable
-				|| (( celixThread_initalized(framework->globalLockThread) == true)
-				&& !isSelf))
-		{
-			bundle_state_e state;
-			bundle_getState(bundle, &state);
-			if ((desiredStates & state) == 0) {
-				status = CELIX_ILLEGAL_STATE;
-				break;
-			}
-
-			bundle_getLockingThread(bundle, &lockingThread);
-			if (isSelf && (celixThread_initalized(lockingThread) == true)
-					&& arrayList_contains(framework->globalLockWaitersList, &lockingThread)) {
-				framework->interrupted = true;
-//				celixThreadCondition_signal_thread_np(&framework->condition, bundle_getLockingThread(bundle));
-				celixThreadCondition_signal(&framework->condition);
-			}
-
-            celixThreadCondition_wait(&framework->condition, &framework->bundleLock);
-
-			status = bundle_isLockable(bundle, &lockable);
-			if (status != CELIX_SUCCESS) {
-				break;
-			}
-	}
-
-		if (status == CELIX_SUCCESS) {
-			bundle_state_e state;
-			bundle_getState(bundle, &state);
-			if ((desiredStates & state) == 0) {
-				status = CELIX_ILLEGAL_STATE;
-			} else {
-				if (bundle_lock(bundle, &locked)) {
-					if (!locked) {
-						status = CELIX_ILLEGAL_STATE;
-					}
-				}
-			}
-		}
-		celixThreadMutex_unlock(&framework->bundleLock);
-	}
-
-	framework_logIfError(framework->logger, status, NULL, "Failed to get bundle lock");
-
-	return status;
-}
-
-bool framework_releaseBundleLock(framework_pt framework, bundle_pt bundle) {
-    bool unlocked;
-    celix_thread_t lockingThread = celix_thread_default;
-
-    celixThreadMutex_lock(&framework->bundleLock);
-
-    bundle_unlock(bundle, &unlocked);
-	if (!unlocked) {
-	    celixThreadMutex_unlock(&framework->bundleLock);
-		return false;
-	}
-	bundle_getLockingThread(bundle, &lockingThread);
-	if (celixThread_initalized(lockingThread) == false) {
-	    celixThreadCondition_broadcast(&framework->condition);
-	}
-
-	celixThreadMutex_unlock(&framework->bundleLock);
-
-	return true;
-}
-
-bool framework_acquireGlobalLock(framework_pt framework) {
-    bool interrupted = false;
-	bool isSelf = false;
-
-	celixThreadMutex_lock(&framework->bundleLock);
-
-	thread_equalsSelf(framework->globalLockThread, &isSelf);
-
-	while (!interrupted
-			&& (celixThread_initalized(framework->globalLockThread) == true)
-			&& (!isSelf)) {
-		celix_thread_t currentThread = celixThread_self();
-		arrayList_add(framework->globalLockWaitersList, &currentThread);
-		celixThreadCondition_broadcast(&framework->condition);
-
-		celixThreadCondition_wait(&framework->condition, &framework->bundleLock);
-		if (framework->interrupted) {
-			interrupted = true;
-			framework->interrupted = false;
-		}
-
-		arrayList_removeElement(framework->globalLockWaitersList, &currentThread);
-	}
-
-	if (!interrupted) {
-		framework->globalLockCount++;
-		framework->globalLockThread = celixThread_self();
-	}
-
-	celixThreadMutex_unlock(&framework->bundleLock);
-
-	return !interrupted;
-}
-
-celix_status_t framework_releaseGlobalLock(framework_pt framework) {
-	int status = CELIX_SUCCESS;
-	if (celixThreadMutex_lock(&framework->bundleLock) != 0) {
-		fw_log(framework->logger, OSGI_FRAMEWORK_LOG_ERROR,  "Error locking framework bundle lock");
-		return CELIX_FRAMEWORK_EXCEPTION;
-	}
-
-	if (celixThread_equals(framework->globalLockThread, celixThread_self())) {
-		framework->globalLockCount--;
-		if (framework->globalLockCount == 0) {
-			framework->globalLockThread = celix_thread_default;
- 			if (celixThreadCondition_broadcast(&framework->condition) != 0) {
-				fw_log(framework->logger, OSGI_FRAMEWORK_LOG_ERROR,  "Failed to broadcast global lock release.");
-				status = CELIX_FRAMEWORK_EXCEPTION;
-				// still need to unlock before returning
-			}
-		}
-	} else {
-		printf("The current thread does not own the global lock");
-	}
-
-	if (celixThreadMutex_unlock(&framework->bundleLock) != 0) {
-		fw_log(framework->logger, OSGI_FRAMEWORK_LOG_ERROR,  "Error unlocking framework bundle lock");
-		return CELIX_FRAMEWORK_EXCEPTION;
-	}
-
-	framework_logIfError(framework->logger, status, NULL, "Failed to release global lock");
-
-	return status;
-}
-
 celix_status_t framework_waitForStop(framework_pt framework) {
-	if (celixThreadMutex_lock(&framework->mutex) != 0) {
-		fw_log(framework->logger, OSGI_FRAMEWORK_LOG_ERROR, "Error locking the framework, shutdown gate not set.");
-		return CELIX_FRAMEWORK_EXCEPTION;
-	}
-	while (!framework->shutdown) {
-	    celix_status_t status = celixThreadCondition_wait(&framework->shutdownGate, &framework->mutex);
-		if (status != 0) {
-			fw_log(framework->logger, OSGI_FRAMEWORK_LOG_ERROR, "Error waiting for shutdown gate.");
-			return CELIX_FRAMEWORK_EXCEPTION;
-		}
-	}
-	if (celixThreadMutex_unlock(&framework->mutex) != 0) {
-		fw_log(framework->logger, OSGI_FRAMEWORK_LOG_ERROR, "Error unlocking the framework.");
-		return CELIX_FRAMEWORK_EXCEPTION;
-	}
-
-    celixThread_join(framework->shutdownThread, NULL);
+    celixThreadMutex_lock(&framework->shutdown.mutex);
+    while (!framework->shutdown.done) {
+        celixThreadCondition_wait(&framework->shutdown.cond, &framework->shutdown.mutex);
+    }
+    celixThreadMutex_unlock(&framework->shutdown.mutex);
 
 	fw_log(framework->logger, OSGI_FRAMEWORK_LOG_INFO, "FRAMEWORK: Successful shutdown");
 	return CELIX_SUCCESS;
 }
 
-static void *framework_shutdown(void *framework) {
+static void* framework_shutdown(void *framework) {
 	framework_pt fw = (framework_pt) framework;
-	int err;
 
 	fw_log(fw->logger, OSGI_FRAMEWORK_LOG_INFO, "FRAMEWORK: Shutdown");
-	celixThreadMutex_lock(&fw->installedBundleMapLock);
 
-	hash_map_iterator_pt iter = hashMapIterator_create(fw->installedBundleMap);
-	bundle_pt bundle = NULL;
-	while ((bundle = hashMapIterator_nextValue(iter)) != NULL) {
-        bundle_state_e state;
-        bundle_getState(bundle, &state);
-        if (state == OSGI_FRAMEWORK_BUNDLE_ACTIVE || state == OSGI_FRAMEWORK_BUNDLE_STARTING) {
-            celixThreadMutex_unlock(&fw->installedBundleMapLock);
-            fw_stopBundle(fw, bundle, 0);
-            celixThreadMutex_lock(&fw->installedBundleMapLock);
-            hashMapIterator_destroy(iter);
-            iter = hashMapIterator_create(fw->installedBundleMap);
+    //celix_framework_bundle_entry_t *fwEntry = NULL;
+	celix_array_list_t *removeEntries = celix_arrayList_create();
+	celixThreadMutex_lock(&fw->installedBundles.mutex);
+	int size = celix_arrayList_size(fw->installedBundles.entries);
+	for (int i = 0; i < size; ++i) {
+        celix_framework_bundle_entry_t *entry = celix_arrayList_get(fw->installedBundles.entries, i);
+        if (entry->bndId != 0) { //i.e. not framework bundle
+            celix_arrayList_add(fw->installedBundles.entries, entry);
         }
-	}
-    hashMapIterator_destroy(iter);
-
-    iter = hashMapIterator_create(fw->installedBundleMap);
-	bundle = NULL;
-	while ((bundle = hashMapIterator_nextValue(iter)) != NULL) {
-		bundle_close(bundle);
-	}
-	hashMapIterator_destroy(iter);
-	celixThreadMutex_unlock(&fw->installedBundleMapLock);
 
-    err = celixThreadMutex_lock(&fw->mutex);
-    if (err != 0) {
-        fw_log(fw->logger, OSGI_FRAMEWORK_LOG_ERROR,  "Error locking the framework, cannot exit clean.");
-        celixThread_exit(NULL);
-        return NULL;
-    }
-
-	if (celixThreadMutex_lock(&fw->dispatcherLock) != CELIX_SUCCESS) {
-		fw_log(fw->logger, OSGI_FRAMEWORK_LOG_ERROR, "Error locking the dispatcherThread.");
 	}
-	else {
-		fw->shutdown = true;
+	celix_arrayList_clear(fw->installedBundles.entries);
+    celixThreadMutex_unlock(&fw->installedBundles.mutex);
 
-		if (celixThreadCondition_broadcast(&fw->dispatcher)) {
-			fw_log(fw->logger, OSGI_FRAMEWORK_LOG_ERROR, "Error broadcasting .");
-		}
 
-		if (celixThreadMutex_unlock(&fw->dispatcherLock)) {
-			fw_log(fw->logger, OSGI_FRAMEWORK_LOG_ERROR, "Error unlocking the dispatcherThread.");
-		}
-
-		celixThread_join(fw->dispatcherThread, NULL);
-	}
+    size = celix_arrayList_size(removeEntries);
+    for (int i = size-1; i >= 0; --i) { //note loop in reverse order -> stop later installed bundle first
+        celix_framework_bundle_entry_t *entry = celix_arrayList_get(removeEntries, i);
 
+        //wait until entry use counts is 0
+        bundle_t *bnd = entry->bnd;
+        fw_bundleEntry_destroy(entry, true);
 
-	err = celixThreadCondition_broadcast(&fw->shutdownGate);
-	if (err != 0) {
-		fw_log(fw->logger, OSGI_FRAMEWORK_LOG_ERROR,  "Error waking the shutdown gate, cannot exit clean.");
-		err = celixThreadMutex_unlock(&fw->mutex);
-		if (err != 0) {
-			fw_log(fw->logger, OSGI_FRAMEWORK_LOG_ERROR,  "Error unlocking the framework, cannot exit clean.");
-		}
+        bundle_state_e state;
+        bundle_getState(bnd, &state);
+        if (state == OSGI_FRAMEWORK_BUNDLE_ACTIVE || state == OSGI_FRAMEWORK_BUNDLE_STARTING) {
+            fw_stopBundle(fw, bnd, 0);
+        }
+        bundle_getState(bnd, &state);
+        if (state == OSGI_FRAMEWORK_BUNDLE_ACTIVE || state == OSGI_FRAMEWORK_BUNDLE_STARTING) {
+            fw_stopBundle(fw, bnd, 0);
+        }
+        bundle_close(bnd);
+    }
 
-		celixThread_exit(NULL);
-		return NULL;
-	}
-	err = celixThreadMutex_unlock(&fw->mutex);
-	if (err != 0) {
-//		fw_log(fw->logger, OSGI_FRAMEWORK_LOG_ERROR,  "Error unlocking the framework, cannot exit clean.");
-	}
+    //ignore fwEntry ?? TODO check
 
-//	fw_log(fw->logger, OSGI_FRAMEWORK_LOG_INFO, "FRAMEWORK: Shutdown done\n");
-	celixThread_exit((void *) CELIX_SUCCESS);
+    celixThreadMutex_lock(&fw->shutdown.mutex);
+    fw->shutdown.done = true;
+    celixThreadCondition_broadcast(&fw->shutdown.cond);
+    celixThreadMutex_unlock(&fw->shutdown.mutex);
 
+    celixThread_exit(NULL);
 	return NULL;
 }
 
@@ -2400,16 +2219,11 @@ celix_status_t fw_fireBundleEvent(framework_pt framework, bundle_event_type_e ev
                 }
             }
 
-            if (celixThreadMutex_lock(&framework->dispatcherLock) != CELIX_SUCCESS) {
-                status = CELIX_FRAMEWORK_EXCEPTION;
-            } else {
-                arrayList_add(framework->requests, request);
-                celix_status_t bcast_status = celixThreadCondition_broadcast(&framework->dispatcher);
-                celix_status_t unlock_status = celixThreadMutex_unlock(&framework->dispatcherLock);
-                if (bcast_status!=0 || unlock_status!=0) {
-                    status = CELIX_FRAMEWORK_EXCEPTION;
-                }
-            }
+            celixThreadMutex_lock(&framework->dispatcher.mutex);
+            arrayList_add(framework->dispatcher.requests, request);
+            celixThreadCondition_broadcast(&framework->dispatcher.cond);
+            celixThreadMutex_unlock(&framework->dispatcher.mutex);
+
         }
     }
 
@@ -2466,16 +2280,10 @@ celix_status_t fw_fireFrameworkEvent(framework_pt framework, framework_event_typ
             request->error = message;
         }
 
-        if (celixThreadMutex_lock(&framework->dispatcherLock) != CELIX_SUCCESS) {
-            status = CELIX_FRAMEWORK_EXCEPTION;
-        } else {
-            arrayList_add(framework->requests, request);
-            celix_status_t bcast_status = celixThreadCondition_broadcast(&framework->dispatcher);
-            celix_status_t unlock_status = celixThreadMutex_unlock(&framework->dispatcherLock);
-            if (bcast_status!=0 || unlock_status!=0) {
-		status = CELIX_FRAMEWORK_EXCEPTION;
-            }
-        }
+        celixThreadMutex_lock(&framework->dispatcher.mutex);
+        arrayList_add(framework->dispatcher.requests, request);
+        celixThreadCondition_broadcast(&framework->dispatcher.cond);
+        celixThreadMutex_unlock(&framework->dispatcher.mutex);
     }
 
 	framework_logIfError(framework->logger, status, NULL, "Failed to fire framework event");
@@ -2486,90 +2294,72 @@ celix_status_t fw_fireFrameworkEvent(framework_pt framework, framework_event_typ
 static void *fw_eventDispatcher(void *fw) {
 	framework_pt framework = (framework_pt) fw;
 
-	while (true) {
-		int size;
-		celix_status_t status;
-
-		if (celixThreadMutex_lock(&framework->dispatcherLock) != 0) {
-			fw_log(framework->logger, OSGI_FRAMEWORK_LOG_ERROR,  "Error locking the dispatcher");
-			celixThread_exit(NULL);
-			return NULL;
-		}
-
-		size = arrayList_size(framework->requests);
-		while (size == 0 && !framework->shutdown) {
-			celixThreadCondition_wait(&framework->dispatcher, &framework->dispatcherLock);
-			// Ignore status and just keep waiting
-			size = arrayList_size(framework->requests);
-		}
-
-		if (size == 0 && framework->shutdown) {
-		    celixThreadMutex_unlock(&framework->dispatcherLock);
-			celixThread_exit(NULL);
-			return NULL;
-		}
+	celixThreadMutex_lock(&framework->dispatcher.mutex);
+	bool active = framework->dispatcher.active;
+    celixThreadMutex_unlock(&framework->dispatcher.mutex);
 
-		request_pt request = (request_pt) arrayList_remove(framework->requests, 0);
+    celix_array_list_t *localRequests = celix_arrayList_create();
 
-		if ((status = celixThreadMutex_unlock(&framework->dispatcherLock)) != 0) {
-			fw_log(framework->logger, OSGI_FRAMEWORK_LOG_ERROR,  "Error unlocking the dispatcher.");
-			celixThread_exit(NULL);
-			return NULL;
-		}
-
-        if (celixThreadMutex_lock(&framework->bundleListenerLock) != CELIX_SUCCESS) {
-            status = CELIX_FRAMEWORK_EXCEPTION;
-        } else if (celixThreadMutex_lock(&framework->bundleLock) != CELIX_SUCCESS) {
-            celixThreadMutex_unlock(&framework->bundleListenerLock);
-            status = CELIX_FRAMEWORK_EXCEPTION;
-        } else {
-            int i;
+	while (active) {
+        celixThreadMutex_lock(&framework->dispatcher.mutex);
+        if (celix_arrayList_size(framework->dispatcher.requests) == 0) {
+            celixThreadCondition_wait(&framework->dispatcher.cond, &framework->dispatcher.mutex);
+        }
+        for (int i = 0; i < celix_arrayList_size(framework->dispatcher.requests); ++i) {
+            void *r = celix_arrayList_get(framework->dispatcher.requests, i);
+            celix_arrayList_add(localRequests, r);
+        }
+		celix_arrayList_clear(framework->dispatcher.requests);
+        celixThreadMutex_unlock(&framework->dispatcher.mutex);
+
+        //FIXME strange locking  of bundleListenerLock and frameworkListenerLock inside a loop.
+        //Seems like a request depends on bundle listeners or framework listeners -> this should be protected with
+        //a use count!!
+		for (int i = 0; i < celix_arrayList_size(localRequests); ++i) {
+		    request_pt request = celix_arrayList_get(localRequests, i);
             int size = arrayList_size(request->listeners);
-            for (i = 0; i < size; i++) {
+            for (int k = 0; k < size; k++) {
                 if (request->type == BUNDLE_EVENT_TYPE) {
-                    fw_bundle_listener_pt listener = (fw_bundle_listener_pt) arrayList_get(request->listeners, i);
-                    bundle_event_pt event = (bundle_event_pt) calloc(1, sizeof(*event));
-                    event->bundleId = request->bundleId;
-                    event->bundleSymbolicName = strdup(request->bundleSymbolicName);
-                    event->type = request->eventType;
-
-                    fw_invokeBundleListener(framework, listener->listener, event, listener->bundle);
-
-                    free(event->bundleSymbolicName);
-                    free(event);
+                    celixThreadMutex_lock(&framework->bundleListenerLock);
+                    fw_bundle_listener_pt listener = (fw_bundle_listener_pt) arrayList_get(request->listeners, k);
+                    bundle_event_t event;
+                    memset(&event, 0, sizeof(event));
+                    event.bundleId = request->bundleId;
+                    event.bundleSymbolicName = request->bundleSymbolicName;
+                    event.type = request->eventType;
+
+                    fw_invokeBundleListener(framework, listener->listener, &event, listener->bundle);
+                    celixThreadMutex_unlock(&framework->bundleListenerLock);
                 } else if (request->type == FRAMEWORK_EVENT_TYPE) {
                     celixThreadMutex_lock(&framework->frameworkListenersLock);
-                    fw_framework_listener_pt listener = (fw_framework_listener_pt) arrayList_get(request->listeners, i);
-                    framework_event_pt event = (framework_event_pt) calloc(1, sizeof(*event));
-                    event->bundleId = request->bundleId;
-                    event->bundleSymbolicName = strdup(request->bundleSymbolicName);
-                    event->type = request->eventType;
-                    event->error = request->error;
-                    event->errorCode = request->errorCode;
-
-                    fw_invokeFrameworkListener(framework, listener->listener, event, listener->bundle);
+                    fw_framework_listener_pt listener = (fw_framework_listener_pt) arrayList_get(request->listeners, k);
+                    framework_event_t event;
+                    memset(&event, 0, sizeof(event));
+                    event.bundleId = request->bundleId;
+                    event.bundleSymbolicName = request->bundleSymbolicName;
+                    event.type = request->eventType;
+                    event.error = request->error;
+                    event.errorCode = request->errorCode;
+
+                    fw_invokeFrameworkListener(framework, listener->listener, &event, listener->bundle);
                     celixThreadMutex_unlock(&framework->frameworkListenersLock);
-                    free(event->bundleSymbolicName);
-                    free(event);
                 }
             }
-
-            if (celixThreadMutex_unlock(&framework->bundleLock)) {
-                status = CELIX_FRAMEWORK_EXCEPTION;
-            }
-
-            if (celixThreadMutex_unlock(&framework->bundleListenerLock)) {
-                status = CELIX_FRAMEWORK_EXCEPTION;
-            }
-
             free(request->bundleSymbolicName);
+            //NOTE next 2 free calls not needed? why it is a char* not a const char*
+            //free(request->filter);
+            //free(request->error);
             free(request);
-        }
+		}
+		celix_arrayList_clear(localRequests);
 
+        celixThreadMutex_lock(&framework->dispatcher.mutex);
+        active = framework->dispatcher.active;
+        celixThreadMutex_unlock(&framework->dispatcher.mutex);
     }
 
+    celix_arrayList_destroy(localRequests);
 	celixThread_exit(NULL);
-
 	return NULL;
 
 }
@@ -2608,10 +2398,14 @@ static celix_status_t frameworkActivator_stop(void * userData, bundle_context_t
 	if (bundleContext_getFramework(context, &framework) == CELIX_SUCCESS) {
 
 	    fw_log(framework->logger, OSGI_FRAMEWORK_LOG_INFO, "FRAMEWORK: Start shutdownthread");
-	    if (celixThread_create(&framework->shutdownThread, NULL, &framework_shutdown, framework) != CELIX_SUCCESS) {
-            fw_log(framework->logger, OSGI_FRAMEWORK_LOG_ERROR,  "Could not create shutdown thread, normal exit not possible.");
-	        status = CELIX_FRAMEWORK_EXCEPTION;
-	    }
+
+        celixThreadMutex_lock(&framework->dispatcher.mutex);
+        framework->dispatcher.active = false;
+        celixThreadCondition_broadcast(&framework->dispatcher.cond);
+        celixThreadMutex_unlock(&framework->dispatcher.mutex);
+        celixThread_join(framework->dispatcher.thread, NULL);
+
+        celixThread_create(&framework->shutdown.thread, NULL, &framework_shutdown, framework);
 	} else {
 		status = CELIX_FRAMEWORK_EXCEPTION;
 	}
@@ -2789,36 +2583,34 @@ static celix_status_t framework_loadLibrary(framework_pt framework, const char *
 
 
 void celix_framework_useBundles(framework_t *fw, bool includeFrameworkBundle, void *callbackHandle, void(*use)(void *handle, const bundle_t *bnd)) {
-    celixThreadMutex_lock(&fw->installedBundleMapLock);
-    int size = hashMap_size(fw->installedBundleMap);
-    if (!includeFrameworkBundle) {
-        size -= 1; //skip framework bundle
-    }
-    long bundleIds[size];
-    int i = 0;
-    hash_map_iterator_t iter = hashMapIterator_construct(fw->installedBundleMap);
-    while (hashMapIterator_hasNext(&iter)) {
-        bundle_t *bnd = (bundle_t *) hashMapIterator_nextValue(&iter);
-        long bndId = celix_bundle_getId(bnd);
-        if (bndId > 0) {
+    celix_array_list_t *bundleIds = celix_arrayList_create();
+
+    celixThreadMutex_lock(&fw->installedBundles.mutex);
+    int size = celix_arrayList_size(fw->installedBundles.entries);
+    for (int i = 0; i < size; ++i) {
+        celix_framework_bundle_entry_t *entry = celix_arrayList_get(fw->installedBundles.entries, i);
+        if (entry->bndId > 0 || includeFrameworkBundle) {
             //NOTE bundle state is checked in celix_framework_useBundles
-            bundleIds[i++] =bndId;
-        }
-        if (bndId == 0 && includeFrameworkBundle) {
-            bundleIds[i++] = bndId;
+            celix_arrayList_addLong(bundleIds, entry->bndId);
         }
     }
-    celixThreadMutex_unlock(&fw->installedBundleMapLock);
+    celixThreadMutex_unlock(&fw->installedBundles.mutex);
+
+    //note that stored bundle ids can now already be invalid (race cond),
+    //but the celix_framework_useBundle function should be able to handle this safely.
 
-    size = i;
-    for (i = 0; i < size; ++i) {
-        celix_framework_useBundle(fw, true, bundleIds[i], callbackHandle, use);
+    size = celix_arrayList_size(bundleIds);
+    for (int i = 0; i < size; ++i) {
+        long bndId = celix_arrayList_getLong(bundleIds, i);
+        celix_framework_useBundle(fw, true, bndId, callbackHandle, use);
     }
+
+    celix_arrayList_destroy(bundleIds);
 }
 
 void celix_framework_useBundle(framework_t *fw, bool onlyActive, long bundleId, void *callbackHandle, void(*use)(void *handle, const bundle_t *bnd)) {
     if (bundleId >= 0) {
-        //TODO get bundle lock without throwing errors framework_acquireBundleLock() -> a more simple lock ??
+        fw_bundleEntry_increaseUseCount(fw, bundleId);
         bundle_t *bnd = framework_getBundleById(fw, bundleId);
         if (bnd != NULL) {
             celix_bundle_state_e bndState = celix_bundle_getState(bnd);
@@ -2830,7 +2622,7 @@ void celix_framework_useBundle(framework_t *fw, bool onlyActive, long bundleId,
         } else {
             framework_logIfError(fw->logger, CELIX_FRAMEWORK_EXCEPTION, NULL, "Bundle with id %li is not installed", bundleId);
         }
-        //TODO unlock
+        fw_bundleEntry_decreaseUseCount(fw, bundleId);
     }
 }
 
@@ -2838,15 +2630,16 @@ service_registration_t* celix_framework_registerServiceFactory(framework_t *fw ,
     const char *error = NULL;
     celix_status_t status = CELIX_SUCCESS;
     service_registration_t *reg = NULL;
+
+    long bndId = celix_bundle_getId(bnd);
+    fw_bundleEntry_increaseUseCount(fw, bndId);
+
     if (serviceName != NULL && factory != NULL) {
-        status = framework_acquireBundleLock(fw, (celix_bundle_t*)bnd, OSGI_FRAMEWORK_BUNDLE_STARTING|OSGI_FRAMEWORK_BUNDLE_ACTIVE);
         status = CELIX_DO_IF(status, celix_serviceRegistry_registerServiceFactory(fw->registry, bnd, serviceName, factory, properties, &reg));
-        if (!framework_releaseBundleLock(fw, (celix_bundle_t*)bnd)) {
-            status = CELIX_ILLEGAL_STATE;
-            error = "Could not release bundle lock";
-        }
     }
 
+    fw_bundleEntry_decreaseUseCount(fw, bndId);
+
     framework_logIfError(fw->logger, status, error, "Cannot register service factory: %s", serviceName);
 
     return reg;
@@ -2877,3 +2670,4 @@ celix_bundle_t* celix_framework_getFrameworkBundle(const celix_framework_t *fw)
     }
     return bnd;
 }
+

http://git-wip-us.apache.org/repos/asf/celix/blob/4d33bcd1/libs/framework/src/framework_private.h
----------------------------------------------------------------------
diff --git a/libs/framework/src/framework_private.h b/libs/framework/src/framework_private.h
index 5eafe7c..babffd3 100644
--- a/libs/framework/src/framework_private.h
+++ b/libs/framework/src/framework_private.h
@@ -46,7 +46,7 @@ struct framework {
     apr_pool_t *pool;
 #endif
     struct bundle * bundle;
-    hash_map_pt installedBundleMap;
+    long bundleId; //the bundle id of the framework (normally 0)
     hash_map_pt installRequestMap;
 
     celix_thread_mutex_t serviceListenersLock;
@@ -62,28 +62,30 @@ struct framework {
     celix_service_registry_t *registry;
     bundle_cache_pt cache;
 
-    celix_thread_cond_t shutdownGate;
-    celix_thread_cond_t condition;
+    struct {
+        celix_thread_mutex_t mutex;
+        celix_thread_cond_t cond;
+        bool done; //true is shutdown is done
+        celix_thread_t thread;
+    } shutdown;
 
-    celix_thread_mutex_t installedBundleMapLock;
-    celix_thread_mutex_t installRequestLock;
-    celix_thread_mutex_t mutex;
-    celix_thread_mutex_t bundleLock;
+    struct {
+        celix_array_list_t *entries; //value = celix_framework_bundle_entry_t*. Note ordered by installed bundle time
+                                     //i.e. later installed bundle are last
+        celix_thread_mutex_t mutex;
+    } installedBundles;
 
-    celix_thread_t globalLockThread;
-    array_list_pt globalLockWaitersList;
-    int globalLockCount;
-
-    bool interrupted;
-    bool shutdown;
 
     properties_pt configurationMap;
 
-    array_list_pt requests;
-    celix_thread_cond_t dispatcher;
-    celix_thread_mutex_t dispatcherLock;
-    celix_thread_t dispatcherThread;
-    celix_thread_t shutdownThread;
+
+    struct {
+        celix_thread_cond_t cond;
+        celix_thread_t thread;
+        celix_thread_mutex_t mutex; //protect active and requests
+        bool active;
+        celix_array_list_t *requests;
+    } dispatcher;
 
     framework_logger_pt logger;
 };