celix_status_t framework_destroy()

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;
}