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 2020/07/16 18:58:53 UTC

[celix] branch feature/async_svc_registration updated: Refactors service tracker to better handle MT issues.

This is an automated email from the ASF dual-hosted git repository.

pnoltes pushed a commit to branch feature/async_svc_registration
in repository https://gitbox.apache.org/repos/asf/celix.git


The following commit(s) were added to refs/heads/feature/async_svc_registration by this push:
     new 714b201  Refactors service tracker to better handle MT issues.
714b201 is described below

commit 714b201ed324b00553830766730deef908a56aa1
Author: Pepijn Noltes <pe...@gmail.com>
AuthorDate: Thu Jul 16 20:58:26 2020 +0200

    Refactors service tracker to better handle MT issues.
---
 libs/framework/CMakeLists.txt                      |   4 -
 .../gtest/src/bundle_context_services_test.cpp     |  17 +-
 libs/framework/gtest/src/single_framework_test.cpp |  57 +-
 libs/framework/include/service_tracker.h           |  10 -
 libs/framework/src/framework.c                     | 243 +++----
 libs/framework/src/resolver.c                      |   3 +
 libs/framework/src/service_registry.c              | 235 ++-----
 libs/framework/src/service_registry_private.h      |   9 -
 libs/framework/src/service_tracker.c               | 761 ++++++++-------------
 libs/framework/src/service_tracker_private.h       |  59 +-
 10 files changed, 521 insertions(+), 877 deletions(-)

diff --git a/libs/framework/CMakeLists.txt b/libs/framework/CMakeLists.txt
index 950de4e..5d4ea4a 100644
--- a/libs/framework/CMakeLists.txt
+++ b/libs/framework/CMakeLists.txt
@@ -45,10 +45,6 @@ set_target_properties(framework PROPERTIES "SOVERSION" 2)
 target_link_libraries(framework PUBLIC Celix::utils Celix::dfi ${CELIX_OPTIONAL_EXTRA_LIBS})
 target_link_libraries(framework PUBLIC UUID::lib CURL::libcurl ZLIB::ZLIB)
 
-#Note option to ensure celix uses separate shutdown thread for closing service trackers.
-#This can prevent deadlocks, but those deadlock are bugs which need to be solved instead of this approach.
-#target_compile_definitions(framework PRIVATE -DCELIX_SERVICE_TRACKER_USE_SHUTDOWN_THREAD)
-
 install(TARGETS framework EXPORT celix DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT framework)
 install(DIRECTORY include/ DESTINATION include/celix COMPONENT framework)
 
diff --git a/libs/framework/gtest/src/bundle_context_services_test.cpp b/libs/framework/gtest/src/bundle_context_services_test.cpp
index 2d2b833..9d29b5b 100644
--- a/libs/framework/gtest/src/bundle_context_services_test.cpp
+++ b/libs/framework/gtest/src/bundle_context_services_test.cpp
@@ -740,7 +740,6 @@ TEST_F(CelixBundleContextServicesTests, servicesTrackerSetTest) {
     void *svc4 = (void*)0x400; //5 ranking
 
     auto set = [](void *handle, void *svc) {
-        ASSERT_TRUE(svc != nullptr);
         static int callCount = 0;
         callCount += 1;
         if (callCount == 1) {
@@ -766,28 +765,28 @@ TEST_F(CelixBundleContextServicesTests, servicesTrackerSetTest) {
     opts.callbackHandle = (void*)&count;
     opts.filter.serviceName = "NA";
     opts.set = set;
-    long trackerId = celix_bundleContext_trackServicesWithOptions(ctx, &opts);
+    long trackerId = celix_bundleContext_trackServicesWithOptions(ctx, &opts); //call 1
     ASSERT_TRUE(trackerId >= 0);
 
     //register svc3 should lead to second set call
     properties_t *props3 = celix_properties_create();
     celix_properties_set(props3, OSGI_FRAMEWORK_SERVICE_RANKING, "10");
-    long svcId3 = celix_bundleContext_registerService(ctx, svc3, "NA", props3);
+    long svcId3 = celix_bundleContext_registerService(ctx, svc3, "NA", props3); //call 2
 
     //register svc4 should lead to no set (lower ranking)
     properties_t *props4 = celix_properties_create();
     celix_properties_set(props4, OSGI_FRAMEWORK_SERVICE_RANKING, "10");
-    long svcId4 = celix_bundleContext_registerService(ctx, svc4, "NA", props4);
+    long svcId4 = celix_bundleContext_registerService(ctx, svc4, "NA", props4); //no update
 
     //unregister svc3 should lead to set (new highest ranking)
-    celix_bundleContext_unregisterService(ctx, svcId3);
+    celix_bundleContext_unregisterService(ctx, svcId3); //call 3
 
-    celix_bundleContext_stopTracker(ctx, trackerId);
+    celix_bundleContext_stopTracker(ctx, trackerId); //call 4 (NULL)
     celix_bundleContext_unregisterService(ctx, svcId1);
     celix_bundleContext_unregisterService(ctx, svcId2);
     celix_bundleContext_unregisterService(ctx, svcId4);
 
-    ASSERT_EQ(3, count); //check if the set is called the expected times
+    ASSERT_EQ(4, count); //check if the set is called the expected times
 }
 
 TEST_F(CelixBundleContextServicesTests, trackAllServices) {
@@ -991,10 +990,8 @@ TEST_F(CelixBundleContextServicesTests, trackServiceTrackerTest) {
     ASSERT_EQ(2, count);
 
     celix_bundleContext_stopTracker(ctx, tracker2);
-    celix_serviceTracker_syncForContext(ctx); //service tracker shutdown on separate track -> need sync
     ASSERT_EQ(1, count);
     celix_bundleContext_stopTracker(ctx, tracker3);
-    celix_serviceTracker_syncForContext(ctx); //service tracker shutdown on separate track -> need sync
     ASSERT_EQ(0, count);
 
     celix_bundleContext_stopTracker(ctx, trackerId);
@@ -1029,6 +1026,7 @@ TEST_F(CelixBundleContextServicesTests, floodEventLoopTest) {
         long id = celix_bundleContext_registerServiceAsync(ctx, (void*)0x42, "test", nullptr); //note cannot be completed because the first service registration in blocking in the event loop.
         EXPECT_GE(id, 0);
         svcIds.push_back(id);
+        celix_bundleContext_findService(ctx, "test"); //just to add some entropy
     }
 
     {
@@ -1045,5 +1043,6 @@ TEST_F(CelixBundleContextServicesTests, floodEventLoopTest) {
     celix_bundleContext_unregisterServiceAsync(ctx, svcId);
     for (auto id : svcIds) {
         celix_bundleContext_unregisterServiceAsync(ctx, id);
+        celix_bundleContext_findService(ctx, "test"); //just to add some entropy
     }
 }
\ No newline at end of file
diff --git a/libs/framework/gtest/src/single_framework_test.cpp b/libs/framework/gtest/src/single_framework_test.cpp
index 2fa7f39..03d164e 100644
--- a/libs/framework/gtest/src/single_framework_test.cpp
+++ b/libs/framework/gtest/src/single_framework_test.cpp
@@ -149,33 +149,32 @@ TEST_F(FrameworkFactory, recreateFramework) {
     framework_destroy(fw);
 }
 
-//TODO fix this. Restarting seems to increase the framework bundle usage count
-//TEST_F(FrameworkFactory, restartFramework) {
-//    framework_t* fw = celix_frameworkFactory_createFramework(nullptr);
-//    ASSERT_TRUE(fw != nullptr);
-//    framework_stop(fw);
-//    framework_waitForStop(fw);
-//
-//    framework_start(fw);
-//    framework_stop(fw);
-//    framework_waitForStop(fw);
-//
-//    framework_start(fw);
-//    framework_stop(fw);
-//    framework_waitForStop(fw);
-//
-//    framework_start(fw);
-//    framework_stop(fw);
-//    framework_waitForStop(fw);
-//
-//    framework_start(fw);
-//    framework_stop(fw);
-//    framework_waitForStop(fw);
-//
-//    framework_start(fw);
-//    framework_stop(fw);
-//    framework_waitForStop(fw);
-//
-//    framework_destroy(fw);
-//}
+TEST_F(FrameworkFactory, restartFramework) {
+    framework_t* fw = celix_frameworkFactory_createFramework(nullptr);
+    ASSERT_TRUE(fw != nullptr);
+    framework_stop(fw);
+    framework_waitForStop(fw);
+
+    framework_start(fw);
+    framework_stop(fw);
+    framework_waitForStop(fw);
+
+    framework_start(fw);
+    framework_stop(fw);
+    framework_waitForStop(fw);
+
+    framework_start(fw);
+    framework_stop(fw);
+    framework_waitForStop(fw);
+
+    framework_start(fw);
+    framework_stop(fw);
+    framework_waitForStop(fw);
+
+    framework_start(fw);
+    framework_stop(fw);
+    framework_waitForStop(fw);
+
+    framework_destroy(fw);
+}
 
diff --git a/libs/framework/include/service_tracker.h b/libs/framework/include/service_tracker.h
index 4e69621..9fd7727 100644
--- a/libs/framework/include/service_tracker.h
+++ b/libs/framework/include/service_tracker.h
@@ -134,16 +134,6 @@ size_t celix_serviceTracker_useServices(
         void (*useWithOwner)(void *handle, void *svc, const celix_properties_t *props, const celix_bundle_t *owner)
 );
 
-/**
- * blocks until all shutdown threads for the service tracker instances for the provided framework are done.
- */
-void celix_serviceTracker_syncForFramework(void *fw);
-
-/**
- * blocks until all shutdown threads for the service tracker instances for the provided bundle context are done.
- */
-void celix_serviceTracker_syncForContext(void *ctx);
-
 
 #ifdef __cplusplus
 }
diff --git a/libs/framework/src/framework.c b/libs/framework/src/framework.c
index 95ea491..70700e9 100644
--- a/libs/framework/src/framework.c
+++ b/libs/framework/src/framework.c
@@ -69,10 +69,16 @@ static inline celix_framework_bundle_entry_t* fw_bundleEntry_create(celix_bundle
 
 static inline void fw_bundleEntry_waitTillUseCountIs(celix_framework_bundle_entry_t *entry, size_t desiredUseCount) {
     celixThreadMutex_lock(&entry->useMutex);
+    time_t start = time(NULL);
+    bool warningPrinted = false;
     while (entry->useCount != desiredUseCount) {
         celixThreadCondition_timedwaitRelative(&entry->useCond, &entry->useMutex, 5, 0);
         if (entry->useCount != desiredUseCount) {
-            fw_log(celix_frameworkLogger_globalLogger(), CELIX_LOG_LEVEL_WARNING, "Bundle %s (%li) still in use. Use count is %u, desired is ", celix_bundle_getSymbolicName(entry->bnd), entry->bndId, entry->useCount, desiredUseCount);
+            time_t now = time(NULL);
+            if (!warningPrinted && (now-start) > 5) {
+                fw_log(celix_frameworkLogger_globalLogger(), CELIX_LOG_LEVEL_WARNING, "Bundle %s (%li) still in use. Use count is %u, desired is %li", celix_bundle_getSymbolicName(entry->bnd), entry->bndId, entry->useCount, desiredUseCount);
+                warningPrinted = true;
+            }
         }
     }
     celixThreadMutex_unlock(&entry->useMutex);
@@ -137,7 +143,6 @@ static inline celix_framework_bundle_entry_t* fw_bundleEntry_removeBundleEntryAn
     return found;
 }
 
-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);
@@ -230,61 +235,66 @@ struct fw_frameworkListener {
 typedef struct fw_frameworkListener * fw_framework_listener_pt;
 
 
-celix_status_t framework_create(framework_pt *framework, properties_pt config) {
-    celix_status_t status = CELIX_SUCCESS;
+celix_status_t framework_create(framework_pt *out, properties_pt config) {
+    celix_framework_t* framework = calloc(1, sizeof(*framework));
+//    celix_thread_mutexattr_t attr;
+//    celixThreadMutexAttr_create(&attr);
+//    celixThreadMutexAttr_settype(&attr, CELIX_THREAD_MUTEX_RECURSIVE);
 
-    *framework = (framework_pt) malloc(sizeof(**framework));
-    if (*framework != NULL) {
-        celix_thread_mutexattr_t attr;
-        celixThreadMutexAttr_create(&attr);
-        celixThreadMutexAttr_settype(&attr, CELIX_THREAD_MUTEX_RECURSIVE);
-
-        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));
-        status = CELIX_DO_IF(status, celixThreadMutex_create(&(*framework)->frameworkListenersLock, &attr));
-        status = CELIX_DO_IF(status, celixThreadMutex_create(&(*framework)->bundleListenerLock, NULL));
-        status = CELIX_DO_IF(status, celixThreadMutex_create(&(*framework)->installedBundles.mutex, NULL));
-        status = CELIX_DO_IF(status, celixThreadCondition_init(&(*framework)->dispatcher.cond, NULL));
-        if (status == CELIX_SUCCESS) {
-            (*framework)->bundle = NULL;
-            (*framework)->registry = NULL;
-            (*framework)->shutdown.done = false;
-            (*framework)->shutdown.initialized = 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)->bundleListeners = NULL;
-            (*framework)->frameworkListeners = NULL;
-            (*framework)->dispatcher.dynamicEventQueue = NULL;
-            (*framework)->configurationMap = config;
-
-            const char* logStr = getenv(CELIX_LOGGING_DEFAULT_ACTIVE_LOG_LEVEL_CONFIG_NAME);
-            if (logStr == NULL) {
-                logStr = celix_properties_get(config, CELIX_LOGGING_DEFAULT_ACTIVE_LOG_LEVEL_CONFIG_NAME, CELIX_LOGGING_DEFAULT_ACTIVE_LOG_LEVEL_DEFAULT_VALUE);
-            }
-            (*framework)->logger = celix_frameworkLogger_create(celix_logUtils_logLevelFromString(logStr, CELIX_LOG_LEVEL_INFO));
+    celixThreadCondition_init(&framework->shutdown.cond, NULL);
+    celixThreadMutex_create(&framework->shutdown.mutex, NULL);
+    celixThreadMutex_create(&framework->dispatcher.mutex, NULL);
+    celixThreadMutex_create(&framework->frameworkListenersLock, NULL);
+    celixThreadMutex_create(&framework->bundleListenerLock, NULL);
+    celixThreadMutex_create(&framework->installedBundles.mutex, NULL);
+    celixThreadCondition_init(&framework->dispatcher.cond, NULL);
+    framework->dispatcher.active = true;
+    framework->nextBundleId = 1L; //system bundle is 0
+    framework->installRequestMap = hashMap_create(utils_stringHash, utils_stringHash, utils_stringEquals, utils_stringEquals);
+    framework->installedBundles.entries = celix_arrayList_create();
+    framework->configurationMap = config;
+    framework->bundleListeners = celix_arrayList_create();
+    framework->frameworkListeners = celix_arrayList_create();
+    framework->dispatcher.dynamicEventQueue = celix_arrayList_create();
+
+    //create and store framework uuid
+    char uuid[37];
+    uuid_t uid;
+    uuid_generate(uid);
+    uuid_unparse(uid, uuid);
+    properties_set(framework->configurationMap, (char*) OSGI_FRAMEWORK_FRAMEWORK_UUID, uuid);
 
-            status = CELIX_DO_IF(status, bundle_create(&(*framework)->bundle));
-            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) {
-                //nop
-            } else {
-                status = CELIX_FRAMEWORK_EXCEPTION;
-                fw_logCode((*framework)->logger, CELIX_LOG_LEVEL_ERROR, status, "Could not create framework");
-            }
-        } else {
-            status = CELIX_FRAMEWORK_EXCEPTION;
-            fw_logCode((*framework)->logger, CELIX_LOG_LEVEL_ERROR, status, "Could not create framework");
-        }
-    } else {
-        status = CELIX_FRAMEWORK_EXCEPTION;
-        fw_logCode((*framework)->logger, CELIX_LOG_LEVEL_ERROR, CELIX_ENOMEM, "Could not create framework");
+    //setup framework logger
+    const char* logStr = getenv(CELIX_LOGGING_DEFAULT_ACTIVE_LOG_LEVEL_CONFIG_NAME);
+    if (logStr == NULL) {
+        logStr = celix_properties_get(config, CELIX_LOGGING_DEFAULT_ACTIVE_LOG_LEVEL_CONFIG_NAME, CELIX_LOGGING_DEFAULT_ACTIVE_LOG_LEVEL_DEFAULT_VALUE);
     }
+    framework->logger = celix_frameworkLogger_create(celix_logUtils_logLevelFromString(logStr, CELIX_LOG_LEVEL_INFO));
 
+    celix_status_t status =bundle_create(&framework->bundle);
+    status = CELIX_DO_IF(status, bundle_getBundleId(framework->bundle, &framework->bundleId));
+    status = CELIX_DO_IF(status, bundle_setFramework(framework->bundle, framework));
+    status = CELIX_DO_IF(status, bundleCache_create(uuid, framework->configurationMap, &framework->cache));
+    status = CELIX_DO_IF(status, serviceRegistry_create(framework, &framework->registry));
+    bundle_context_t *context = NULL;
+    status = CELIX_DO_IF(status, bundleContext_create(framework, framework->logger, framework->bundle, &context));
+    status = CELIX_DO_IF(status, bundle_setContext(framework->bundle, context));
+
+    //create framework bundle entry
+    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);
+
+    if (status != CELIX_SUCCESS) {
+        fw_logCode(framework->logger, CELIX_LOG_LEVEL_ERROR, status, "Could not create framework");
+        free(framework);
+        framework = NULL;
+    }
+
+    *out = framework;
     return status;
 }
 
@@ -389,22 +399,6 @@ celix_status_t framework_destroy(framework_pt framework) {
 }
 
 celix_status_t fw_init(framework_pt framework) {
-	bundle_state_e state = OSGI_FRAMEWORK_BUNDLE_UNKNOWN;
-	const char *location = NULL;
-	module_pt module = NULL;
-	linked_list_pt wires = NULL;
-	array_list_pt archives = NULL;
-	bundle_archive_pt archive = NULL;
-
-    /*create and store framework uuid*/
-    char uuid[37];
-
-    uuid_t uid;
-    uuid_generate(uid);
-    uuid_unparse(uid, uuid);
-
-    properties_set(framework->configurationMap, (char*) OSGI_FRAMEWORK_FRAMEWORK_UUID, uuid);
-
     celixThreadMutex_lock(&framework->dispatcher.mutex);
     framework->dispatcher.active = true;
     celixThreadMutex_unlock(&framework->dispatcher.mutex);
@@ -415,49 +409,15 @@ celix_status_t fw_init(framework_pt framework) {
     celixThreadMutex_unlock(&framework->shutdown.mutex);
 
 
-	celix_status_t status = CELIX_SUCCESS;
-	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->dispatcher.dynamicEventQueue));
-	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)) {
-	        status = CELIX_DO_IF(status, bundleCache_create(uuid, framework->configurationMap,&framework->cache));
-	        status = CELIX_DO_IF(status, bundle_getState(framework->bundle, &state));
-	        if (status == CELIX_SUCCESS) {
-	            if (state == OSGI_FRAMEWORK_BUNDLE_INSTALLED) {
-	                bool cleanCache = celix_properties_getAsBool(framework->configurationMap, OSGI_FRAMEWORK_FRAMEWORK_STORAGE_CLEAN_NAME, OSGI_FRAMEWORK_FRAMEWORK_STORAGE_CLEAN_DEFAULT);
-	                if (cleanCache) {
-	                    bundleCache_delete(framework->cache);
-	                }
-	            }
-            }
-        }
-	}
+	celixThread_create(&framework->dispatcher.thread, NULL, fw_eventDispatcher, framework);
 
