static celix_status_t celix_framework_stopBundleEntryInternal()

in libs/framework/src/framework.c [2021:2128]


static celix_status_t celix_framework_stopBundleEntryInternal(celix_framework_t* framework,
                                                              celix_bundle_entry_t* bndEntry) {
    celix_bundle_activator_t *activator = NULL;
    bundle_context_t *context = NULL;
    bool wasActive = false;
    char *error = NULL;

    celix_status_t status = CELIX_SUCCESS;
    celix_bundle_state_e state = celix_bundle_getState(bndEntry->bnd);
    switch (state) {
    case CELIX_BUNDLE_STATE_UNKNOWN:
        status = CELIX_ILLEGAL_STATE;
        error = "state is unknown";
        break;
    case CELIX_BUNDLE_STATE_UNINSTALLED:
        status = CELIX_ILLEGAL_STATE;
        error = "bundle is uninstalled";
        break;
    case CELIX_BUNDLE_STATE_STARTING:
        status = CELIX_BUNDLE_EXCEPTION;
        error = "bundle is starting";
        break;
    case CELIX_BUNDLE_STATE_STOPPING:
        status = CELIX_BUNDLE_EXCEPTION;
        error = "bundle is stopping";
        break;
    case CELIX_BUNDLE_STATE_INSTALLED:
    case CELIX_BUNDLE_STATE_RESOLVED:
        break;
    case CELIX_BUNDLE_STATE_ACTIVE:
        wasActive = true;
        break;
    }


    if (status == CELIX_SUCCESS && wasActive) {
        CELIX_DO_IF(status, bundle_setState(bndEntry->bnd, CELIX_BUNDLE_STATE_STOPPING));
        CELIX_DO_IF(status, fw_fireBundleEvent(framework, OSGI_FRAMEWORK_BUNDLE_EVENT_STOPPING, bndEntry));
        activator = bundle_getActivator(bndEntry->bnd);

        if (status == CELIX_SUCCESS) {
            context = celix_bundle_getContext(bndEntry->bnd);
            if (activator->stop != NULL) {
                status = CELIX_DO_IF(status, activator->stop(activator->userData, context));
                if (status == CELIX_SUCCESS) {
                    celix_dependency_manager_t *mng = celix_bundleContext_getDependencyManager(context);
                    celix_dependencyManager_removeAllComponents(mng);
                }
            }
        }
        if (status == CELIX_SUCCESS) {
            if (activator->destroy != NULL) {
                status = CELIX_DO_IF(status, activator->destroy(activator->userData, context));
            }
        }

        if (bndEntry->bndId >= CELIX_FRAMEWORK_BUNDLE_ID) {
            //framework and "normal" bundle
            celix_framework_waitUntilNoEventsForBnd(framework, bndEntry->bndId);
            celix_bundleContext_cleanup(bndEntry->bnd->context);
        }
        if (bndEntry->bndId > CELIX_FRAMEWORK_BUNDLE_ID) {
            //"normal" bundle
            if (status == CELIX_SUCCESS) {
                celix_module_t* module = NULL;
                const char *symbolicName = NULL;
                long id = 0;
                bundle_getCurrentModule(bndEntry->bnd, &module);
                module_getSymbolicName(module, &symbolicName);
                bundle_getBundleId(bndEntry->bnd, &id);
            }

            if (context != NULL) {
                status = CELIX_DO_IF(status, bundleContext_destroy(context));
                CELIX_DO_IF(status, celix_bundle_setContext(bndEntry->bnd, NULL));
            }

            status = CELIX_DO_IF(status, bundle_setState(bndEntry->bnd, CELIX_BUNDLE_STATE_RESOLVED));
            CELIX_DO_IF(status, fw_fireBundleEvent(framework, OSGI_FRAMEWORK_BUNDLE_EVENT_STOPPED, bndEntry));
        } else if (bndEntry->bndId == CELIX_FRAMEWORK_BUNDLE_ID) {
            //framework bundle
            status = CELIX_DO_IF(status, bundle_setState(bndEntry->bnd, CELIX_BUNDLE_STATE_RESOLVED));
            CELIX_DO_IF(status, fw_fireBundleEvent(framework, OSGI_FRAMEWORK_BUNDLE_EVENT_STOPPED, bndEntry));
        }

        if (activator != NULL) {
            bundle_setActivator(bndEntry->bnd, NULL);
            free(activator);
        }
    }

    if (status != CELIX_SUCCESS) {
        celix_module_t* module = NULL;
        const char *symbolicName = NULL;
        long id = 0;
        bundle_getCurrentModule(bndEntry->bnd, &module);
        module_getSymbolicName(module, &symbolicName);
        bundle_getBundleId(bndEntry->bnd, &id);
        if (error != NULL) {
            fw_logCode(framework->logger, CELIX_LOG_LEVEL_ERROR, status, "Cannot stop bundle: %s [%ld]; cause: %s", symbolicName, id, error);
        } else {
            fw_logCode(framework->logger, CELIX_LOG_LEVEL_ERROR, status, "Cannot stop bundle: %s [%ld]", symbolicName, id);
        }
    } else {
        fw_fireBundleEvent(framework, OSGI_FRAMEWORK_BUNDLE_EVENT_STOPPED, bndEntry);
    }
    return status;
}