in libs/framework/src/framework.c [297:389]
celix_status_t framework_destroy(framework_pt framework) {
celix_status_t status = CELIX_SUCCESS;
celixThreadMutex_lock(&framework->shutdown.mutex);
bool shutdownInitialized = framework->shutdown.initialized;
celixThreadMutex_unlock(&framework->shutdown.mutex);
if (shutdownInitialized) {
framework_waitForStop(framework);
}
celix_serviceRegistry_destroy(framework->registry);
for (int i = 0; i < celix_arrayList_size(framework->installedBundles.entries); ++i) {
celix_bundle_entry_t*entry = celix_arrayList_get(framework->installedBundles.entries, i);
celixThreadMutex_lock(&entry->useMutex);
size_t count = entry->useCount;
celixThreadMutex_unlock(&entry->useMutex);
bundle_t *bnd = entry->bnd;
if (count > 0) {
const char *bndName = celix_bundle_getSymbolicName(bnd);
fw_log(framework->logger, CELIX_LOG_LEVEL_FATAL, "Cannot destroy framework. The use count of bundle %s (bnd id %li) is not 0, but %zu.", bndName, entry->bndId, count);
celixThreadMutex_lock(&framework->dispatcher.mutex);
int nrOfRequests = framework->dispatcher.eventQueueSize + celix_arrayList_size(framework->dispatcher.dynamicEventQueue);
celixThreadMutex_unlock(&framework->dispatcher.mutex);
fw_log(framework->logger, CELIX_LOG_LEVEL_WARNING, "nr of request left: %i (should be 0).", nrOfRequests);
}
fw_bundleEntry_destroy(entry, true);
bool systemBundle = false;
bundle_isSystemBundle(bnd, &systemBundle);
if (systemBundle) {
bundle_context_t *context = celix_bundle_getContext(framework->bundle);
bundleContext_destroy(context);
}
celix_bundle_archive_t *archive = NULL;
bundle_getArchive(bnd, &archive);
celix_module_t* module = NULL;
bundle_getCurrentModule(bnd, &module);
if (!systemBundle && module) {
celix_module_closeLibraries(module);
}
if (archive) {
celix_bundleArchive_destroy(archive);
}
bundle_destroy(bnd);
}
celix_arrayList_destroy(framework->installedBundles.entries);
celixThreadMutex_destroy(&framework->installedBundles.mutex);
celixThreadMutex_destroy(&framework->installLock);
//teardown framework bundle lifecycle handling
assert(celix_arrayList_size(framework->bundleLifecycleHandling.bundleLifecycleHandlers) == 0);
celix_arrayList_destroy(framework->bundleLifecycleHandling.bundleLifecycleHandlers);
celixThreadMutex_destroy(&framework->bundleLifecycleHandling.mutex);
celixThreadCondition_destroy(&framework->bundleLifecycleHandling.cond);
hashMap_destroy(framework->installRequestMap, false, false);
if (framework->bundleListeners) {
celix_arrayList_destroy(framework->bundleListeners);
}
if (framework->frameworkListeners) {
celix_arrayList_destroy(framework->frameworkListeners);
}
assert(celix_arrayList_size(framework->dispatcher.dynamicEventQueue) == 0);
celix_arrayList_destroy(framework->dispatcher.dynamicEventQueue);
assert(celix_longHashMap_size(framework->dispatcher.scheduledEvents) == 0);
celix_longHashMap_destroy(framework->dispatcher.scheduledEvents);
celix_bundleCache_destroy(framework->cache);
celixThreadCondition_destroy(&framework->dispatcher.cond);
celixThreadMutex_destroy(&framework->frameworkListenersLock);
celixThreadMutex_destroy(&framework->bundleListenerLock);
celixThreadMutex_destroy(&framework->dispatcher.mutex);
celixThreadMutex_destroy(&framework->shutdown.mutex);
celixThreadCondition_destroy(&framework->shutdown.cond);
celix_frameworkLogger_destroy(framework->logger);
celix_properties_destroy(framework->configurationMap);
free(framework->dispatcher.eventQueue);
free(framework);
return status;
}