-    status = CELIX_DO_IF(status, bundle_getArchive(framework->bundle, &archive));
-    status = CELIX_DO_IF(status, bundleArchive_getLocation(archive, &location));
-    if (status == CELIX_SUCCESS) {
-        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) {
-        wires = resolver_resolve(module);
-        if (wires != NULL) {
-            framework_markResolvedModules(framework, wires);
-        } else {
-            status = CELIX_BUNDLE_EXCEPTION;
-            fw_logCode(framework->logger, CELIX_LOG_LEVEL_ERROR, status, "Unresolved constraints in System Bundle");
-        }
+    bool cleanCache = celix_properties_getAsBool(framework->configurationMap, OSGI_FRAMEWORK_FRAMEWORK_STORAGE_CLEAN_NAME, OSGI_FRAMEWORK_FRAMEWORK_STORAGE_CLEAN_DEFAULT);
+    if (cleanCache) {
+        bundleCache_delete(framework->cache);
     }
 
-    status = CELIX_DO_IF(status, bundleCache_getArchives(framework->cache, &archives));
+    celix_array_list_t* archives = NULL;
+    celix_status_t status = bundleCache_getArchives(framework->cache, &archives);
     if (status == CELIX_SUCCESS) {
         unsigned int arcIdx;
         for (arcIdx = 0; arcIdx < arrayList_size(archives); arcIdx++) {
@@ -480,12 +440,9 @@ celix_status_t fw_init(framework_pt framework) {
         arrayList_destroy(archives);
     }
 
-    status = CELIX_DO_IF(status, serviceRegistry_create(framework, &framework->registry));
-    status = CELIX_DO_IF(status, framework_setBundleStateAndNotify(framework, framework->bundle, OSGI_FRAMEWORK_BUNDLE_STARTING));
 
-    bundle_context_t *context = NULL;
-    status = CELIX_DO_IF(status, bundleContext_create(framework, framework->logger, framework->bundle, &context));
-    status = CELIX_DO_IF(status, bundle_setContext(framework->bundle, context));
+    status = CELIX_DO_IF(status, bundle_setState(framework->bundle, OSGI_FRAMEWORK_BUNDLE_STARTING));
+
     if (status == CELIX_SUCCESS) {
         celix_bundle_activator_t *activator = calloc(1,(sizeof(*activator)));
         if (activator != NULL) {
@@ -504,19 +461,11 @@ celix_status_t fw_init(framework_pt framework) {
             status = CELIX_DO_IF(status, bundle_getContext(framework->bundle, &validateContext));
 
             if (status == CELIX_SUCCESS) {
-                /* This code part is in principle dead, but in future it may do something.
-                 * That's why it's outcommented and not deleted
-		        if (create != NULL) {
-                    create(context, &userData);
-                }
-                */
                 activator->userData = userData;
-
                 if (start != NULL) {
                     start(userData, validateContext);
                 }
-            }
-            else{
+            } else {
             	free(activator);
             }
         } else {
@@ -543,10 +492,8 @@ celix_status_t framework_start(framework_pt framework) {
 	}
 
 	status = CELIX_DO_IF(status, bundle_getState(framework->bundle, &state));
-	if (status == CELIX_SUCCESS) {
-	    if (state == OSGI_FRAMEWORK_BUNDLE_STARTING) {
-	        status = CELIX_DO_IF(status, framework_setBundleStateAndNotify(framework, framework->bundle, OSGI_FRAMEWORK_BUNDLE_ACTIVE));
-	    }
+	if (status == CELIX_SUCCESS && state == OSGI_FRAMEWORK_BUNDLE_STARTING) {
+        bundle_setState(framework->bundle, OSGI_FRAMEWORK_BUNDLE_ACTIVE);
 	}
 
 	celix_framework_bundle_entry_t* entry = fw_bundleEntry_getBundleEntryAndIncreaseUseCount(framework, framework->bundleId);
@@ -892,7 +839,7 @@ celix_status_t fw_startBundle(framework_pt framework, long bndId, int options __
 
                         status = CELIX_DO_IF(status, bundle_setActivator(entry->bnd, activator));
 
-                        status = CELIX_DO_IF(status, framework_setBundleStateAndNotify(framework, entry->bnd, OSGI_FRAMEWORK_BUNDLE_STARTING));
+                        status = CELIX_DO_IF(status, bundle_setState(entry->bnd, OSGI_FRAMEWORK_BUNDLE_STARTING));
                         CELIX_DO_IF(status, fw_fireBundleEvent(framework, OSGI_FRAMEWORK_BUNDLE_EVENT_STARTING, entry));
 
                         status = CELIX_DO_IF(status, bundle_getContext(entry->bnd, &context));
@@ -911,7 +858,7 @@ celix_status_t fw_startBundle(framework_pt framework, long bndId, int options __
                             }
                         }
 
-                        status = CELIX_DO_IF(status, framework_setBundleStateAndNotify(framework, entry->bnd, OSGI_FRAMEWORK_BUNDLE_ACTIVE));
+                        status = CELIX_DO_IF(status, bundle_setState(entry->bnd, OSGI_FRAMEWORK_BUNDLE_ACTIVE));
                         CELIX_DO_IF(status, fw_fireBundleEvent(framework, OSGI_FRAMEWORK_BUNDLE_EVENT_STARTED, entry));
 
                         if (status != CELIX_SUCCESS) {
@@ -924,7 +871,7 @@ celix_status_t fw_startBundle(framework_pt framework, long bndId, int options __
                             bundle_setActivator(entry->bnd, NULL);
                             bundleContext_destroy(context);
                             free(activator);
-                            framework_setBundleStateAndNotify(framework, entry->bnd, OSGI_FRAMEWORK_BUNDLE_RESOLVED);
+                            status = bundle_setState(entry->bnd, OSGI_FRAMEWORK_BUNDLE_RESOLVED);
                         }
                     }
                 }
@@ -975,7 +922,7 @@ celix_status_t framework_updateBundle(framework_pt framework, bundle_pt bundle,
 	status = CELIX_DO_IF(status, bundle_revise(bundle, location, inputFile));
 
 	status = CELIX_DO_IF(status, bundleArchive_setLastModified(archive, time(NULL)));
-	status = CELIX_DO_IF(status, framework_setBundleStateAndNotify(framework, bundle, OSGI_FRAMEWORK_BUNDLE_INSTALLED));
+	status = CELIX_DO_IF(status, bundle_setState(bundle, OSGI_FRAMEWORK_BUNDLE_INSTALLED));
 
 	bundle_revision_pt revision = NULL;
 	array_list_pt handles = NULL;
@@ -1069,10 +1016,10 @@ celix_status_t fw_stopBundle(framework_pt framework, long bndId, bool record) {
 	}
 
 
-	CELIX_DO_IF(status, framework_setBundleStateAndNotify(framework, entry->bnd, OSGI_FRAMEWORK_BUNDLE_STOPPING));
+	CELIX_DO_IF(status, bundle_setState(entry->bnd, OSGI_FRAMEWORK_BUNDLE_STOPPING));
 	CELIX_DO_IF(status, fw_fireBundleEvent(framework, OSGI_FRAMEWORK_BUNDLE_EVENT_STOPPING, entry));
 	if (status == CELIX_SUCCESS) {
-	    if (wasActive || (bndId == 0)) {
+	    if (wasActive) {
 	        activator = bundle_getActivator(entry->bnd);
 
 	        status = CELIX_DO_IF(status, bundle_getContext(entry->bnd, &context));
@@ -1092,9 +1039,7 @@ celix_status_t fw_stopBundle(framework_pt framework, long bndId, bool record) {
 	        }
 
             if (bndId > 0) {
-	            celix_serviceTracker_syncForContext(entry->bnd->context);
 	            celix_bundleContext_cleanup(entry->bnd->context);
-                celix_serviceTracker_syncForContext(framework->bundle->context);
                 if (status == CELIX_SUCCESS) {
                     module_pt module = NULL;
                     const char *symbolicName = NULL;
@@ -1109,12 +1054,14 @@ celix_status_t fw_stopBundle(framework_pt framework, long bndId, bool record) {
                     status = CELIX_DO_IF(status, bundle_setContext(entry->bnd, NULL));
                 }
 
-                status = CELIX_DO_IF(status, framework_setBundleStateAndNotify(framework, entry->bnd, OSGI_FRAMEWORK_BUNDLE_RESOLVED));
+                status = CELIX_DO_IF(status, bundle_setState(entry->bnd, OSGI_FRAMEWORK_BUNDLE_RESOLVED));
+                CELIX_DO_IF(status, fw_fireBundleEvent(framework, OSGI_FRAMEWORK_BUNDLE_EVENT_STOPPED, entry));
             } else if (bndId == 0) {
                 //framework bundle
-                celix_serviceTracker_syncForContext(framework->bundle->context);
                 celix_bundleContext_cleanup(entry->bnd->context);
-                celix_serviceTracker_syncForContext(framework->bundle->context);
+
+                status = CELIX_DO_IF(status, bundle_setState(entry->bnd, OSGI_FRAMEWORK_BUNDLE_RESOLVED));
+                CELIX_DO_IF(status, fw_fireBundleEvent(framework, OSGI_FRAMEWORK_BUNDLE_EVENT_STOPPED, entry));
             }
 	    }
 
@@ -1141,7 +1088,6 @@ celix_status_t fw_stopBundle(framework_pt framework, long bndId, bool record) {
  	}
 
 	fw_bundleEntry_decreaseUseCount(entry);
-    celix_serviceTracker_syncForFramework(framework);
 
 	return status;
 }
@@ -1176,7 +1122,7 @@ static celix_status_t fw_uninstallBundleEntry(celix_framework_t *framework, celi
 
         CELIX_DO_IF(status, fw_fireBundleEvent(framework, OSGI_FRAMEWORK_BUNDLE_EVENT_UNRESOLVED, entry));
 
-        status = CELIX_DO_IF(status, framework_setBundleStateAndNotify(framework, bnd, OSGI_FRAMEWORK_BUNDLE_UNINSTALLED));
+        status = CELIX_DO_IF(status, bundle_setState(bnd, OSGI_FRAMEWORK_BUNDLE_UNINSTALLED));
         status = CELIX_DO_IF(status, bundleArchive_setLastModified(archive, time(NULL)));
 
         CELIX_DO_IF(status, fw_fireBundleEvent(framework, OSGI_FRAMEWORK_BUNDLE_EVENT_UNINSTALLED, entry));
@@ -1290,7 +1236,7 @@ celix_status_t fw_refreshBundle(framework_pt framework, long bndId) {
         bundle_refresh(entry->bnd);
 
         if (fire) {
-            framework_setBundleStateAndNotify(framework, entry->bnd, OSGI_FRAMEWORK_BUNDLE_INSTALLED);
+            bundle_setState(entry->bnd, OSGI_FRAMEWORK_BUNDLE_INSTALLED);
             fw_fireBundleEvent(framework, OSGI_FRAMEWORK_BUNDLE_EVENT_UNRESOLVED, entry);
         }
 
@@ -1750,7 +1696,7 @@ celix_status_t framework_markBundleResolved(framework_pt framework, module_pt mo
                 status = CELIX_DO_IF(status, framework_loadBundleLibraries(framework, bundle));
             }
 
-            status = CELIX_DO_IF(status, framework_setBundleStateAndNotify(framework, bundle, OSGI_FRAMEWORK_BUNDLE_RESOLVED));
+            status = CELIX_DO_IF(status, bundle_setState(bundle, OSGI_FRAMEWORK_BUNDLE_RESOLVED));
             CELIX_DO_IF(status, fw_fireBundleEvent(framework, OSGI_FRAMEWORK_BUNDLE_EVENT_RESOLVED, entry));
         }
 
@@ -1812,12 +1758,6 @@ bundle_pt framework_getBundle(framework_pt framework, const char* location) {
     return bnd;
 }
 
-celix_status_t framework_setBundleStateAndNotify(framework_pt framework, bundle_pt bundle, int state) {
-    int ret = CELIX_SUCCESS;
-    bundle_setState(bundle, state);
-    return ret;
-}
-
 celix_status_t framework_waitForStop(framework_pt framework) {
     celixThreadMutex_lock(&framework->shutdown.mutex);
     while (!framework->shutdown.done) {
@@ -1979,7 +1919,7 @@ static void celix_framework_addToEventQueue(celix_framework_t *fw, const celix_f
 
 static void fw_handleEventRequest(celix_framework_t *framework, celix_framework_event_t* event) {
     if (event->type == CELIX_BUNDLE_EVENT_TYPE) {
-        fw_log(framework->logger, CELIX_LOG_LEVEL_TRACE, "Handling fw bundle event for bundle %s", event->bndEntry->bnd->symbolicName);
+        //fw_log(framework->logger, CELIX_LOG_LEVEL_TRACE, "Handling fw bundle event for bundle %s", event->bndEntry->bnd->symbolicName);
         celix_array_list_t *localListeners = celix_arrayList_create();
         celixThreadMutex_lock(&framework->bundleListenerLock);
         for (int i = 0; i < celix_arrayList_size(framework->bundleListeners); ++i) {
@@ -2003,7 +1943,6 @@ static void fw_handleEventRequest(celix_framework_t *framework, celix_framework_
     } else if (event->type == CELIX_FRAMEWORK_EVENT_TYPE) {
         fw_log(framework->logger, CELIX_LOG_LEVEL_TRACE, "Handling fw event");
         celixThreadMutex_lock(&framework->frameworkListenersLock);
-        //TODO refactor use of framework listeners to use a useCount + conditition.
         for (int i = 0; i < celix_arrayList_size(framework->frameworkListeners); ++i) {
             fw_framework_listener_pt listener = celix_arrayList_get(framework->frameworkListeners, i);
             framework_event_t fEvent;
@@ -2016,7 +1955,7 @@ static void fw_handleEventRequest(celix_framework_t *framework, celix_framework_
         }
         celixThreadMutex_unlock(&framework->frameworkListenersLock);
     } else if (event->type == CELIX_REGISTER_SERVICE_EVENT) {
-        fw_log(framework->logger, CELIX_LOG_LEVEL_TRACE, "Handling fw service registration event for service '%s' with svc id %li", event->serviceName, event->registerServiceId);
+        //fw_log(framework->logger, CELIX_LOG_LEVEL_TRACE, "Handling fw service registration event for service '%s' with svc id %li", event->serviceName, event->registerServiceId);
         service_registration_t* reg = NULL;
         celix_status_t status;
         if (event->factory != NULL) {
@@ -2030,7 +1969,7 @@ static void fw_handleEventRequest(celix_framework_t *framework, celix_framework_
             event->registerCallback(event->registerData, serviceRegistration_getServiceId(reg));
         }
     } else if (event->type == CELIX_UNREGISTER_SERVICE_EVENT) {
-        fw_log(framework->logger, CELIX_LOG_LEVEL_TRACE, "Handling fw service unregister event for service id %li", event->unregisterServiceId);
+        //fw_log(framework->logger, CELIX_LOG_LEVEL_TRACE, "Handling fw service unregister event for service id %li", event->unregisterServiceId);
         celix_serviceRegistry_unregisterService(framework->registry, event->bndEntry->bnd, event->unregisterServiceId);
     }
 }
diff --git a/libs/framework/src/resolver.c b/libs/framework/src/resolver.c
index ac34609..5b68632 100644
--- a/libs/framework/src/resolver.c
+++ b/libs/framework/src/resolver.c
@@ -288,6 +288,9 @@ void resolver_addModule(module_pt module) {
 }
 
 void resolver_removeModule(module_pt module) {
+    if (m_modules == NULL) {
+        return;
+    }
     linked_list_pt caps = NULL;
     linkedList_removeElement(m_modules, module);
     caps = module_getCapabilities(module);
diff --git a/libs/framework/src/service_registry.c b/libs/framework/src/service_registry.c
index 48cc0da..bb878e3 100644
--- a/libs/framework/src/service_registry.c
+++ b/libs/framework/src/service_registry.c
@@ -30,22 +30,10 @@
 #include "service_reference_private.h"
 #include "framework_private.h"
 
-#ifdef DEBUG
-#define CHECK_DELETED_REFERENCES true
-#else
-#define CHECK_DELETED_REFERENCES false
-#endif
-
 static celix_status_t serviceRegistry_registerServiceInternal(service_registry_pt registry, bundle_pt bundle, const char* serviceName, const void * serviceObject, properties_pt dictionary, long reservedId, enum celix_service_type svcType, service_registration_pt *registration);
 static celix_status_t serviceRegistry_addHooks(service_registry_pt registry, const char* serviceName, const void *serviceObject, service_registration_pt registration);
 static celix_status_t serviceRegistry_removeHook(service_registry_pt registry, service_registration_pt registration);
 static void serviceRegistry_logWarningServiceReferenceUsageCount(service_registry_pt registry, bundle_pt bundle, service_reference_pt ref, size_t usageCount, size_t refCount);
-static celix_status_t serviceRegistry_checkReference(service_registry_pt registry, service_reference_pt ref,
-                                                     reference_status_t *refStatus);
-static void serviceRegistry_logIllegalReference(service_registry_pt registry, service_reference_pt reference,
-                                                   reference_status_t refStatus);
-static celix_status_t serviceRegistry_setReferenceStatus(service_registry_pt registry, service_reference_pt reference,
-                                                  bool deleted);
 static celix_status_t serviceRegistry_getUsingBundles(service_registry_pt registry, service_registration_pt reg, array_list_pt *bundles);
 static celix_status_t serviceRegistry_getServiceReference_internal(service_registry_pt registry, bundle_pt owner, service_registration_pt registration, service_reference_pt *out);
 static void celix_serviceRegistry_serviceChanged(celix_service_registry_t *registry, celix_service_event_type_t eventType, service_registration_pt registration);
@@ -81,9 +69,6 @@ celix_status_t serviceRegistry_create(framework_pt framework, service_registry_p
         reg->nextServiceId = 1L;
         reg->serviceReferences = hashMap_create(NULL, NULL, NULL, NULL);
 
-        reg->checkDeletedReferences = CHECK_DELETED_REFERENCES;
-        reg->deletedServiceReferences = hashMap_create(NULL, NULL, NULL, NULL);
-
 		reg->listenerHooks = celix_arrayList_create();
 		reg->serviceListeners = celix_arrayList_create();
 
@@ -154,8 +139,6 @@ celix_status_t serviceRegistry_destroy(service_registry_pt registry) {
     }
     celix_arrayList_destroy(registry->listenerHooks);
 
-    hashMap_destroy(registry->deletedServiceReferences, false, false);
-
     size = hashMap_size(registry->pendingRegisterEvents.map);
     assert(size == 0);
     celixThreadMutex_destroy(&registry->pendingRegisterEvents.mutex);
@@ -333,7 +316,6 @@ static celix_status_t serviceRegistry_getServiceReference_internal(service_regis
         }
         if (status == CELIX_SUCCESS) {
             hashMap_put(references, (void*)registration->serviceId, ref);
-            hashMap_put(registry->deletedServiceReferences, ref, (void *)false);
         }
     } else {
         serviceReference_retain(ref);
@@ -434,21 +416,15 @@ celix_status_t serviceRegistry_getServiceReferences(service_registry_pt registry
 
 celix_status_t serviceRegistry_retainServiceReference(service_registry_pt registry, bundle_pt bundle, service_reference_pt reference) {
     celix_status_t status = CELIX_SUCCESS;
-    reference_status_t refStatus;
     bundle_pt refBundle = NULL;
     
     celixThreadRwlock_writeLock(&registry->lock);
-    serviceRegistry_checkReference(registry, reference, &refStatus);
-    if (refStatus == REF_ACTIVE) {
-        serviceReference_getOwner(reference, &refBundle);
-        if (refBundle == bundle) {
-            serviceReference_retain(reference);
-        } else {
-            status = CELIX_ILLEGAL_ARGUMENT;
-            fw_log(registry->framework->logger, CELIX_LOG_LEVEL_ERROR, "cannot retain a service reference from an other bundle (in ref %p) (provided %p).", refBundle, bundle);
-        }
+    serviceReference_getOwner(reference, &refBundle);
+    if (refBundle == bundle) {
+        serviceReference_retain(reference);
     } else {
-        serviceRegistry_logIllegalReference(registry, reference, refStatus);
+        status = CELIX_ILLEGAL_ARGUMENT;
+        fw_log(registry->framework->logger, CELIX_LOG_LEVEL_ERROR, "cannot retain a service reference from an other bundle (in ref %p) (provided %p).", refBundle, bundle);
     }
     celixThreadRwlock_unlock(&registry->lock);
 
@@ -460,97 +436,54 @@ celix_status_t serviceRegistry_ungetServiceReference(service_registry_pt registr
     celix_status_t status = CELIX_SUCCESS;
     bool destroyed = false;
     size_t count = 0;
-    reference_status_t refStatus;
 
     celixThreadRwlock_writeLock(&registry->lock);
-    serviceRegistry_checkReference(registry, reference, &refStatus);
-    if (refStatus == REF_ACTIVE) {
-        serviceReference_getUsageCount(reference, &count);
-        serviceReference_release(reference, &destroyed);
-        if (destroyed) {
-
-            if (count > 0) {
-                serviceRegistry_logWarningServiceReferenceUsageCount(registry, bundle, reference, count, 0);
-            }
+    serviceReference_getUsageCount(reference, &count);
+    serviceReference_release(reference, &destroyed);
+    if (destroyed) {
 
-            hash_map_pt refsMap = hashMap_get(registry->serviceReferences, bundle);
+        if (count > 0) {
+            serviceRegistry_logWarningServiceReferenceUsageCount(registry, bundle, reference, count, 0);
+        }
 
-            unsigned long refId = 0UL;
-            service_reference_pt ref = NULL;
+        hash_map_pt refsMap = hashMap_get(registry->serviceReferences, bundle);
 
-            if (refsMap != NULL) {
-                hash_map_iterator_t iter = hashMapIterator_construct(refsMap);
-                while (hashMapIterator_hasNext(&iter)) {
-                    hash_map_entry_pt entry = hashMapIterator_nextEntry(&iter);
-                    refId = (unsigned long) hashMapEntry_getKey(entry); //note could be invalid e.g. freed
-                    ref = hashMapEntry_getValue(entry);
+        unsigned long refId = 0UL;
+        service_reference_pt ref = NULL;
 
-                    if (ref == reference) {
-                        break;
-                    } else {
-                        ref = NULL;
-                        refId = 0UL;
-                    }
+        if (refsMap != NULL) {
+            hash_map_iterator_t iter = hashMapIterator_construct(refsMap);
+            while (hashMapIterator_hasNext(&iter)) {
+                hash_map_entry_pt entry = hashMapIterator_nextEntry(&iter);
+                refId = (unsigned long) hashMapEntry_getKey(entry); //note could be invalid e.g. freed
+                ref = hashMapEntry_getValue(entry);
+
+                if (ref == reference) {
+                    break;
+                } else {
+                    ref = NULL;
+                    refId = 0UL;
                 }
             }
+        }
 
-            if (ref != NULL) {
-                hashMap_remove(refsMap, (void*)refId);
-                int size = hashMap_size(refsMap);
-                if (size == 0) {
-                    hashMap_destroy(refsMap, false, false);
-                    hashMap_remove(registry->serviceReferences, bundle);
-                }
-                serviceRegistry_setReferenceStatus(registry, reference, true);
-            } else {
-                fw_log(registry->framework->logger, CELIX_LOG_LEVEL_ERROR, "Cannot find reference %p in serviceReferences map",
-                       reference);
+        if (ref != NULL) {
+            hashMap_remove(refsMap, (void*)refId);
+            int size = hashMap_size(refsMap);
+            if (size == 0) {
+                hashMap_destroy(refsMap, false, false);
+                hashMap_remove(registry->serviceReferences, bundle);
             }
+        } else {
+            fw_log(registry->framework->logger, CELIX_LOG_LEVEL_FATAL, "Cannot find reference %p in serviceReferences map",
+                   reference);
         }
-    } else {
-        serviceRegistry_logIllegalReference(registry, reference, refStatus);
     }
     celixThreadRwlock_unlock(&registry->lock);
 
     return status;
 }
 
-static celix_status_t serviceRegistry_setReferenceStatus(service_registry_pt registry, service_reference_pt reference,
-                                                  bool deleted) {
-    //precondition write locked on registry->lock
-    if (registry->checkDeletedReferences) {
-        hashMap_put(registry->deletedServiceReferences, reference, (void *) deleted);
-    }
-    return CELIX_SUCCESS;
-}
-
-static void serviceRegistry_logIllegalReference(service_registry_pt registry __attribute__((unused)), service_reference_pt reference,
-                                                   reference_status_t refStatus) {
-    fw_log(registry->framework->logger, CELIX_LOG_LEVEL_ERROR,
-           "Error handling service reference %p, status is %i",reference, refStatus);
-}
-
-static celix_status_t serviceRegistry_checkReference(service_registry_pt registry, service_reference_pt ref,
-                                              reference_status_t *out) {
-    //precondition read or write locked on registry->lock
-    celix_status_t status = CELIX_SUCCESS;
-
-    if (registry->checkDeletedReferences) {
-        reference_status_t refStatus = REF_UNKNOWN;
-
-        if (hashMap_containsKey(registry->deletedServiceReferences, ref)) {
-            bool deleted = (bool) hashMap_get(registry->deletedServiceReferences, ref);
-            refStatus = deleted ? REF_DELETED : REF_ACTIVE;
-        }
-
-        *out = refStatus;
-    } else {
-        *out = REF_ACTIVE;
-    }
-
-    return status;
-}
-
 static void serviceRegistry_logWarningServiceReferenceUsageCount(service_registry_pt registry __attribute__((unused)), bundle_pt bundle, service_reference_pt ref, size_t usageCount, size_t refCount) {
     if (usageCount > 0) {
         fw_log(registry->framework->logger, CELIX_LOG_LEVEL_WARNING, "Service Reference destroyed with usage count is %zu, expected 0. Look for missing bundleContext_ungetService calls.", usageCount);
@@ -602,8 +535,6 @@ celix_status_t serviceRegistry_clearReferencesFor(service_registry_pt registry,
             while (!destroyed) {
                 serviceReference_release(ref, &destroyed);
             }
-            serviceRegistry_setReferenceStatus(registry, ref, true);
-
         }
         hashMapIterator_destroy(iter);
         hashMap_destroy(refsMap, false, false);
@@ -648,78 +579,53 @@ celix_status_t serviceRegistry_getService(service_registry_pt registry, bundle_p
     size_t count = 0;
     const void *service = NULL;
     bool valid = false;
-    reference_status_t refStatus;
 
 
     celixThreadRwlock_readLock(&registry->lock);
-    serviceRegistry_checkReference(registry, reference, &refStatus);
-    if (refStatus == REF_ACTIVE) {
-        serviceReference_getServiceRegistration(reference, &registration);
-        valid = serviceRegistration_isValid(registration);
-        if (valid) {
-            serviceRegistration_retain(registration);
-            serviceReference_increaseUsage(reference, &count);
-        } else {
-            *out = NULL; //invalid service registration
-        }
+    serviceReference_getServiceRegistration(reference, &registration);
+    valid = serviceRegistration_isValid(registration);
+    if (valid) {
+        serviceRegistration_retain(registration);
+        serviceReference_increaseUsage(reference, &count);
+    } else {
+        *out = NULL; //invalid service registration
     }
     celixThreadRwlock_unlock(&registry->lock);
 
-    if (valid && refStatus == REF_ACTIVE) {
-        if (count == 1) {
-            serviceRegistration_getService(registration, bundle, &service);
-            serviceReference_setService(reference, service);
-        }
-        serviceRegistration_release(registration);
-
-        /* NOTE the out argument of sr_getService should be 'const void**'
-           To ensure backwards compatibility a cast is made instead.
-        */
-        serviceReference_getService(reference, (void **)out);
-    } else {
-        if (refStatus != REF_ACTIVE) {
-            serviceRegistry_logIllegalReference(registry, reference, refStatus);
-        }
-        status = CELIX_BUNDLE_EXCEPTION;
+    if (count == 1) {
+        serviceRegistration_getService(registration, bundle, &service);
+        serviceReference_setService(reference, service);
     }
+    serviceRegistration_release(registration);
+
+    /* NOTE the out argument of sr_getService should be 'const void**'
+       To ensure backwards compatibility a cast is made instead.
+    */
+    serviceReference_getService(reference, (void **)out);
 
 	return status;
 }
 
 celix_status_t serviceRegistry_ungetService(service_registry_pt registry, bundle_pt bundle, service_reference_pt reference, bool *result) {
-	celix_status_t status = CELIX_SUCCESS;
     service_registration_pt reg = NULL;
     const void *service = NULL;
     size_t count = 0;
-    celix_status_t subStatus = CELIX_SUCCESS;
-    reference_status_t refStatus;
 
     celixThreadRwlock_readLock(&registry->lock);
-    serviceRegistry_checkReference(registry, reference, &refStatus);
     celixThreadRwlock_unlock(&registry->lock);
 
-    if (refStatus == REF_ACTIVE) {
-        subStatus = serviceReference_decreaseUsage(reference, &count);
-        if (count == 0) {
-            /*NOTE the argument service of sr_getService should be 'const void**'
-              To ensure backwards compatibility a cast is made instead.
-              */
-            serviceReference_getService(reference, (void**)&service);
-            serviceReference_getServiceRegistration(reference, &reg);
-            if (reg != NULL) {
-                serviceRegistration_ungetService(reg, bundle, &service);
-            }
+    celix_status_t status = serviceReference_decreaseUsage(reference, &count);
+    if (count == 0) {
+        /*NOTE the argument service of sr_getService should be 'const void**'
+          To ensure backwards compatibility a cast is made instead.
+          */
+        serviceReference_getService(reference, (void**)&service);
+        serviceReference_getServiceRegistration(reference, &reg);
+        if (reg != NULL) {
+            serviceRegistration_ungetService(reg, bundle, &service);
         }
-    } else {
-        serviceRegistry_logIllegalReference(registry, reference, refStatus);
-        status = CELIX_BUNDLE_EXCEPTION;
     }
 
-    if (result) {
-        *result = (subStatus == CELIX_SUCCESS);
-    }
-
-
 	return status;
 }
 
@@ -1085,7 +991,7 @@ celix_status_t celix_serviceRegistry_addServiceListener(celix_service_registry_t
     celixThreadMutex_create(&entry->mutex, NULL);
     celixThreadCondition_init(&entry->cond, NULL);
 
-    celix_array_list_t *registrations =  celix_arrayList_create();
+    celix_array_list_t *references =  celix_arrayList_create();
 
     celixThreadRwlock_writeLock(&registry->lock);
     celix_arrayList_add(registry->serviceListeners, entry); //use count 1
@@ -1101,7 +1007,9 @@ celix_status_t celix_serviceRegistry_addServiceListener(celix_service_registry_t
             if (celix_filter_match(filter, props)) {
                 serviceRegistration_retain(registration);
                 long svcId = serviceRegistration_getServiceId(registration);
-                celix_arrayList_add(registrations, registration);
+                service_reference_pt ref = NULL;
+                serviceRegistry_getServiceReference_internal(registry, bundle, registration, &ref);
+                celix_arrayList_add(references, ref);
                 //update pending register event count
                 celix_increasePendingRegisteredEvent(registry, svcId);
             }
@@ -1114,22 +1022,23 @@ celix_status_t celix_serviceRegistry_addServiceListener(celix_service_registry_t
     //The handling of pending registered events is to ensure that the UNREGISTERING event is always
     //after the 1 or 2 REGISTERED events.
 
-    for (int i = 0; i < celix_arrayList_size(registrations); ++i) {
-        service_registration_pt reg = celix_arrayList_get(registrations, i);
-        long svcId = serviceRegistration_getServiceId(reg);
-        service_reference_pt ref = NULL;
-        serviceRegistry_getServiceReference_internal(registry, bundle, reg, &ref);
+    for (int i = 0; i < celix_arrayList_size(references); ++i) {
+        service_reference_pt ref = celix_arrayList_get(references, i);
+        long svcId = serviceReference_getServiceId(ref);
         celix_service_event_t event;
         event.reference = ref;
         event.type = OSGI_FRAMEWORK_SERVICE_EVENT_REGISTERED;
         listener->serviceChanged(listener->handle, &event);
         serviceReference_release(ref, NULL);
+
+        service_registration_t* reg = NULL;
+        serviceReference_getServiceRegistration(ref, &reg);
         serviceRegistration_release(reg);
 
         //update pending register event count
         celix_decreasePendingRegisteredEvent(registry, svcId);
     }
-    celix_arrayList_destroy(registrations);
+    celix_arrayList_destroy(references);
 
     serviceRegistry_callHooksForListenerFilter(registry, bundle, entry->filter, false);
 
diff --git a/libs/framework/src/service_registry_private.h b/libs/framework/src/service_registry_private.h
index a51bb90..f181731 100644
--- a/libs/framework/src/service_registry_private.h
+++ b/libs/framework/src/service_registry_private.h
@@ -62,9 +62,6 @@ struct celix_serviceRegistry {
 	hash_map_t *serviceRegistrations; //key = bundle (reg owner), value = list ( registration )
 	hash_map_t *serviceReferences; //key = bundle, value = map (key = serviceId, value = reference)
 
-	bool checkDeletedReferences; //If enabled. check if provided service references are still valid
-	hash_map_t *deletedServiceReferences; //key = ref pointer, value = bool
-
 	long nextServiceId;
 
 	celix_array_list_t *listenerHooks; //celix_service_registry_listener_hook_entry_t*
@@ -103,12 +100,6 @@ typedef struct celix_service_registry_service_listener_entry {
     unsigned int useCount;
 } celix_service_registry_service_listener_entry_t;
 
-typedef enum reference_status_enum {
-	REF_ACTIVE,
-	REF_DELETED,
-	REF_UNKNOWN
-} reference_status_t;
-
 struct usageCount {
 	unsigned int count;
 	service_reference_pt reference;
diff --git a/libs/framework/src/service_tracker.c b/libs/framework/src/service_tracker.c
index 8775c23..112c077 100644
--- a/libs/framework/src/service_tracker.c
+++ b/libs/framework/src/service_tracker.c
@@ -34,14 +34,14 @@
 #include "bundle_context_private.h"
 #include "celix_array_list.h"
 
-static celix_status_t serviceTracker_track(celix_service_tracker_instance_t *tracker, service_reference_pt reference, celix_service_event_t *event);
-static celix_status_t serviceTracker_untrack(celix_service_tracker_instance_t *tracker, service_reference_pt reference, celix_service_event_t *event);
-static void serviceTracker_untrackTracked(celix_service_tracker_instance_t *tracker, celix_tracked_entry_t *tracked);
-static celix_status_t serviceTracker_invokeAddingService(celix_service_tracker_instance_t *tracker, service_reference_pt ref, void **svcOut);
-static celix_status_t serviceTracker_invokeAddService(celix_service_tracker_instance_t *tracker, celix_tracked_entry_t *tracked);
-static celix_status_t serviceTracker_invokeRemovingService(celix_service_tracker_instance_t *tracker, celix_tracked_entry_t *tracked);
+static celix_status_t serviceTracker_track(service_tracker_t *tracker, service_reference_pt reference, celix_service_event_t *event);
+static celix_status_t serviceTracker_untrack(service_tracker_t *tracker, service_reference_pt reference);
+static void serviceTracker_untrackTracked(service_tracker_t *tracker, celix_tracked_entry_t *tracked);
+static celix_status_t serviceTracker_invokeAddingService(service_tracker_t *tracker, service_reference_pt ref, void **svcOut);
+static celix_status_t serviceTracker_invokeAddService(service_tracker_t *tracker, celix_tracked_entry_t *tracked);
+static celix_status_t serviceTracker_invokeRemovingService(service_tracker_t *tracker, celix_tracked_entry_t *tracked);
 static void serviceTracker_checkAndInvokeSetService(void *handle, void *highestSvc, const properties_t *props, const bundle_t *bnd);
-static bool serviceTracker_useHighestRankingServiceInternal(celix_service_tracker_instance_t *instance,
+static bool serviceTracker_useHighestRankingServiceInternal(service_tracker_t *tracker,
                                                             const char *serviceName /*sanity*/,
                                                             void *callbackHandle,
                                                             void (*use)(void *handle, void *svc),
@@ -56,18 +56,6 @@ static void* shutdownServiceTrackerInstanceHandler(void *data);
 
 static void serviceTracker_serviceChanged(void *handle, celix_service_event_t *event);
 
-static celix_thread_once_t g_once = CELIX_THREAD_ONCE_INIT; //once for g_shutdownMutex, g_shutdownCond
-
-
-static celix_thread_mutex_t g_shutdownMutex;
-static celix_thread_cond_t g_shutdownCond;
-static celix_array_list_t *g_shutdownInstances = NULL; //value = celix_service_tracker_instance -> used for syncing with shutdown threads
-
-
-static void serviceTracker_once(void) {
-    celixThreadMutex_create(&g_shutdownMutex, NULL);
-    celixThreadCondition_init(&g_shutdownCond, NULL);
-}
 
 static inline celix_tracked_entry_t* tracked_create(service_reference_pt ref, void *svc, celix_properties_t *props, celix_bundle_t *bnd) {
     celix_tracked_entry_t *tracked = calloc(1, sizeof(*tracked));
@@ -128,332 +116,272 @@ celix_status_t serviceTracker_create(bundle_context_pt context, const char * ser
 	return status;
 }
 
-celix_status_t serviceTracker_createWithFilter(bundle_context_pt context, const char * filter, service_tracker_customizer_pt customizer, service_tracker_pt *tracker) {
-	celix_status_t status = CELIX_SUCCESS;
-	*tracker = (service_tracker_pt) calloc(1, sizeof(**tracker));
-	if (!*tracker) {
-		status = CELIX_ENOMEM;
-	} else {
-		(*tracker)->context = context;
-		(*tracker)->filter = strdup(filter);
-        (*tracker)->customizer = customizer;
-	}
+celix_status_t serviceTracker_createWithFilter(bundle_context_pt context, const char * filter, service_tracker_customizer_pt customizer, service_tracker_pt *out) {
+	service_tracker_t* tracker = calloc(1, sizeof(*tracker));
+	*out = tracker;
+    tracker->context = context;
+    tracker->filter = celix_utils_strdup(filter);
+    tracker->customizer = *customizer;
+    free(customizer);
 
-	framework_logIfError(celix_frameworkLogger_globalLogger(), status, NULL, "Cannot create service tracker [filter=%s]", filter);
+    celixThreadMutex_create(&tracker->closeSync.mutex, NULL);
+    celixThreadCondition_init(&tracker->closeSync.cond, NULL);
 
-	return status;
+    celixThreadMutex_create(&tracker->mutex, NULL);
+    celixThreadCondition_init(&tracker->cond, NULL);
+    tracker->trackedServices = celix_arrayList_create();
+    tracker->untrackingServices = celix_arrayList_create();
+
+    celixThreadMutex_create(&tracker->mutex, NULL);
+    tracker->currentHighestServiceId = -1;
+
+    tracker->listener.handle = tracker;
+    tracker->listener.serviceChanged = (void *) serviceTracker_serviceChanged;
+
+    tracker->callbackHandle = tracker->callbackHandle;
+
+    tracker->add = tracker->add;
+    tracker->addWithProperties = tracker->addWithProperties;
+    tracker->addWithOwner = tracker->addWithOwner;
+    tracker->set = tracker->set;
+    tracker->setWithProperties = tracker->setWithProperties;
+    tracker->setWithOwner = tracker->setWithOwner;
+    tracker->remove = tracker->remove;
+    tracker->removeWithProperties = tracker->removeWithProperties;
+    tracker->removeWithOwner = tracker->removeWithOwner;
+
+	return CELIX_SUCCESS;
 }
 
 celix_status_t serviceTracker_destroy(service_tracker_pt tracker) {
-    if (tracker->customizer != NULL) {
-	    serviceTrackerCustomizer_destroy(tracker->customizer);
-	}
-
     free(tracker->serviceName);
 	free(tracker->filter);
-	free(tracker);
-
+    celixThreadMutex_destroy(&tracker->closeSync.mutex);
+    celixThreadCondition_destroy(&tracker->closeSync.cond);
+    celixThreadMutex_destroy(&tracker->mutex);
+    celixThreadCondition_destroy(&tracker->cond);
+    celix_arrayList_destroy(tracker->trackedServices);
+    celix_arrayList_destroy(tracker->untrackingServices);
+    free(tracker);
 	return CELIX_SUCCESS;
 }
 
 celix_status_t serviceTracker_open(service_tracker_pt tracker) {
-    celix_service_listener_t *listener = NULL;
-    celix_service_tracker_instance_t *instance = NULL;
-    celix_status_t status = CELIX_SUCCESS;
-
-    bool addListener = false;
-
-    celixThreadRwlock_writeLock(&tracker->instanceLock);
-    if (tracker->instance == NULL) {
-        instance = calloc(1, sizeof(*instance));
-        instance->context = tracker->context;
-
-        instance->closing = false;
-        instance->activeServiceChangeCalls = 0;
-        celixThreadMutex_create(&instance->closingLock, NULL);
-        celixThreadCondition_init(&instance->activeServiceChangeCallsCond, NULL);
-
-
-        celixThreadRwlock_create(&instance->lock, NULL);
-        instance->trackedServices = celix_arrayList_create();
-
-        celixThreadMutex_create(&instance->mutex, NULL);
-        instance->currentHighestServiceId = -1;
-
-        instance->listener.handle = instance;
-        instance->listener.serviceChanged = (void *) serviceTracker_serviceChanged;
-        listener = &instance->listener;
-
-        instance->callbackHandle = tracker->callbackHandle;
-        instance->filter = strdup(tracker->filter);
-        if (tracker->customizer != NULL) {
-            memcpy(&instance->customizer, tracker->customizer, sizeof(instance->customizer));
-        }
-        instance->add = tracker->add;
-        instance->addWithProperties = tracker->addWithProperties;
-        instance->addWithOwner = tracker->addWithOwner;
-        instance->set = tracker->set;
-        instance->setWithProperties = tracker->setWithProperties;
-        instance->setWithOwner = tracker->setWithOwner;
-        instance->remove = tracker->remove;
-        instance->removeWithProperties = tracker->removeWithProperties;
-        instance->removeWithOwner = tracker->removeWithOwner;
-
-        tracker->instance = instance;
-
-        addListener = true;
-    } else {
-        //already open
-        framework_logIfError(tracker->context->framework->logger, status, NULL, "Tracker already open");
+    celixThreadMutex_lock(&tracker->mutex);
+    bool alreadyOpen = tracker->open;
+    tracker->open = true;
+    celixThreadMutex_unlock(&tracker->mutex);
 
+    if (!alreadyOpen) {
+        bundleContext_addServiceListener(tracker->context, &tracker->listener, tracker->filter);
     }
-    celixThreadRwlock_unlock(&tracker->instanceLock);
-
-	if (addListener) {
-	    bundleContext_addServiceListener(tracker->context, listener, tracker->filter);
-	}
 	return CELIX_SUCCESS;
 }
 
-celix_status_t serviceTracker_close(service_tracker_pt tracker) {
+celix_status_t serviceTracker_close(service_tracker_t* tracker) {
 	//put all tracked entries in tmp array list, so that the untrack (etc) calls are not blocked.
     //set state to close to prevent service listener events
 
-    celixThreadRwlock_writeLock(&tracker->instanceLock);
-    celix_service_tracker_instance_t *instance = tracker->instance;
-    tracker->instance = NULL;
-    if (instance != NULL) {
-        celixThreadMutex_lock(&instance->closingLock);
-        //prevent service listener events
-        instance->closing = true;
-        celixThreadMutex_unlock(&instance->closingLock);
-    }
-    celixThreadRwlock_unlock(&tracker->instanceLock);
-
-    if (instance != NULL) {
-        celixThreadRwlock_writeLock(&instance->lock);
-        unsigned int size = celix_arrayList_size(instance->trackedServices);
-        if(size > 0) {
-            celix_tracked_entry_t *trackedEntries[size];
-            for (unsigned int i = 0u; i < size; i++) {
-                trackedEntries[i] = (celix_tracked_entry_t *) arrayList_get(instance->trackedServices, i);
-            }
-            arrayList_clear(instance->trackedServices);
-            celixThreadRwlock_unlock(&instance->lock);
+    celixThreadMutex_lock(&tracker->mutex);
+    bool open = tracker->open;
+    tracker->open = false;
+    celixThreadMutex_unlock(&tracker->mutex);
 
-            //loop trough tracked entries an untrack
-            for (unsigned int i = 0u; i < size; i++) {
-                serviceTracker_untrackTracked(instance, trackedEntries[i]);
+    if (!open) {
+        return CELIX_SUCCESS;
+    }
+
+
+    //indicate that the service tracking is closing and wait for the still pending service registration events.
+    celixThreadMutex_lock(&tracker->closeSync.mutex);
+    tracker->closeSync.closing = true;
+    while (tracker->closeSync.activeCalls > 0) {
+        celixThreadCondition_wait(&tracker->closeSync.cond, &tracker->closeSync.mutex);
+    }
+    celixThreadMutex_unlock(&tracker->closeSync.mutex);
+
+    int nrOfTrackedEntries;
+    do {
+        celixThreadMutex_lock(&tracker->mutex);
+        celix_tracked_entry_t* tracked = NULL;
+        nrOfTrackedEntries = celix_arrayList_size(tracker->trackedServices);
+        if (nrOfTrackedEntries > 0) {
+            tracked = celix_arrayList_get(tracker->trackedServices, 0);
+            celix_arrayList_removeAt(tracker->trackedServices, 0);
+            celix_arrayList_add(tracker->untrackingServices, tracked);
+        }
+        celixThreadMutex_unlock(&tracker->mutex);
+
+        if (tracked != NULL) {
+            int currentSize = nrOfTrackedEntries - 1;
+            if (currentSize == 0) {
+                serviceTracker_checkAndInvokeSetService(tracker, NULL, NULL, NULL);
+            } else {
+                serviceTracker_useHighestRankingServiceInternal(tracker, tracked->serviceName, tracker, NULL, NULL, serviceTracker_checkAndInvokeSetService);
             }
-        } else {
-            celixThreadRwlock_unlock(&instance->lock);
-        }
 
-        celixThreadMutex_lock(&instance->closingLock);
-        while (instance->activeServiceChangeCalls > 0) {
-            celixThreadCondition_wait(&instance->activeServiceChangeCallsCond, &instance->closingLock);
+            serviceTracker_untrackTracked(tracker, tracked);
+            celixThreadMutex_lock(&tracker->mutex);
+            celix_arrayList_remove(tracker->untrackingServices, tracked);
+            celixThreadCondition_broadcast(&tracker->cond);
+            celixThreadMutex_unlock(&tracker->mutex);
         }
-        celixThreadMutex_unlock(&instance->closingLock);
 
 
-#ifdef CELIX_SERVICE_TRACKER_USE_SHUTDOWN_THREAD
-        //NOTE Separate thread is needed to prevent deadlock where closing is triggered from a serviceChange event and the
-        // untrack -> removeServiceListener will try to remove a service listener which is being invoked and is the
-        // actual thread calling the removeServiceListener.
-        //
-        // This can be detached -> because service listener events are ignored (closing=true) and so no callbacks
-        // are made back to the celix framework / tracker owner.
-        serviceTracker_addInstanceFromShutdownList(instance);
-        celix_thread_t localThread;
-        celixThread_create(&localThread, NULL, shutdownServiceTrackerInstanceHandler, instance);
-        celixThread_detach(localThread);
-#else
-        fw_removeServiceListener(instance->context->framework, instance->context->bundle, &instance->listener);
-
-        celixThreadMutex_destroy(&instance->closingLock);
-        celixThreadCondition_destroy(&instance->activeServiceChangeCallsCond);
-        celixThreadMutex_destroy(&instance->mutex);
-        celixThreadRwlock_destroy(&instance->lock);
-        celix_arrayList_destroy(instance->trackedServices);
-        free(instance->filter);
-        free(instance);
-#endif
-    }
+        celixThreadMutex_lock(&tracker->mutex);
+        nrOfTrackedEntries = celix_arrayList_size(tracker->trackedServices);
+        celixThreadMutex_unlock(&tracker->mutex);
+    } while (nrOfTrackedEntries > 0);
+
+
+    fw_removeServiceListener(tracker->context->framework, tracker->context->bundle, &tracker->listener);
 
 	return CELIX_SUCCESS;
 }
 
-service_reference_pt serviceTracker_getServiceReference(service_tracker_pt tracker) {
+service_reference_pt serviceTracker_getServiceReference(service_tracker_t* tracker) {
     //TODO deprecated warning -> not locked
-	celix_tracked_entry_t *tracked;
+
     service_reference_pt result = NULL;
-	unsigned int i;
-
-	celixThreadRwlock_readLock(&tracker->instanceLock);
-	celix_service_tracker_instance_t *instance = tracker->instance;
-	if (instance != NULL) {
-        celixThreadRwlock_readLock(&instance->lock);
-        for (i = 0; i < arrayList_size(instance->trackedServices); ++i) {
-            tracked = (celix_tracked_entry_t *) arrayList_get(instance->trackedServices, i);
-            result = tracked->reference;
-            break;
-        }
-        celixThreadRwlock_unlock(&instance->lock);
+
+    celixThreadMutex_lock(&tracker->mutex);
+    for (int i = 0; i < celix_arrayList_size(tracker->trackedServices); ++i) {
+        celix_tracked_entry_t *tracked = celix_arrayList_get(tracker->trackedServices, i);
+        result = tracked->reference;
+        break;
     }
-    celixThreadRwlock_unlock(&tracker->instanceLock);
+    celixThreadMutex_unlock(&tracker->mutex);
 
 	return result;
 }
 
-array_list_pt serviceTracker_getServiceReferences(service_tracker_pt tracker) {
+array_list_pt serviceTracker_getServiceReferences(service_tracker_t* tracker) {
     //TODO deprecated warning -> not locked
-    celix_tracked_entry_t *tracked;
-	unsigned int i;
 	array_list_pt references = NULL;
 	arrayList_create(&references);
 
-    celixThreadRwlock_readLock(&tracker->instanceLock);
-	celix_service_tracker_instance_t *instance = tracker->instance;
-	if (instance != NULL) {
-        celixThreadRwlock_readLock(&instance->lock);
-        for (i = 0; i < arrayList_size(instance->trackedServices); i++) {
-            tracked = (celix_tracked_entry_t*) arrayList_get(instance->trackedServices, i);
-            arrayList_add(references, tracked->reference);
-        }
-        celixThreadRwlock_unlock(&instance->lock);
+    celixThreadMutex_lock(&tracker->mutex);
+    for (int i = 0; i < celix_arrayList_size(tracker->trackedServices); i++) {
+        celix_tracked_entry_t *tracked = celix_arrayList_get(tracker->trackedServices, i);
+        arrayList_add(references, tracked->reference);
     }
-    celixThreadRwlock_unlock(&tracker->instanceLock);
+    celixThreadMutex_unlock(&tracker->mutex);
 
 	return references;
 }
 
-void *serviceTracker_getService(service_tracker_pt tracker) {
+void *serviceTracker_getService(service_tracker_t* tracker) {
     //TODO deprecated warning -> not locked
-    celix_tracked_entry_t* tracked;
     void *service = NULL;
-	unsigned int i;
-
-	celixThreadRwlock_readLock(&tracker->instanceLock);
-	celix_service_tracker_instance_t *instance = tracker->instance;
-	if (instance != NULL) {
-        celixThreadRwlock_readLock(&instance->lock);
-        for (i = 0; i < arrayList_size(instance->trackedServices); i++) {
-            tracked = (celix_tracked_entry_t*) arrayList_get(instance->trackedServices, i);
-            service = tracked->service;
-            break;
-        }
-        celixThreadRwlock_unlock(&instance->lock);
+
+    celixThreadMutex_lock(&tracker->mutex);
+    for (int i = 0; i < celix_arrayList_size(tracker->trackedServices); i++) {
+        celix_tracked_entry_t* tracked = celix_arrayList_get(tracker->trackedServices, i);
+        service = tracked->service;
+        break;
     }
-    celixThreadRwlock_unlock(&tracker->instanceLock);
+    celixThreadMutex_unlock(&tracker->mutex);
 
     return service;
 }
 
-array_list_pt serviceTracker_getServices(service_tracker_pt tracker) {
+array_list_pt serviceTracker_getServices(service_tracker_t* tracker) {
     //TODO deprecated warning -> not locked, also make locked variant
-    celix_tracked_entry_t *tracked;
-	unsigned int i;
 	array_list_pt references = NULL;
 	arrayList_create(&references);
 
-    celixThreadRwlock_readLock(&tracker->instanceLock);
-    celix_service_tracker_instance_t *instance = tracker->instance;
-    if (instance != NULL) {
-        celixThreadRwlock_readLock(&instance->lock);
-        for (i = 0; i < arrayList_size(instance->trackedServices); i++) {
-            tracked = (celix_tracked_entry_t *) arrayList_get(instance->trackedServices, i);
-            arrayList_add(references, tracked->service);
-        }
-        celixThreadRwlock_unlock(&instance->lock);
+    celixThreadMutex_lock(&tracker->mutex);
+    for (int i = 0; i < celix_arrayList_size(tracker->trackedServices); i++) {
+        celix_tracked_entry_t *tracked = celix_arrayList_get(tracker->trackedServices, i);
+        arrayList_add(references, tracked->service);
     }
-    celixThreadRwlock_unlock(&tracker->instanceLock);
+    celixThreadMutex_unlock(&tracker->mutex);
 
     return references;
 }
 
 void *serviceTracker_getServiceByReference(service_tracker_pt tracker, service_reference_pt reference) {
     //TODO deprecated warning -> not locked
-    celix_tracked_entry_t *tracked;
     void *service = NULL;
-	unsigned int i;
-
-    celixThreadRwlock_readLock(&tracker->instanceLock);
-    celix_service_tracker_instance_t *instance = tracker->instance;
-    if (instance != NULL) {
-        celixThreadRwlock_readLock(&instance->lock);
-        for (i = 0; i < arrayList_size(instance->trackedServices); i++) {
-            bool equals = false;
-            tracked = (celix_tracked_entry_t *) arrayList_get(instance->trackedServices, i);
-            serviceReference_equals(reference, tracked->reference, &equals);
-            if (equals) {
-                service = tracked->service;
-                break;
-            }
+
+    celixThreadMutex_lock(&tracker->mutex);
+    for (int i = 0; i < celix_arrayList_size(tracker->trackedServices); i++) {
+        bool equals = false;
+        celix_tracked_entry_t *tracked = celix_arrayList_get(tracker->trackedServices, i);
+        serviceReference_equals(reference, tracked->reference, &equals);
+        if (equals) {
+            service = tracked->service;
+            break;
         }
-        celixThreadRwlock_unlock(&instance->lock);
     }
-    celixThreadRwlock_unlock(&tracker->instanceLock);
+    celixThreadMutex_unlock(&tracker->mutex);
 
 	return service;
 }
 
 static void serviceTracker_serviceChanged(void *handle, celix_service_event_t *event) {
-	celix_service_tracker_instance_t *instance = handle;
+    service_tracker_t *tracker = handle;
 
-    celixThreadMutex_lock(&instance->closingLock);
-    bool closing = instance->closing;
+    celixThreadMutex_lock(&tracker->closeSync.mutex);
+    bool closing = tracker->closeSync.closing;
     if (!closing) {
-        instance->activeServiceChangeCalls += 1;
+        tracker->closeSync.activeCalls += 1;
     }
-    celixThreadMutex_unlock(&instance->closingLock);
+    celixThreadMutex_unlock(&tracker->closeSync.mutex);
 
     if (!closing) {
         switch (event->type) {
             case OSGI_FRAMEWORK_SERVICE_EVENT_REGISTERED:
-                serviceTracker_track(instance, event->reference, event);
+                serviceTracker_track(tracker, event->reference, event);
                 break;
             case OSGI_FRAMEWORK_SERVICE_EVENT_MODIFIED:
-                serviceTracker_track(instance, event->reference, event);
+                serviceTracker_track(tracker, event->reference, event);
                 break;
             case OSGI_FRAMEWORK_SERVICE_EVENT_UNREGISTERING:
-                serviceTracker_untrack(instance, event->reference, event);
+                serviceTracker_untrack(tracker, event->reference);
                 break;
-            case OSGI_FRAMEWORK_SERVICE_EVENT_MODIFIED_ENDMATCH:
-                //TODO
+            default:
+                //nop
                 break;
         }
-        celixThreadMutex_lock(&instance->closingLock);
-        assert(instance->activeServiceChangeCalls > 0);
-        instance->activeServiceChangeCalls -= 1;
-        if (instance->activeServiceChangeCalls == 0) {
-            celixThreadCondition_broadcast(&instance->activeServiceChangeCallsCond);
+    } else {
+        switch (event->type) {
+            case OSGI_FRAMEWORK_SERVICE_EVENT_UNREGISTERING:
+                //untrack the service reference, because after this call the registration can be gone
+                serviceTracker_untrack(tracker, event->reference);
+                break;
+            default:
+                //nop
+                break;
         }
-        celixThreadMutex_unlock(&instance->closingLock);
+    }
+
+    if (!closing) {
+        celixThreadMutex_lock(&tracker->closeSync.mutex);
+        tracker->closeSync.activeCalls -= 1;
+        celixThreadCondition_broadcast(&tracker->closeSync.cond);
+        celixThreadMutex_unlock(&tracker->closeSync.mutex);
     }
 }
 
 size_t serviceTracker_nrOfTrackedServices(service_tracker_t *tracker) {
-    size_t result = 0;
-    celixThreadRwlock_readLock(&tracker->instanceLock);
-    celixThreadRwlock_readLock(&tracker->instance->lock);
-    result = (size_t) arrayList_size(tracker->instance->trackedServices);
-    celixThreadRwlock_unlock(&tracker->instance->lock);
-    celixThreadRwlock_unlock(&tracker->instanceLock);
+    celixThreadMutex_lock(&tracker->mutex);
+    size_t result = (size_t) arrayList_size(tracker->trackedServices);
+    celixThreadMutex_unlock(&tracker->mutex);
     return result;
 }
 
-static celix_status_t serviceTracker_track(celix_service_tracker_instance_t *instance, service_reference_pt reference, celix_service_event_t *event) {
+static celix_status_t serviceTracker_track(service_tracker_t* tracker, service_reference_pt reference, celix_service_event_t *event) {
 	celix_status_t status = CELIX_SUCCESS;
 
     celix_tracked_entry_t *found = NULL;
-    unsigned int i;
-    
-    bundleContext_retainServiceReference(instance->context, reference);
 
-    celixThreadRwlock_readLock(&instance->lock);
-    for (i = 0; i < arrayList_size(instance->trackedServices); i++) {
+    bundleContext_retainServiceReference(tracker->context, reference);
+
+    celixThreadMutex_lock(&tracker->mutex);
+    for (int i = 0; i < celix_arrayList_size(tracker->trackedServices); i++) {
         bool equals = false;
-        celix_tracked_entry_t *visit = (celix_tracked_entry_t*) arrayList_get(instance->trackedServices, i);
+        celix_tracked_entry_t *visit = (celix_tracked_entry_t*) arrayList_get(tracker->trackedServices, i);
         serviceReference_equals(reference, visit->reference, &equals);
         if (equals) {
             //NOTE it is possible to get two REGISTERED events, second one can be ignored.
@@ -461,12 +389,12 @@ static celix_status_t serviceTracker_track(celix_service_tracker_instance_t *ins
             break;
         }
     }
-    celixThreadRwlock_unlock(&instance->lock);
+    celixThreadMutex_unlock(&tracker->mutex);
 
     if (found == NULL) {
         //NEW entry
         void *service = NULL;
-        status = serviceTracker_invokeAddingService(instance, reference, &service);
+        status = serviceTracker_invokeAddingService(tracker, reference, &service);
         if (status == CELIX_SUCCESS && service != NULL) {
             assert(reference != NULL);
 
@@ -482,22 +410,24 @@ static celix_status_t serviceTracker_track(celix_service_tracker_instance_t *ins
 
             celix_tracked_entry_t *tracked = tracked_create(reference, service, props, bnd); //use count 1
 
-            celixThreadRwlock_writeLock(&instance->lock);
-            arrayList_add(instance->trackedServices, tracked);
-            celixThreadRwlock_unlock(&instance->lock);
+            celixThreadMutex_lock(&tracker->mutex);
+            arrayList_add(tracker->trackedServices, tracked);
+            celixThreadMutex_unlock(&tracker->mutex);
 
-            serviceTracker_invokeAddService(instance, tracked);
-            serviceTracker_useHighestRankingServiceInternal(instance, tracked->serviceName, instance, NULL, NULL, serviceTracker_checkAndInvokeSetService);
+            serviceTracker_invokeAddService(tracker, tracked);
+            serviceTracker_useHighestRankingServiceInternal(tracker, tracked->serviceName, tracker, NULL, NULL, serviceTracker_checkAndInvokeSetService);
         }
+    } else {
+        bundleContext_ungetServiceReference(tracker->context, reference);
     }
 
-    framework_logIfError(instance->context->framework->logger, status, NULL, "Cannot track reference");
+    framework_logIfError(tracker->context->framework->logger, status, NULL, "Cannot track reference");
 
     return status;
 }
 
 static void serviceTracker_checkAndInvokeSetService(void *handle, void *highestSvc, const celix_properties_t *props, const celix_bundle_t *bnd) {
-    celix_service_tracker_instance_t *instance = handle;
+    service_tracker_t *tracker = handle;
     bool update = false;
     long svcId = -1;
     if (highestSvc == NULL) {
@@ -507,117 +437,131 @@ static void serviceTracker_checkAndInvokeSetService(void *handle, void *highestS
         svcId = celix_properties_getAsLong(props, OSGI_FRAMEWORK_SERVICE_ID, -1);
     }
     if (svcId >= 0) {
-        celixThreadMutex_lock(&instance->mutex);
-        if (instance->currentHighestServiceId != svcId) {
-            instance->currentHighestServiceId = svcId;
+        celixThreadMutex_lock(&tracker->mutex);
+        if (tracker->currentHighestServiceId != svcId) {
+            tracker->currentHighestServiceId = svcId;
             update = true;
             //update
         }
-        celixThreadMutex_unlock(&instance->mutex);
+        celixThreadMutex_unlock(&tracker->mutex);
     }
     if (update) {
-        void *h = instance->callbackHandle;
-        if (instance->set != NULL) {
-            instance->set(h, highestSvc);
+        void *h = tracker->callbackHandle;
+        if (tracker->set != NULL) {
+            tracker->set(h, highestSvc);
         }
-        if (instance->setWithProperties != NULL) {
-            instance->setWithProperties(h, highestSvc, props);
+        if (tracker->setWithProperties != NULL) {
+            tracker->setWithProperties(h, highestSvc, props);
         }
-        if (instance->setWithOwner != NULL) {
-            instance->setWithOwner(h, highestSvc, props, bnd);
+        if (tracker->setWithOwner != NULL) {
+            tracker->setWithOwner(h, highestSvc, props, bnd);
         }
     }
 }
 
-static celix_status_t serviceTracker_invokeAddService(celix_service_tracker_instance_t *instance, celix_tracked_entry_t *tracked) {
+static celix_status_t serviceTracker_invokeAddService(service_tracker_t *tracker, celix_tracked_entry_t *tracked) {
     celix_status_t status = CELIX_SUCCESS;
 
     void *customizerHandle = NULL;
     added_callback_pt function = NULL;
 
-    serviceTrackerCustomizer_getHandle(&instance->customizer, &customizerHandle);
-    serviceTrackerCustomizer_getAddedFunction(&instance->customizer, &function);
+    serviceTrackerCustomizer_getHandle(&tracker->customizer, &customizerHandle);
+    serviceTrackerCustomizer_getAddedFunction(&tracker->customizer, &function);
     if (function != NULL) {
         function(customizerHandle, tracked->reference, tracked->service);
     }
 
-    void *handle = instance->callbackHandle;
-    if (instance->add != NULL) {
-        instance->add(handle, tracked->service);
+    void *handle = tracker->callbackHandle;
+    if (tracker->add != NULL) {
+        tracker->add(handle, tracked->service);
     }
-    if (instance->addWithProperties != NULL) {
-        instance->addWithProperties(handle, tracked->service, tracked->properties);
+    if (tracker->addWithProperties != NULL) {
+        tracker->addWithProperties(handle, tracked->service, tracked->properties);
     }
-    if (instance->addWithOwner != NULL) {
-        instance->addWithOwner(handle, tracked->service, tracked->properties, tracked->serviceOwner);
+    if (tracker->addWithOwner != NULL) {
+        tracker->addWithOwner(handle, tracked->service, tracked->properties, tracked->serviceOwner);
     }
     return status;
 }
 
-static celix_status_t serviceTracker_invokeAddingService(celix_service_tracker_instance_t *instance, service_reference_pt ref, void **svcOut) {
+static celix_status_t serviceTracker_invokeAddingService(service_tracker_t *tracker, service_reference_pt ref, void **svcOut) {
 	celix_status_t status = CELIX_SUCCESS;
 
     void *handle = NULL;
     adding_callback_pt function = NULL;
 
-    status = serviceTrackerCustomizer_getHandle(&instance->customizer, &handle);
+    status = serviceTrackerCustomizer_getHandle(&tracker->customizer, &handle);
 
     if (status == CELIX_SUCCESS) {
-        status = serviceTrackerCustomizer_getAddingFunction(&instance->customizer, &function);
+        status = serviceTrackerCustomizer_getAddingFunction(&tracker->customizer, &function);
     }
 
     if (status == CELIX_SUCCESS && function != NULL) {
         status = function(handle, ref, svcOut);
     } else if (status == CELIX_SUCCESS) {
-        status = bundleContext_getService(instance->context, ref, svcOut);
+        status = bundleContext_getService(tracker->context, ref, svcOut);
     }
 
-    framework_logIfError(instance->context->framework->logger, status, NULL, "Cannot handle addingService");
+    framework_logIfError(tracker->context->framework->logger, status, NULL, "Cannot handle addingService");
 
     return status;
 }
 
-static celix_status_t serviceTracker_untrack(celix_service_tracker_instance_t* instance, service_reference_pt reference, celix_service_event_t *event) {
+static celix_status_t serviceTracker_untrack(service_tracker_t* tracker, service_reference_pt reference) {
     celix_status_t status = CELIX_SUCCESS;
     celix_tracked_entry_t *remove = NULL;
-    unsigned int i;
-    unsigned int size;
     const char *serviceName = NULL;
 
-    celixThreadRwlock_writeLock(&instance->lock);
-    size = arrayList_size(instance->trackedServices);
-    for (i = 0; i < size; i++) {
+    celixThreadMutex_lock(&tracker->mutex);
+    for (int i = 0; i < celix_arrayList_size(tracker->trackedServices); i++) {
         bool equals;
-        celix_tracked_entry_t *tracked = (celix_tracked_entry_t*) arrayList_get(instance->trackedServices, i);
+        celix_tracked_entry_t *tracked = (celix_tracked_entry_t*) arrayList_get(tracker->trackedServices, i);
         serviceName = tracked->serviceName;
         serviceReference_equals(reference, tracked->reference, &equals);
         if (equals) {
             remove = tracked;
             //remove from trackedServices to prevent getting this service, but don't destroy yet, can be in use
-            arrayList_remove(instance->trackedServices, i);
+            celix_arrayList_removeAt(tracker->trackedServices, i);
+            celix_arrayList_add(tracker->untrackingServices, remove);
             break;
         }
     }
-    size = arrayList_size(instance->trackedServices); //updated size
-    celixThreadRwlock_unlock(&instance->lock);
+    int size = celix_arrayList_size(tracker->trackedServices); //updated size
+    celixThreadMutex_unlock(&tracker->mutex);
 
-    if (size == 0) {
-        serviceTracker_checkAndInvokeSetService(instance, NULL, NULL, NULL);
-    } else {
-        serviceTracker_useHighestRankingServiceInternal(instance, serviceName, instance, NULL, NULL, serviceTracker_checkAndInvokeSetService);
+    if (remove != NULL) {
+        if (size == 0) {
+            serviceTracker_checkAndInvokeSetService(tracker, NULL, NULL, NULL);
+        } else {
+            serviceTracker_useHighestRankingServiceInternal(tracker, serviceName, tracker, NULL, NULL, serviceTracker_checkAndInvokeSetService);
+        }
     }
 
-    serviceTracker_untrackTracked(instance, remove);
+    //note also syncing on untracking entries, to ensure no untrack is parallel in progress
+    if (remove != NULL) {
+        serviceTracker_untrackTracked(tracker, remove);
+        celixThreadMutex_lock(&tracker->mutex);
+        celix_arrayList_remove(tracker->untrackingServices, remove);
+        celixThreadMutex_unlock(&tracker->mutex);
+    } else {
+        //ensure no untrack is still happening (to ensure it safe to unregister service)
+        celixThreadMutex_lock(&tracker->mutex);
+        while (celix_arrayList_size(tracker->untrackingServices) > 0) {
+            celixThreadCondition_wait(&tracker->cond, &tracker->mutex);
+        }
+        celixThreadMutex_unlock(&tracker->mutex);
+    }
 
-    framework_logIfError(instance->context->framework->logger, status, NULL, "Cannot untrack reference");
+    framework_logIfError(tracker->context->framework->logger, status, NULL, "Cannot untrack reference");
 
     return status;
 }
 
-static void serviceTracker_untrackTracked(celix_service_tracker_instance_t *instance, celix_tracked_entry_t *tracked) {
+static void serviceTracker_untrackTracked(service_tracker_t *tracker, celix_tracked_entry_t *tracked) {
     if (tracked != NULL) {
-        serviceTracker_invokeRemovingService(instance, tracked);
-        bundleContext_ungetServiceReference(instance->context, tracked->reference);
+        serviceTracker_invokeRemovingService(tracker, tracked);
+
+        bundleContext_ungetServiceReference(tracker->context, tracked->reference);
         tracked_release(tracked);
 
         //Wait till the useCount is 0, because the untrack should only return if the service is not used anymore.
@@ -625,37 +569,37 @@ static void serviceTracker_untrackTracked(celix_service_tracker_instance_t *inst
     }
 }
 
-static celix_status_t serviceTracker_invokeRemovingService(celix_service_tracker_instance_t *instance, celix_tracked_entry_t *tracked) {
+static celix_status_t serviceTracker_invokeRemovingService(service_tracker_t *tracker, celix_tracked_entry_t *tracked) {
     celix_status_t status = CELIX_SUCCESS;
     bool ungetSuccess = true;
 
     void *customizerHandle = NULL;
     removed_callback_pt function = NULL;
 
-    serviceTrackerCustomizer_getHandle(&instance->customizer, &customizerHandle);
-    serviceTrackerCustomizer_getRemovedFunction(&instance->customizer, &function);
+    serviceTrackerCustomizer_getHandle(&tracker->customizer, &customizerHandle);
+    serviceTrackerCustomizer_getRemovedFunction(&tracker->customizer, &function);
 
     if (function != NULL) {
         status = function(customizerHandle, tracked->reference, tracked->service);
     }
 
-    void *handle = instance->callbackHandle;
-    if (instance->remove != NULL) {
-        instance->remove(handle, tracked->service);
+    void *handle = tracker->callbackHandle;
+    if (tracker->remove != NULL) {
+        tracker->remove(handle, tracked->service);
     }
-    if (instance->addWithProperties != NULL) {
-        instance->removeWithProperties(handle, tracked->service, tracked->properties);
+    if (tracker->addWithProperties != NULL) {
+        tracker->removeWithProperties(handle, tracked->service, tracked->properties);
     }
-    if (instance->removeWithOwner != NULL) {
-        instance->removeWithOwner(handle, tracked->service, tracked->properties, tracked->serviceOwner);
+    if (tracker->removeWithOwner != NULL) {
+        tracker->removeWithOwner(handle, tracked->service, tracked->properties, tracked->serviceOwner);
     }
 
     if (status == CELIX_SUCCESS) {
-        status = bundleContext_ungetService(instance->context, tracked->reference, &ungetSuccess);
+        status = bundleContext_ungetService(tracker->context, tracked->reference, &ungetSuccess);
     }
 
     if (!ungetSuccess) {
-        framework_log(instance->context->framework->logger, CELIX_LOG_LEVEL_ERROR, __FUNCTION__, __BASE_FILE__, __LINE__, "Error ungetting service");
+        framework_log(tracker->context->framework->logger, CELIX_LOG_LEVEL_ERROR, __FUNCTION__, __BASE_FILE__, __LINE__, "Error ungetting service");
         status = CELIX_BUNDLE_EXCEPTION;
     }
 
@@ -706,7 +650,19 @@ celix_service_tracker_t* celix_serviceTracker_createWithOptions(
             tracker->addWithOwner = opts->addWithOwner;
             tracker->removeWithOwner = opts->removeWithOwner;
 
-            celixThreadRwlock_create(&tracker->instanceLock, NULL);
+            celixThreadMutex_create(&tracker->closeSync.mutex, NULL);
+            celixThreadCondition_init(&tracker->closeSync.cond, NULL);
+
+            celixThreadMutex_create(&tracker->mutex, NULL);
+            celixThreadCondition_init(&tracker->cond, NULL);
+            tracker->trackedServices = celix_arrayList_create();
+            tracker->untrackingServices = celix_arrayList_create();
+
+            celixThreadMutex_create(&tracker->mutex, NULL);
+            tracker->currentHighestServiceId = -1;
+
+            tracker->listener.handle = tracker;
+            tracker->listener.serviceChanged = (void *) serviceTracker_serviceChanged;
 
             //setting lang
             const char *lang = opts->filter.serviceLanguage;
@@ -721,7 +677,7 @@ celix_service_tracker_t* celix_serviceTracker_createWithOptions(
                 if(status != CELIX_SUCCESS) {
                     framework_log(tracker->context->framework->logger, CELIX_LOG_LEVEL_ERROR, __FUNCTION__, __BASE_FILE__, __LINE__,
                     "Error incorrect version range.");
-                    celixThreadRwlock_destroy(&tracker->instanceLock);
+                    free(tracker->serviceName);
                     free(tracker);
                     return NULL;
                 }
@@ -730,7 +686,7 @@ celix_service_tracker_t* celix_serviceTracker_createWithOptions(
                 if(versionRange == NULL) {
                     framework_log(tracker->context->framework->logger, CELIX_LOG_LEVEL_ERROR, __FUNCTION__, __BASE_FILE__, __LINE__,
                                   "Error creating LDAP filter.");
-                    celixThreadRwlock_destroy(&tracker->instanceLock);
+                    free(tracker->serviceName);
                     free(tracker);
                     return NULL;
                 }
@@ -759,7 +715,7 @@ celix_service_tracker_t* celix_serviceTracker_createWithOptions(
                 }
             }
 
-            if(versionRange != NULL){
+            if (versionRange != NULL){
                 free(versionRange);
             }
 
@@ -778,7 +734,7 @@ void celix_serviceTracker_destroy(celix_service_tracker_t *tracker) {
     }
 }
 
-static bool serviceTracker_useHighestRankingServiceInternal(celix_service_tracker_instance_t *instance,
+static bool serviceTracker_useHighestRankingServiceInternal(service_tracker_t *tracker,
                                                             const char *serviceName /*sanity*/,
                                                             void *callbackHandle,
                                                             void (*use)(void *handle, void *svc),
@@ -791,11 +747,11 @@ static bool serviceTracker_useHighestRankingServiceInternal(celix_service_tracke
     unsigned int i;
 
     //first lock tracker and get highest tracked entry
-    celixThreadRwlock_readLock(&instance->lock);
-    unsigned int size = arrayList_size(instance->trackedServices);
+    celixThreadMutex_lock(&tracker->mutex);
+    unsigned int size = arrayList_size(tracker->trackedServices);
 
     for (i = 0; i < size; i++) {
-        tracked = (celix_tracked_entry_t *) arrayList_get(instance->trackedServices, i);
+        tracked = (celix_tracked_entry_t *) arrayList_get(tracker->trackedServices, i);
         if (serviceName != NULL && tracked->serviceName != NULL && strncmp(tracked->serviceName, serviceName, 10*1024) == 0) {
             const char *val = properties_getWithDefault(tracked->properties, OSGI_FRAMEWORK_SERVICE_RANKING, "0");
             long rank = strtol(val, NULL, 10);
@@ -809,7 +765,7 @@ static bool serviceTracker_useHighestRankingServiceInternal(celix_service_tracke
         tracked_retain(highest);
     }
     //unlock tracker so that the tracked entry can be removed from the trackedServices list if unregistered.
-    celixThreadRwlock_unlock(&instance->lock);
+    celixThreadMutex_unlock(&tracker->mutex);
 
     if (highest != NULL) {
         //got service, call, decrease use count an signal useCond after.
@@ -843,11 +799,7 @@ bool celix_serviceTracker_useHighestRankingService(
     struct timespec start, now;
     clock_gettime(CLOCK_MONOTONIC, &start);
     do {
-        celixThreadRwlock_readLock(&tracker->instanceLock);
-        if (tracker->instance != NULL) {
-            called = serviceTracker_useHighestRankingServiceInternal(tracker->instance, serviceName, callbackHandle, use, useWithProperties, useWithOwner);
-        }
-        celixThreadRwlock_unlock(&tracker->instanceLock);
+        called = serviceTracker_useHighestRankingServiceInternal(tracker, serviceName, callbackHandle, use, useWithProperties, useWithOwner);
 
         if (waitTimeoutInSeconds <= 0) {
             break;
@@ -871,141 +823,34 @@ size_t celix_serviceTracker_useServices(
         void (*useWithProperties)(void *handle, void *svc, const celix_properties_t *props),
         void (*useWithOwner)(void *handle, void *svc, const celix_properties_t *props, const celix_bundle_t *owner)) {
     size_t count = 0;
-    celixThreadRwlock_readLock(&tracker->instanceLock);
-    celix_service_tracker_instance_t *instance = tracker->instance;
-    if (instance != NULL) {
-        //first lock tracker, get tracked entries and increase use count
-        celixThreadRwlock_readLock(&instance->lock);
-        int size = celix_arrayList_size(instance->trackedServices);
-        count = (size_t)size;
-        celix_tracked_entry_t *entries[size];
-        for (int i = 0; i < size; i++) {
-            celix_tracked_entry_t *tracked = (celix_tracked_entry_t *) arrayList_get(instance->trackedServices, i);
-            tracked_retain(tracked);
-            entries[i] = tracked;
-        }
-        //unlock tracker so that the tracked entry can be removed from the trackedServices list if unregistered.
-        celixThreadRwlock_unlock(&instance->lock);
-
-        //then use entries and decrease use count
-        for (int i = 0; i < size; i++) {
-            celix_tracked_entry_t *entry = entries[i];
-            //got service, call, decrease use count an signal useCond after.
-            if (use != NULL) {
-                use(callbackHandle, entry->service);
-            }
-            if (useWithProperties != NULL) {
-                useWithProperties(callbackHandle, entry->service, entry->properties);
-            }
-            if (useWithOwner != NULL) {
-                useWithOwner(callbackHandle, entry->service, entry->properties, entry->serviceOwner);
-            }
-
-            tracked_release(entry);
-        }
+    //first lock tracker, get tracked entries and increase use count
+    celixThreadMutex_lock(&tracker->mutex);
+    int size = celix_arrayList_size(tracker->trackedServices);
+    count = (size_t)size;
+    celix_tracked_entry_t *entries[size];
+    for (int i = 0; i < size; i++) {
+        celix_tracked_entry_t *tracked = (celix_tracked_entry_t *) arrayList_get(tracker->trackedServices, i);
+        tracked_retain(tracked);
+        entries[i] = tracked;
     }
-    celixThreadRwlock_unlock(&tracker->instanceLock);
-    return count;
-}
+    //unlock tracker so that the tracked entry can be removed from the trackedServices list if unregistered.
+    celixThreadMutex_unlock(&tracker->mutex);
 
-void celix_serviceTracker_syncForFramework(void *fw) {
-    celixThread_once(&g_once, serviceTracker_once);
-    celixThreadMutex_lock(&g_shutdownMutex);
-    size_t count = 0;
-    do {
-        count = 0;
-        if (g_shutdownInstances != NULL) {
-            for (int i = 0; i < celix_arrayList_size(g_shutdownInstances); ++i) {
-                celix_service_tracker_instance_t *instance = celix_arrayList_get(g_shutdownInstances, i);
-                if (instance->context->framework == fw) {
-                    count += 1;
-                }
-            }
-        }
-        if (count > 0) {
-            pthread_cond_wait(&g_shutdownCond, &g_shutdownMutex);
+    //then use entries and decrease use count
+    for (int i = 0; i < size; i++) {
+        celix_tracked_entry_t *entry = entries[i];
+        //got service, call, decrease use count an signal useCond after.
+        if (use != NULL) {
+            use(callbackHandle, entry->service);
         }
-    } while (count > 0);
-
-    if (g_shutdownInstances != NULL && celix_arrayList_size(g_shutdownInstances) == 0) {
-        celix_arrayList_destroy(g_shutdownInstances);
-        g_shutdownInstances = NULL;
-    }
-    celixThreadMutex_unlock(&g_shutdownMutex);
-}
-
-void celix_serviceTracker_syncForContext(void *ctx) {
-    celixThread_once(&g_once, serviceTracker_once);
-    celixThreadMutex_lock(&g_shutdownMutex);
-    size_t count;
-    do {
-        count = 0;
-        if (g_shutdownInstances != NULL) {
-            for (int i = 0; i < celix_arrayList_size(g_shutdownInstances); ++i) {
-                celix_service_tracker_instance_t *instance = celix_arrayList_get(g_shutdownInstances, i);
-                if (instance->context == ctx) {
-                    count += 1;
-                }
-            }
+        if (useWithProperties != NULL) {
+            useWithProperties(callbackHandle, entry->service, entry->properties);
         }
-        if (count > 0) {
-            pthread_cond_wait(&g_shutdownCond, &g_shutdownMutex);
+        if (useWithOwner != NULL) {
+            useWithOwner(callbackHandle, entry->service, entry->properties, entry->serviceOwner);
         }
-    } while (count > 0);
 
-    if (g_shutdownInstances != NULL && celix_arrayList_size(g_shutdownInstances) == 0) {
-        celix_arrayList_destroy(g_shutdownInstances);
-        g_shutdownInstances = NULL;
+        tracked_release(entry);
     }
-    celixThreadMutex_unlock(&g_shutdownMutex);
-}
-
-#ifdef CELIX_SERVICE_TRACKER_USE_SHUTDOWN_THREAD
-static void serviceTracker_addInstanceFromShutdownList(celix_service_tracker_instance_t *instance) {
-    celixThread_once(&g_once, serviceTracker_once);
-    celixThreadMutex_lock(&g_shutdownMutex);
-    if (g_shutdownInstances == NULL) {
-        g_shutdownInstances = celix_arrayList_create();
-    }
-    celix_arrayList_add(g_shutdownInstances, instance);
-    celixThreadMutex_unlock(&g_shutdownMutex);
-}
-
-static void serviceTracker_remInstanceFromShutdownList(celix_service_tracker_instance_t *instance) {
-    celixThread_once(&g_once, serviceTracker_once);
-    celixThreadMutex_lock(&g_shutdownMutex);
-    if (g_shutdownInstances != NULL) {
-        size_t size = celix_arrayList_size(g_shutdownInstances);
-        for (size_t i = 0; i < size; ++i) {
-            celix_array_list_entry_t entry;
-            memset(&entry, 0, sizeof(entry));
-            entry.voidPtrVal = instance;
-            celix_arrayList_removeEntry(g_shutdownInstances, entry);
-        }
-        if (celix_arrayList_size(g_shutdownInstances) == 0) {
-            celix_arrayList_destroy(g_shutdownInstances);
-            g_shutdownInstances = NULL;
-        }
-        celixThreadCondition_broadcast(&g_shutdownCond);
-    }
-    celixThreadMutex_unlock(&g_shutdownMutex);
-}
-
-static void* shutdownServiceTrackerInstanceHandler(void *data) {
-    celix_service_tracker_instance_t *instance = data;
-
-    fw_removeServiceListener(instance->context->framework, instance->context->bundle, &instance->listener);
-
-    celixThreadMutex_destroy(&instance->closingLock);
-    celixThreadCondition_destroy(&instance->activeServiceChangeCallsCond);
-    celixThreadMutex_destroy(&instance->mutex);
-    celixThreadRwlock_destroy(&instance->lock);
-    celix_arrayList_destroy(instance->trackedServices);
-    free(instance->filter);
-
-    serviceTracker_remInstanceFromShutdownList(instance);
-    free(instance);
-
-    return NULL;
-}
-#endif
\ No newline at end of file
+    return count;
+}
\ No newline at end of file
diff --git a/libs/framework/src/service_tracker_private.h b/libs/framework/src/service_tracker_private.h
index 47b8fa7..4bc1b27 100644
--- a/libs/framework/src/service_tracker_private.h
+++ b/libs/framework/src/service_tracker_private.h
@@ -23,51 +23,14 @@
 #include "service_tracker.h"
 #include "celix_types.h"
 
-//instance for an active per open statement and removed per close statement
-typedef struct celix_service_tracker_instance {
-	celix_thread_mutex_t closingLock; //projects closing and activeServiceChangeCalls
-	bool closing; //when true the service tracker instance is being closed and all calls from the service listener are ignored
-	size_t activeServiceChangeCalls;
-	celix_thread_cond_t activeServiceChangeCallsCond;
-
-	bundle_context_t *context;
-	char * filter;
-
-	service_tracker_customizer_t customizer;
-	celix_service_listener_t listener;
-
-	void *callbackHandle;
-
-	void (*set)(void *handle, void *svc); //highest ranking
-	void (*add)(void *handle, void *svc);
-	void (*remove)(void *handle, void *svc);
-	void (*modified)(void *handle, void *svc);
-
-	void (*setWithProperties)(void *handle, void *svc, const properties_t *props); //highest ranking
-	void (*addWithProperties)(void *handle, void *svc, const properties_t *props);
-	void (*removeWithProperties)(void *handle, void *svc, const properties_t *props);
-	void (*modifiedWithProperties)(void *handle, void *svc, const properties_t *props);
-
-	void (*setWithOwner)(void *handle, void *svc, const properties_t *props, const bundle_t *owner); //highest ranking
-	void (*addWithOwner)(void *handle, void *svc, const properties_t *props, const bundle_t *owner);
-	void (*removeWithOwner)(void *handle, void *svc, const properties_t *props, const bundle_t *owner);
-	void (*modifiedWithOwner)(void *handle, void *svc, const properties_t *props, const bundle_t *owner);
-
-	celix_thread_rwlock_t lock; //projects trackedServices
-	array_list_t *trackedServices;
-
-	celix_thread_mutex_t mutex; //protect current highest service id
-	long currentHighestServiceId;
-
-	celix_thread_t shutdownThread; //will be created when this instance is shutdown
-} celix_service_tracker_instance_t;
-
 struct celix_serviceTracker {
 	bundle_context_t *context;
 
 	char* serviceName;
 	char* filter;
-	service_tracker_customizer_t *customizer;
+
+    service_tracker_customizer_t customizer;
+    celix_service_listener_t listener;
 
 	void *callbackHandle;
 
@@ -86,9 +49,19 @@ struct celix_serviceTracker {
 	void (*removeWithOwner)(void *handle, void *svc, const properties_t *props, const bundle_t *owner);
 	void (*modifiedWithOwner)(void *handle, void *svc, const properties_t *props, const bundle_t *owner);
 
-	celix_thread_rwlock_t instanceLock;
-	celix_service_tracker_instance_t *instance; /*NULL -> close, !NULL->open*/
-
+    struct {
+        celix_thread_mutex_t mutex; //projects below
+        celix_thread_cond_t cond;
+        bool closing; //if closing is true, no new service registrations are added to the serice tracker
+        size_t activeCalls; // >0 if there is still a serviceChange for a service registration call active
+    } closeSync;
+
+    celix_thread_mutex_t mutex; //projects below
+    celix_thread_cond_t  cond;
+    celix_array_list_t *trackedServices;
+    celix_array_list_t *untrackingServices;
+    bool open;
+    long currentHighestServiceId;
 };
 
 typedef struct celix_tracked_entry {