Return-Path: X-Original-To: archive-asf-public-internal@cust-asf2.ponee.io Delivered-To: archive-asf-public-internal@cust-asf2.ponee.io Received: from cust-asf.ponee.io (cust-asf.ponee.io [163.172.22.183]) by cust-asf2.ponee.io (Postfix) with ESMTP id C67FC200D44 for ; Mon, 20 Nov 2017 21:33:05 +0100 (CET) Received: by cust-asf.ponee.io (Postfix) id C5285160BE1; Mon, 20 Nov 2017 20:33:05 +0000 (UTC) Delivered-To: archive-asf-public@cust-asf.ponee.io Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by cust-asf.ponee.io (Postfix) with SMTP id A98EE160C1F for ; Mon, 20 Nov 2017 21:33:01 +0100 (CET) Received: (qmail 60549 invoked by uid 500); 20 Nov 2017 20:33:00 -0000 Mailing-List: contact commits-help@celix.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@celix.apache.org Delivered-To: mailing list commits@celix.apache.org Received: (qmail 59506 invoked by uid 99); 20 Nov 2017 20:32:59 -0000 Received: from git1-us-west.apache.org (HELO git1-us-west.apache.org) (140.211.11.23) by apache.org (qpsmtpd/0.29) with ESMTP; Mon, 20 Nov 2017 20:32:59 +0000 Received: by git1-us-west.apache.org (ASF Mail Server at git1-us-west.apache.org, from userid 33) id B9BC6F5F78; Mon, 20 Nov 2017 20:32:58 +0000 (UTC) Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: pnoltes@apache.org To: commits@celix.apache.org Date: Mon, 20 Nov 2017 20:33:20 -0000 Message-Id: In-Reply-To: References: X-Mailer: ASF-Git Admin Mailer Subject: [23/46] celix git commit: CELIX-417: Initial refactoring for CMake usage archived-at: Mon, 20 Nov 2017 20:33:06 -0000 http://git-wip-us.apache.org/repos/asf/celix/blob/a1c30887/framework/private/src/framework.c ---------------------------------------------------------------------- diff --git a/framework/private/src/framework.c b/framework/private/src/framework.c deleted file mode 100644 index b1db384..0000000 --- a/framework/private/src/framework.c +++ /dev/null @@ -1,2620 +0,0 @@ -/** - *Licensed to the Apache Software Foundation (ASF) under one - *or more contributor license agreements. See the NOTICE file - *distributed with this work for additional information - *regarding copyright ownership. The ASF licenses this file - *to you under the Apache License, Version 2.0 (the - *"License"); you may not use this file except in compliance - *with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - *Unless required by applicable law or agreed to in writing, - *software distributed under the License is distributed on an - *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - *specific language governing permissions and limitations - *under the License. - */ -/* - * framework.c - * - * \date Mar 23, 2010 - * \author Apache Celix Project Team - * \copyright Apache License, Version 2.0 - */ -#include -#include -#include -#include -#include "celixbool.h" - -#ifdef _WIN32 -#include -#include -#else -#include -#endif -#include - -#include "framework_private.h" -#include "constants.h" -#include "resolver.h" -#include "utils.h" -#include "linked_list_iterator.h" -#include "service_reference_private.h" -#include "listener_hook_service.h" -#include "service_registration_private.h" - -typedef celix_status_t (*create_function_pt)(bundle_context_pt context, void **userData); -typedef celix_status_t (*start_function_pt)(void * handle, bundle_context_pt context); -typedef celix_status_t (*stop_function_pt)(void * handle, bundle_context_pt context); -typedef celix_status_t (*destroy_function_pt)(void * handle, bundle_context_pt context); - -struct activator { - void * userData; - start_function_pt start; - stop_function_pt stop; - destroy_function_pt destroy; -}; - -celix_status_t framework_setBundleStateAndNotify(framework_pt framework, bundle_pt bundle, int state); -celix_status_t framework_markBundleResolved(framework_pt framework, module_pt module); - -celix_status_t framework_acquireBundleLock(framework_pt framework, bundle_pt bundle, int desiredStates); -bool framework_releaseBundleLock(framework_pt framework, bundle_pt bundle); - -bool framework_acquireGlobalLock(framework_pt framework); -celix_status_t framework_releaseGlobalLock(framework_pt framework); - -celix_status_t framework_acquireInstallLock(framework_pt framework, const char* location); -celix_status_t framework_releaseInstallLock(framework_pt framework, const char* location); - -long framework_getNextBundleId(framework_pt framework); - -celix_status_t fw_installBundle2(framework_pt framework, bundle_pt * bundle, long id, const char * location, const char *inputFile, bundle_archive_pt archive); - -celix_status_t fw_refreshBundles(framework_pt framework, bundle_pt bundles[], int size); -celix_status_t fw_refreshBundle(framework_pt framework, bundle_pt bundle); - -celix_status_t fw_populateDependentGraph(framework_pt framework, bundle_pt exporter, hash_map_pt *map); - -celix_status_t fw_fireBundleEvent(framework_pt framework, bundle_event_type_e, bundle_pt bundle); -celix_status_t fw_fireFrameworkEvent(framework_pt framework, framework_event_type_e eventType, bundle_pt bundle, celix_status_t errorCode); -static void *fw_eventDispatcher(void *fw); - -celix_status_t fw_invokeBundleListener(framework_pt framework, bundle_listener_pt listener, bundle_event_pt event, bundle_pt bundle); -celix_status_t fw_invokeFrameworkListener(framework_pt framework, framework_listener_pt listener, framework_event_pt event, bundle_pt bundle); - -static celix_status_t framework_loadBundleLibraries(framework_pt framework, bundle_pt bundle); -static celix_status_t framework_loadLibraries(framework_pt framework, const char* libraries, const char* activator, bundle_archive_pt archive, void **activatorHandle); -static celix_status_t framework_loadLibrary(framework_pt framework, const char* library, bundle_archive_pt archive, void **handle); - -static celix_status_t frameworkActivator_start(void * userData, bundle_context_pt context); -static celix_status_t frameworkActivator_stop(void * userData, bundle_context_pt context); -static celix_status_t frameworkActivator_destroy(void * userData, bundle_context_pt context); - - -struct fw_refreshHelper { - framework_pt framework; - bundle_pt bundle; - bundle_state_e oldState; -}; - -celix_status_t fw_refreshHelper_refreshOrRemove(struct fw_refreshHelper * refreshHelper); -celix_status_t fw_refreshHelper_restart(struct fw_refreshHelper * refreshHelper); -celix_status_t fw_refreshHelper_stop(struct fw_refreshHelper * refreshHelper); - -struct fw_serviceListener { - bundle_pt bundle; - service_listener_pt listener; - filter_pt filter; - array_list_pt retainedReferences; -}; - -typedef struct fw_serviceListener * fw_service_listener_pt; - -struct fw_bundleListener { - bundle_pt bundle; - bundle_listener_pt listener; -}; - -typedef struct fw_bundleListener * fw_bundle_listener_pt; - -struct fw_frameworkListener { - bundle_pt bundle; - framework_listener_pt listener; -}; - -typedef struct fw_frameworkListener * fw_framework_listener_pt; - -enum event_type { - FRAMEWORK_EVENT_TYPE, - BUNDLE_EVENT_TYPE, - EVENT_TYPE_SERVICE, -}; - -typedef enum event_type event_type_e; - -struct request { - event_type_e type; - array_list_pt listeners; - - int eventType; - long bundleId; - char* bundleSymbolicName; - celix_status_t errorCode; - char *error; - - char *filter; -}; - -typedef struct request *request_pt; - -framework_logger_pt logger; - -//TODO introduce a counter + mutex to control the freeing of the logger when mutiple threads are running a framework. -static celix_thread_once_t loggerInit = CELIX_THREAD_ONCE_INIT; -static void framework_loggerInit(void) { - logger = malloc(sizeof(*logger)); - logger->logFunction = frameworkLogger_log; -} - -/* Note: RTLD_NODELETE flag is needed in order to obtain a readable valgrind output. - * Valgrind output is written when the application terminates, so symbols resolving - * is impossible if dlopened libraries are unloaded before the application ends. - * RTLD_NODELETE closes the dynamic library but does not unload it from the memory space, - * so that symbols will be available until the application terminates. - * On the other hand, since the memory mapping is not destroyed after dlclose, calling again - * dlopen for the same library clashes with the previous mapping: this breaks the memory layout - * in case the user, for example, uninstall (dlclose) and install the bundle again (dlopen) - * So, RTLD_NODELETE should be used only for debugging purposes. - * Refer to dlopen manpage for additional details about libraries dynamic loading. - */ -#ifdef _WIN32 - #define handle_t HMODULE - #define fw_openLibrary(path) LoadLibrary(path) - #define fw_closeLibrary(handle) FreeLibrary(handle) - - #define fw_getSymbol(handle, name) GetProcAddress(handle, name) - - #define fw_getLastError() GetLastError() - - HMODULE fw_getCurrentModule() { - HMODULE hModule = NULL; - GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, (LPCTSTR)fw_getCurrentModule, &hModule); - return hModule; - } -#else - #define handle_t void * - #if defined(DEBUG) && !defined(ANDROID) - #define fw_openLibrary(path) dlopen(path, RTLD_LAZY|RTLD_LOCAL|RTLD_NODELETE) - #else - #define fw_openLibrary(path) dlopen(path, RTLD_LAZY|RTLD_LOCAL) - #endif - #define fw_closeLibrary(handle) dlclose(handle) - #define fw_getSymbol(handle, name) dlsym(handle, name) - #define fw_getLastError() dlerror() -#endif - -celix_status_t framework_create(framework_pt *framework, properties_pt config) { - celix_status_t status = CELIX_SUCCESS; - - logger = hashMap_get(config, "logger"); - if (logger == NULL) { - celixThread_once(&loggerInit, framework_loggerInit); - } - - *framework = (framework_pt) malloc(sizeof(**framework)); - if (*framework != NULL) { - status = CELIX_DO_IF(status, celixThreadCondition_init(&(*framework)->condition, NULL)); - status = CELIX_DO_IF(status, celixThreadMutex_create(&(*framework)->mutex, NULL)); - status = CELIX_DO_IF(status, celixThreadMutex_create(&(*framework)->installedBundleMapLock, NULL)); - status = CELIX_DO_IF(status, celixThreadMutex_create(&(*framework)->bundleLock, NULL)); - status = CELIX_DO_IF(status, celixThreadMutex_create(&(*framework)->installRequestLock, NULL)); - status = CELIX_DO_IF(status, celixThreadMutex_create(&(*framework)->dispatcherLock, NULL)); - status = CELIX_DO_IF(status, celixThreadMutex_create(&(*framework)->bundleListenerLock, NULL)); - status = CELIX_DO_IF(status, celixThreadCondition_init(&(*framework)->dispatcher, NULL)); - if (status == CELIX_SUCCESS) { - (*framework)->bundle = NULL; - (*framework)->installedBundleMap = NULL; - (*framework)->registry = NULL; - (*framework)->interrupted = false; - (*framework)->shutdown = false; - (*framework)->globalLockWaitersList = NULL; - (*framework)->globalLockCount = 0; - (*framework)->globalLockThread = celix_thread_default; - (*framework)->nextBundleId = 1l; - (*framework)->cache = NULL; - (*framework)->installRequestMap = hashMap_create(utils_stringHash, utils_stringHash, utils_stringEquals, utils_stringEquals); - (*framework)->serviceListeners = NULL; - (*framework)->bundleListeners = NULL; - (*framework)->frameworkListeners = NULL; - (*framework)->requests = NULL; - (*framework)->configurationMap = config; - (*framework)->logger = logger; - - - status = CELIX_DO_IF(status, bundle_create(&(*framework)->bundle)); - status = CELIX_DO_IF(status, arrayList_create(&(*framework)->globalLockWaitersList)); - status = CELIX_DO_IF(status, bundle_setFramework((*framework)->bundle, (*framework))); - if (status == CELIX_SUCCESS) { - // - } else { - status = CELIX_FRAMEWORK_EXCEPTION; - fw_logCode((*framework)->logger, OSGI_FRAMEWORK_LOG_ERROR, status, "Could not create framework"); - } - } else { - status = CELIX_FRAMEWORK_EXCEPTION; - fw_logCode((*framework)->logger, OSGI_FRAMEWORK_LOG_ERROR, status, "Could not create framework"); - } - } else { - status = CELIX_FRAMEWORK_EXCEPTION; - fw_logCode(logger, OSGI_FRAMEWORK_LOG_ERROR, CELIX_ENOMEM, "Could not create framework"); - } - - return status; -} - -celix_status_t framework_destroy(framework_pt framework) { - celix_status_t status = CELIX_SUCCESS; - - celixThreadMutex_lock(&framework->installedBundleMapLock); - - if (framework->installedBundleMap != NULL) { - hash_map_iterator_pt iterator = hashMapIterator_create(framework->installedBundleMap); - while (hashMapIterator_hasNext(iterator)) { - hash_map_entry_pt entry = hashMapIterator_nextEntry(iterator); - bundle_pt bundle = (bundle_pt) hashMapEntry_getValue(entry); - char * key = hashMapEntry_getKey(entry); - bundle_archive_pt archive = NULL; - - bool systemBundle = false; - bundle_isSystemBundle(bundle, &systemBundle); - if (systemBundle) { - bundle_context_pt context = NULL; - bundle_getContext(framework->bundle, &context); - bundleContext_destroy(context); - } - - if (bundle_getArchive(bundle, &archive) == CELIX_SUCCESS) { - if (!systemBundle) { - bundle_revision_pt revision = NULL; - array_list_pt handles = NULL; - status = CELIX_DO_IF(status, bundleArchive_getCurrentRevision(archive, &revision)); - status = CELIX_DO_IF(status, bundleRevision_getHandles(revision, &handles)); - if (handles != NULL) { - for (int i = arrayList_size(handles) - 1; i >= 0; i--) { - void *handle = arrayList_get(handles, i); - fw_closeLibrary(handle); - } - } - } - - bundleArchive_destroy(archive); - } - bundle_destroy(bundle); - hashMapIterator_remove(iterator); - free(key); - } - hashMapIterator_destroy(iterator); - } - - celixThreadMutex_unlock(&framework->installedBundleMapLock); - - hashMap_destroy(framework->installRequestMap, false, false); - - serviceRegistry_destroy(framework->registry); - - arrayList_destroy(framework->globalLockWaitersList); - - if (framework->serviceListeners != NULL) { - arrayList_destroy(framework->serviceListeners); - } - if (framework->bundleListeners) { - arrayList_destroy(framework->bundleListeners); - } - if (framework->frameworkListeners) { - arrayList_destroy(framework->frameworkListeners); - } - - if(framework->requests){ - int i; - for (i = 0; i < arrayList_size(framework->requests); i++) { - request_pt request = arrayList_get(framework->requests, i); - free(request); - } - arrayList_destroy(framework->requests); - } - if(framework->installedBundleMap!=NULL){ - hashMap_destroy(framework->installedBundleMap, true, false); - } - - bundleCache_destroy(&framework->cache); - - celixThreadCondition_destroy(&framework->dispatcher); - celixThreadMutex_destroy(&framework->bundleListenerLock); - celixThreadMutex_destroy(&framework->dispatcherLock); - celixThreadMutex_destroy(&framework->installRequestLock); - celixThreadMutex_destroy(&framework->bundleLock); - celixThreadMutex_destroy(&framework->installedBundleMapLock); - celixThreadMutex_destroy(&framework->mutex); - celixThreadCondition_destroy(&framework->condition); - - logger = hashMap_get(framework->configurationMap, "logger"); - if (logger == NULL) { - free(framework->logger); - } - - properties_destroy(framework->configurationMap); - - free(framework); - - return status; -} - -celix_status_t fw_init(framework_pt framework) { - bundle_state_e state; - const char *location = NULL; - module_pt module = NULL; - linked_list_pt wires = NULL; - array_list_pt archives = NULL; - bundle_archive_pt archive = NULL; - - celix_status_t status = CELIX_SUCCESS; - status = CELIX_DO_IF(status, framework_acquireBundleLock(framework, framework->bundle, OSGI_FRAMEWORK_BUNDLE_INSTALLED|OSGI_FRAMEWORK_BUNDLE_RESOLVED|OSGI_FRAMEWORK_BUNDLE_STARTING|OSGI_FRAMEWORK_BUNDLE_ACTIVE)); - status = CELIX_DO_IF(status, arrayList_create(&framework->serviceListeners)); - status = CELIX_DO_IF(status, arrayList_create(&framework->bundleListeners)); - status = CELIX_DO_IF(status, arrayList_create(&framework->frameworkListeners)); - status = CELIX_DO_IF(status, arrayList_create(&framework->requests)); - status = CELIX_DO_IF(status, celixThread_create(&framework->dispatcherThread, NULL, fw_eventDispatcher, framework)); - status = CELIX_DO_IF(status, bundle_getState(framework->bundle, &state)); - if (status == CELIX_SUCCESS) { - if ((state == OSGI_FRAMEWORK_BUNDLE_INSTALLED) || (state == OSGI_FRAMEWORK_BUNDLE_RESOLVED)) { - bundle_state_e state; - status = CELIX_DO_IF(status, bundleCache_create(framework->configurationMap,&framework->cache)); - status = CELIX_DO_IF(status, bundle_getState(framework->bundle, &state)); - if (status == CELIX_SUCCESS) { - if (state == OSGI_FRAMEWORK_BUNDLE_INSTALLED) { - const char *clean = properties_get(framework->configurationMap, OSGI_FRAMEWORK_FRAMEWORK_STORAGE_CLEAN); - if (clean != NULL && (strcmp(clean, OSGI_FRAMEWORK_FRAMEWORK_STORAGE_CLEAN_ONFIRSTINIT) == 0)) { - bundleCache_delete(framework->cache); - } - } - } - } - } - - if (status == CELIX_SUCCESS) { - /*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); - - framework->installedBundleMap = hashMap_create(utils_stringHash, NULL, utils_stringEquals, NULL); - } - - status = CELIX_DO_IF(status, bundle_getArchive(framework->bundle, &archive)); - status = CELIX_DO_IF(status, bundleArchive_getLocation(archive, &location)); - if (status == CELIX_SUCCESS) { - hashMap_put(framework->installedBundleMap, strdup(location), framework->bundle); - } - 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, OSGI_FRAMEWORK_LOG_ERROR, status, "Unresolved constraints in System Bundle"); - } - } - - status = CELIX_DO_IF(status, bundleCache_getArchives(framework->cache, &archives)); - if (status == CELIX_SUCCESS) { - unsigned int arcIdx; - for (arcIdx = 0; arcIdx < arrayList_size(archives); arcIdx++) { - bundle_archive_pt archive1 = (bundle_archive_pt) arrayList_get(archives, arcIdx); - long id; - bundle_state_e bundleState; - bundleArchive_getId(archive1, &id); - framework->nextBundleId = framework->nextBundleId > id + 1 ? framework->nextBundleId : id + 1; - - bundleArchive_getPersistentState(archive1, &bundleState); - if (bundleState == OSGI_FRAMEWORK_BUNDLE_UNINSTALLED) { - bundleArchive_closeAndDelete(archive1); - } else { - bundle_pt bundle = NULL; - const char *location1 = NULL; - status = bundleArchive_getLocation(archive1, &location1); - fw_installBundle2(framework, &bundle, id, location1, NULL, archive1); - } - } - arrayList_destroy(archives); - } - - status = CELIX_DO_IF(status, serviceRegistry_create(framework, fw_serviceChanged, &framework->registry)); - status = CELIX_DO_IF(status, framework_setBundleStateAndNotify(framework, framework->bundle, OSGI_FRAMEWORK_BUNDLE_STARTING)); - status = CELIX_DO_IF(status, celixThreadCondition_init(&framework->shutdownGate, NULL)); - - bundle_context_pt 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)); - if (status == CELIX_SUCCESS) { - activator_pt activator = NULL; - activator = (activator_pt) calloc(1,(sizeof(*activator))); - if (activator != NULL) { - bundle_context_pt context = NULL; - void * userData = NULL; - - //create_function_pt create = NULL; - start_function_pt start = (start_function_pt) frameworkActivator_start; - stop_function_pt stop = (stop_function_pt) frameworkActivator_stop; - destroy_function_pt destroy = (destroy_function_pt) frameworkActivator_destroy; - - activator->start = start; - activator->stop = stop; - activator->destroy = destroy; - status = CELIX_DO_IF(status, bundle_setActivator(framework->bundle, activator)); - status = CELIX_DO_IF(status, bundle_getContext(framework->bundle, &context)); - - 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, context); - } - } - else{ - free(activator); - } - } else { - status = CELIX_ENOMEM; - } - } - - if (status != CELIX_SUCCESS) { - fw_logCode(framework->logger, OSGI_FRAMEWORK_LOG_ERROR, status, "Could not init framework"); - } - - framework_releaseBundleLock(framework, framework->bundle); - - return status; -} - -celix_status_t framework_start(framework_pt framework) { - celix_status_t status = CELIX_SUCCESS; - bundle_state_e state = OSGI_FRAMEWORK_BUNDLE_UNKNOWN; - - status = CELIX_DO_IF(status, framework_acquireBundleLock(framework, framework->bundle, OSGI_FRAMEWORK_BUNDLE_INSTALLED|OSGI_FRAMEWORK_BUNDLE_RESOLVED|OSGI_FRAMEWORK_BUNDLE_STARTING|OSGI_FRAMEWORK_BUNDLE_ACTIVE)); - status = CELIX_DO_IF(status, bundle_getState(framework->bundle, &state)); - if (status == CELIX_SUCCESS) { - if ((state == OSGI_FRAMEWORK_BUNDLE_INSTALLED) || (state == OSGI_FRAMEWORK_BUNDLE_RESOLVED)) { - status = CELIX_DO_IF(status, fw_init(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)); - } - - framework_releaseBundleLock(framework, framework->bundle); - } - - status = CELIX_DO_IF(status, fw_fireBundleEvent(framework, OSGI_FRAMEWORK_BUNDLE_EVENT_STARTED, framework->bundle)); - status = CELIX_DO_IF(status, fw_fireFrameworkEvent(framework, OSGI_FRAMEWORK_EVENT_STARTED, framework->bundle, 0)); - - if (status != CELIX_SUCCESS) { - status = CELIX_BUNDLE_EXCEPTION; - fw_logCode(framework->logger, OSGI_FRAMEWORK_LOG_ERROR, status, "Could not start framework"); - fw_fireFrameworkEvent(framework, OSGI_FRAMEWORK_EVENT_ERROR, framework->bundle, status); - } - - return status; -} - -void framework_stop(framework_pt framework) { - fw_stopBundle(framework, framework->bundle, true); -} - -celix_status_t fw_getProperty(framework_pt framework, const char* name, const char* defaultValue, const char** value) { - celix_status_t status = CELIX_SUCCESS; - - if (framework == NULL || name == NULL || *value != NULL) { - status = CELIX_ILLEGAL_ARGUMENT; - } else { - if (framework->configurationMap != NULL) { - *value = properties_get(framework->configurationMap, name); - } - if (*value == NULL) { - *value = getenv(name); - } - if (*value == NULL) { - *value = defaultValue; - } - } - - return status; -} - -celix_status_t fw_installBundle(framework_pt framework, bundle_pt * bundle, const char * location, const char *inputFile) { - return fw_installBundle2(framework, bundle, -1, location, inputFile, NULL); -} - -celix_status_t fw_installBundle2(framework_pt framework, bundle_pt * bundle, long id, const char * location, const char *inputFile, bundle_archive_pt archive) { - celix_status_t status = CELIX_SUCCESS; -// bundle_archive_pt bundle_archive = NULL; - bundle_state_e state = OSGI_FRAMEWORK_BUNDLE_UNKNOWN; - bool locked; - - status = CELIX_DO_IF(status, framework_acquireInstallLock(framework, location)); - status = CELIX_DO_IF(status, bundle_getState(framework->bundle, &state)); - if (status == CELIX_SUCCESS) { - if (state == OSGI_FRAMEWORK_BUNDLE_STOPPING || state == OSGI_FRAMEWORK_BUNDLE_UNINSTALLED) { - fw_log(framework->logger, OSGI_FRAMEWORK_LOG_INFO, "The framework is being shutdown"); - status = CELIX_DO_IF(status, framework_releaseInstallLock(framework, location)); - status = CELIX_FRAMEWORK_SHUTDOWN; - } - } - - if (status == CELIX_SUCCESS) { - *bundle = framework_getBundle(framework, location); - if (*bundle != NULL) { - framework_releaseInstallLock(framework, location); - return CELIX_SUCCESS; - } - - if (archive == NULL) { - id = framework_getNextBundleId(framework); - - status = CELIX_DO_IF(status, bundleCache_createArchive(framework->cache, id, location, inputFile, &archive)); - - if (status != CELIX_SUCCESS) { - bundleArchive_destroy(archive); - } - } else { - // purge revision - // multiple revisions not yet implemented - } - - if (status == CELIX_SUCCESS) { - locked = framework_acquireGlobalLock(framework); - if (!locked) { - status = CELIX_BUNDLE_EXCEPTION; - } else { - status = CELIX_DO_IF(status, bundle_createFromArchive(bundle, framework, archive)); - - framework_releaseGlobalLock(framework); - if (status == CELIX_SUCCESS) { - celixThreadMutex_lock(&framework->installedBundleMapLock); - hashMap_put(framework->installedBundleMap, strdup(location), *bundle); - celixThreadMutex_unlock(&framework->installedBundleMapLock); - - } else { - status = CELIX_BUNDLE_EXCEPTION; - status = CELIX_DO_IF(status, bundleArchive_closeAndDelete(archive)); - } - } - } - } - - framework_releaseInstallLock(framework, location); - - if (status != CELIX_SUCCESS) { - fw_logCode(framework->logger, OSGI_FRAMEWORK_LOG_ERROR, status, "Could not install bundle"); - } else { - status = CELIX_DO_IF(status, fw_fireBundleEvent(framework, OSGI_FRAMEWORK_BUNDLE_EVENT_INSTALLED, *bundle)); - } - - return status; -} - -celix_status_t framework_getBundleEntry(framework_pt framework, bundle_pt bundle, const char* name, char** entry) { - celix_status_t status = CELIX_SUCCESS; - - bundle_revision_pt revision; - bundle_archive_pt archive = NULL; - const char *root; - - status = CELIX_DO_IF(status, bundle_getArchive(bundle, &archive)); - status = CELIX_DO_IF(status, bundleArchive_getCurrentRevision(archive, &revision)); - status = CELIX_DO_IF(status, bundleRevision_getRoot(revision, &root)); - if (status == CELIX_SUCCESS) { - char e[strlen(name) + strlen(root) + 2]; - strcpy(e, root); - if ((strlen(name) > 0) && (name[0] == '/')) { - strcat(e, name); - } else { - strcat(e, "/"); - strcat(e, name); - } - - if (access(e, F_OK) == 0) { - (*entry) = strndup(e, 1024*10); - } else { - (*entry) = NULL; - } - } - - return status; -} - -celix_status_t fw_startBundle(framework_pt framework, bundle_pt bundle, int options) { - celix_status_t status = CELIX_SUCCESS; - - linked_list_pt wires = NULL; - bundle_context_pt context = NULL; - bundle_state_e state; - module_pt module = NULL; - activator_pt activator = NULL; - char *error = NULL; - const char *name = NULL; - - status = CELIX_DO_IF(status, framework_acquireBundleLock(framework, bundle, OSGI_FRAMEWORK_BUNDLE_INSTALLED|OSGI_FRAMEWORK_BUNDLE_RESOLVED|OSGI_FRAMEWORK_BUNDLE_STARTING|OSGI_FRAMEWORK_BUNDLE_ACTIVE)); - status = CELIX_DO_IF(status, bundle_getState(bundle, &state)); - - if (status == CELIX_SUCCESS) { - switch (state) { - case OSGI_FRAMEWORK_BUNDLE_UNKNOWN: - error = "state is unknown"; - status = CELIX_ILLEGAL_STATE; - break; - case OSGI_FRAMEWORK_BUNDLE_UNINSTALLED: - error = "bundle is uninstalled"; - status = CELIX_ILLEGAL_STATE; - break; - case OSGI_FRAMEWORK_BUNDLE_STARTING: - error = "bundle is starting"; - status = CELIX_BUNDLE_EXCEPTION; - break; - case OSGI_FRAMEWORK_BUNDLE_STOPPING: - error = "bundle is stopping"; - status = CELIX_BUNDLE_EXCEPTION; - break; - case OSGI_FRAMEWORK_BUNDLE_ACTIVE: - break; - case OSGI_FRAMEWORK_BUNDLE_INSTALLED: - bundle_getCurrentModule(bundle, &module); - module_getSymbolicName(module, &name); - if (!module_isResolved(module)) { - wires = resolver_resolve(module); - if (wires == NULL) { - framework_releaseBundleLock(framework, bundle); - return CELIX_BUNDLE_EXCEPTION; - } - framework_markResolvedModules(framework, wires); - - } - /* no break */ - case OSGI_FRAMEWORK_BUNDLE_RESOLVED: - module = NULL; - name = NULL; - bundle_getCurrentModule(bundle, &module); - module_getSymbolicName(module, &name); - status = CELIX_DO_IF(status, bundleContext_create(framework, framework->logger, bundle, &context)); - status = CELIX_DO_IF(status, bundle_setContext(bundle, context)); - - if (status == CELIX_SUCCESS) { - activator = (activator_pt) calloc(1,(sizeof(*activator))); - if (activator == NULL) { - status = CELIX_ENOMEM; - } else { - void * userData = NULL; - bundle_context_pt context; - create_function_pt create = (create_function_pt) fw_getSymbol((handle_t) bundle_getHandle(bundle), OSGI_FRAMEWORK_BUNDLE_ACTIVATOR_CREATE); - start_function_pt start = (start_function_pt) fw_getSymbol((handle_t) bundle_getHandle(bundle), OSGI_FRAMEWORK_BUNDLE_ACTIVATOR_START); - stop_function_pt stop = (stop_function_pt) fw_getSymbol((handle_t) bundle_getHandle(bundle), OSGI_FRAMEWORK_BUNDLE_ACTIVATOR_STOP); - destroy_function_pt destroy = (destroy_function_pt) fw_getSymbol((handle_t) bundle_getHandle(bundle), OSGI_FRAMEWORK_BUNDLE_ACTIVATOR_DESTROY); - - activator->start = start; - activator->stop = stop; - activator->destroy = destroy; - status = CELIX_DO_IF(status, bundle_setActivator(bundle, activator)); - - status = CELIX_DO_IF(status, framework_setBundleStateAndNotify(framework, bundle, OSGI_FRAMEWORK_BUNDLE_STARTING)); - status = CELIX_DO_IF(status, fw_fireBundleEvent(framework, OSGI_FRAMEWORK_BUNDLE_EVENT_STARTING, bundle)); - - status = CELIX_DO_IF(status, bundle_getContext(bundle, &context)); - - if (status == CELIX_SUCCESS) { - if (create != NULL) { - status = CELIX_DO_IF(status, create(context, &userData)); - if (status == CELIX_SUCCESS) { - activator->userData = userData; - } - } - } - if (status == CELIX_SUCCESS) { - if (start != NULL) { - status = CELIX_DO_IF(status, start(userData, context)); - } - } - - status = CELIX_DO_IF(status, framework_setBundleStateAndNotify(framework, bundle, OSGI_FRAMEWORK_BUNDLE_ACTIVE)); - status = CELIX_DO_IF(status, fw_fireBundleEvent(framework, OSGI_FRAMEWORK_BUNDLE_EVENT_STARTED, bundle)); - } - } - - break; - } - } - - framework_releaseBundleLock(framework, bundle); - - if (status != CELIX_SUCCESS) { - module_pt module = NULL; - const char *symbolicName = NULL; - long id = 0; - bundle_getCurrentModule(bundle, &module); - module_getSymbolicName(module, &symbolicName); - bundle_getBundleId(bundle, &id); - if (error != NULL) { - fw_logCode(framework->logger, OSGI_FRAMEWORK_LOG_ERROR, status, "Could not start bundle: %s [%ld]; cause: %s", symbolicName, id, error); - } else { - fw_logCode(framework->logger, OSGI_FRAMEWORK_LOG_ERROR, status, "Could not start bundle: %s [%ld]", symbolicName, id); - } - if(activator!=NULL){ - free(activator); - } - } - - return status; -} - -celix_status_t framework_updateBundle(framework_pt framework, bundle_pt bundle, const char *inputFile) { - celix_status_t status = CELIX_SUCCESS; - bundle_state_e oldState; - const char *location; - bundle_archive_pt archive = NULL; - char *error = NULL; - - status = CELIX_DO_IF(status, framework_acquireBundleLock(framework, bundle, OSGI_FRAMEWORK_BUNDLE_INSTALLED|OSGI_FRAMEWORK_BUNDLE_RESOLVED|OSGI_FRAMEWORK_BUNDLE_ACTIVE)); - status = CELIX_DO_IF(status, bundle_getState(bundle, &oldState)); - if (status == CELIX_SUCCESS) { - if (oldState == OSGI_FRAMEWORK_BUNDLE_ACTIVE) { - fw_stopBundle(framework, bundle, false); - } - } - status = CELIX_DO_IF(status, bundle_getArchive(bundle, &archive)); - status = CELIX_DO_IF(status, bundleArchive_getLocation(archive, &location)); - - if (status == CELIX_SUCCESS) { - bool locked = framework_acquireGlobalLock(framework); - if (!locked) { - status = CELIX_BUNDLE_EXCEPTION; - error = "Unable to acquire the global lock to update the bundle"; - } - } - - status = CELIX_DO_IF(status, bundle_revise(bundle, location, inputFile)); - status = CELIX_DO_IF(status, framework_releaseGlobalLock(framework)); - - status = CELIX_DO_IF(status, bundleArchive_setLastModified(archive, time(NULL))); - status = CELIX_DO_IF(status, framework_setBundleStateAndNotify(framework, bundle, OSGI_FRAMEWORK_BUNDLE_INSTALLED)); - - bundle_revision_pt revision = NULL; - array_list_pt handles = NULL; - status = CELIX_DO_IF(status, bundleArchive_getCurrentRevision(archive, &revision)); - status = CELIX_DO_IF(status, bundleRevision_getHandles(revision, &handles)); - if (handles != NULL) { - int i; - for (i = arrayList_size(handles) - 1; i >= 0; i--) { - void* handle = arrayList_get(handles, i); - fw_closeLibrary(handle); - } - } - - - status = CELIX_DO_IF(status, fw_fireBundleEvent(framework, OSGI_FRAMEWORK_BUNDLE_EVENT_UNRESOLVED, bundle)); - status = CELIX_DO_IF(status, fw_fireBundleEvent(framework, OSGI_FRAMEWORK_BUNDLE_EVENT_UPDATED, bundle)); - - // Refresh packages? - - if (status == CELIX_SUCCESS) { - if (oldState == OSGI_FRAMEWORK_BUNDLE_ACTIVE) { - status = CELIX_DO_IF(status, fw_startBundle(framework, bundle, 1)); - } - } - - framework_releaseBundleLock(framework, bundle); - - if (status != CELIX_SUCCESS) { - module_pt module = NULL; - const char *symbolicName = NULL; - long id = 0; - bundle_getCurrentModule(bundle, &module); - module_getSymbolicName(module, &symbolicName); - bundle_getBundleId(bundle, &id); - if (error != NULL) { - fw_logCode(framework->logger, OSGI_FRAMEWORK_LOG_ERROR, status, "Cannot update bundle: %s [%ld]; cause: %s", symbolicName, id, error); - } else { - fw_logCode(framework->logger, OSGI_FRAMEWORK_LOG_ERROR, status, "Cannot update bundle: %s [%ld]", symbolicName, id); - } - } - - return status; -} - -celix_status_t fw_stopBundle(framework_pt framework, bundle_pt bundle, bool record) { - celix_status_t status = CELIX_SUCCESS; - bundle_state_e state; - activator_pt activator = NULL; - bundle_context_pt context = NULL; - bool wasActive = false; - long id = 0; - char *error = NULL; - - status = CELIX_DO_IF(status, framework_acquireBundleLock(framework, bundle, OSGI_FRAMEWORK_BUNDLE_INSTALLED|OSGI_FRAMEWORK_BUNDLE_RESOLVED|OSGI_FRAMEWORK_BUNDLE_STARTING|OSGI_FRAMEWORK_BUNDLE_ACTIVE)); - - if (record) { - status = CELIX_DO_IF(status, bundle_setPersistentStateInactive(bundle)); - } - - status = CELIX_DO_IF(status, bundle_getState(bundle, &state)); - if (status == CELIX_SUCCESS) { - switch (state) { - case OSGI_FRAMEWORK_BUNDLE_UNKNOWN: - status = CELIX_ILLEGAL_STATE; - error = "state is unknown"; - break; - case OSGI_FRAMEWORK_BUNDLE_UNINSTALLED: - status = CELIX_ILLEGAL_STATE; - error = "bundle is uninstalled"; - break; - case OSGI_FRAMEWORK_BUNDLE_STARTING: - status = CELIX_BUNDLE_EXCEPTION; - error = "bundle is starting"; - break; - case OSGI_FRAMEWORK_BUNDLE_STOPPING: - status = CELIX_BUNDLE_EXCEPTION; - error = "bundle is stopping"; - break; - case OSGI_FRAMEWORK_BUNDLE_INSTALLED: - case OSGI_FRAMEWORK_BUNDLE_RESOLVED: - break; - case OSGI_FRAMEWORK_BUNDLE_ACTIVE: - wasActive = true; - break; - } - } - - - status = CELIX_DO_IF(status, framework_setBundleStateAndNotify(framework, bundle, OSGI_FRAMEWORK_BUNDLE_STOPPING)); - status = CELIX_DO_IF(status, fw_fireBundleEvent(framework, OSGI_FRAMEWORK_BUNDLE_EVENT_STOPPING, bundle)); - status = CELIX_DO_IF(status, bundle_getBundleId(bundle, &id)); - if (status == CELIX_SUCCESS) { - if (wasActive || (id == 0)) { - activator = bundle_getActivator(bundle); - - status = CELIX_DO_IF(status, bundle_getContext(bundle, &context)); - if (status == CELIX_SUCCESS) { - if (activator->stop != NULL) { - status = CELIX_DO_IF(status, activator->stop(activator->userData, context)); - } - } - if (status == CELIX_SUCCESS) { - if (activator->destroy != NULL) { - status = CELIX_DO_IF(status, activator->destroy(activator->userData, context)); - } - } - - if (id != 0) { - status = CELIX_DO_IF(status, serviceRegistry_clearServiceRegistrations(framework->registry, bundle)); - if (status == CELIX_SUCCESS) { - module_pt module = NULL; - const char *symbolicName = NULL; - long id = 0; - bundle_getCurrentModule(bundle, &module); - module_getSymbolicName(module, &symbolicName); - bundle_getBundleId(bundle, &id); - - serviceRegistry_clearReferencesFor(framework->registry, bundle); - } - // #TODO remove listeners for bundle - - if (context != NULL) { - status = CELIX_DO_IF(status, bundleContext_destroy(context)); - status = CELIX_DO_IF(status, bundle_setContext(bundle, NULL)); - } - - status = CELIX_DO_IF(status, framework_setBundleStateAndNotify(framework, bundle, OSGI_FRAMEWORK_BUNDLE_RESOLVED)); - } - } - - if (activator != NULL) { - bundle_setActivator(bundle, NULL); - free(activator); - } - } - - framework_releaseBundleLock(framework, bundle); - - if (status != CELIX_SUCCESS) { - module_pt module = NULL; - const char *symbolicName = NULL; - long id = 0; - bundle_getCurrentModule(bundle, &module); - module_getSymbolicName(module, &symbolicName); - bundle_getBundleId(bundle, &id); - if (error != NULL) { - fw_logCode(framework->logger, OSGI_FRAMEWORK_LOG_ERROR, status, "Cannot stop bundle: %s [%ld]; cause: %s", symbolicName, id, error); - } else { - fw_logCode(framework->logger, OSGI_FRAMEWORK_LOG_ERROR, status, "Cannot stop bundle: %s [%ld]", symbolicName, id); - } - } else { - fw_fireBundleEvent(framework, OSGI_FRAMEWORK_BUNDLE_EVENT_STOPPED, bundle); - } - - return status; -} - -celix_status_t fw_uninstallBundle(framework_pt framework, bundle_pt bundle) { - celix_status_t status = CELIX_SUCCESS; - bool locked; - bundle_archive_pt archive = NULL; - const char * location = NULL; - bundle_pt target = NULL; - char *error = NULL; - - status = CELIX_DO_IF(status, framework_acquireBundleLock(framework, bundle, OSGI_FRAMEWORK_BUNDLE_INSTALLED|OSGI_FRAMEWORK_BUNDLE_RESOLVED|OSGI_FRAMEWORK_BUNDLE_STARTING|OSGI_FRAMEWORK_BUNDLE_ACTIVE|OSGI_FRAMEWORK_BUNDLE_STOPPING)); - status = CELIX_DO_IF(status, fw_stopBundle(framework, bundle, true)); - if (status == CELIX_SUCCESS) { - locked = framework_acquireGlobalLock(framework); - if (!locked) { - status = CELIX_ILLEGAL_STATE; - error = "Unable to acquire the global lock to uninstall the bundle"; - } - } - - status = CELIX_DO_IF(status, bundle_getArchive(bundle, &archive)); - status = CELIX_DO_IF(status, bundleArchive_getLocation(archive, &location)); - if (status == CELIX_SUCCESS) { - - celixThreadMutex_lock(&framework->installedBundleMapLock); - - hash_map_entry_pt entry = hashMap_getEntry(framework->installedBundleMap, location); - char* entryLocation = hashMapEntry_getKey(entry); - - target = (bundle_pt) hashMap_remove(framework->installedBundleMap, location); - - free(entryLocation); - if (target != NULL) { - status = CELIX_DO_IF(status, bundle_setPersistentStateUninstalled(target)); - // fw_rememberUninstalledBundle(framework, target); - } - celixThreadMutex_unlock(&framework->installedBundleMapLock); - - } - - framework_releaseGlobalLock(framework); - - if (status == CELIX_SUCCESS) { - if (target == NULL) { - fw_log(framework->logger, OSGI_FRAMEWORK_LOG_ERROR, "Could not remove bundle from installed map"); - } - } - - status = CELIX_DO_IF(status, framework_setBundleStateAndNotify(framework, bundle, OSGI_FRAMEWORK_BUNDLE_INSTALLED)); - - // TODO Unload all libraries for transition to unresolved - bundle_revision_pt revision = NULL; - array_list_pt handles = NULL; - status = CELIX_DO_IF(status, bundleArchive_getCurrentRevision(archive, &revision)); - status = CELIX_DO_IF(status, bundleRevision_getHandles(revision, &handles)); - if(handles != NULL){ - for (int i = arrayList_size(handles) - 1; i >= 0; i--) { - void *handle = arrayList_get(handles, i); - fw_closeLibrary(handle); - } - } - - status = CELIX_DO_IF(status, fw_fireBundleEvent(framework, OSGI_FRAMEWORK_BUNDLE_EVENT_UNRESOLVED, bundle)); - - status = CELIX_DO_IF(status, framework_setBundleStateAndNotify(framework, bundle, OSGI_FRAMEWORK_BUNDLE_UNINSTALLED)); - status = CELIX_DO_IF(status, bundleArchive_setLastModified(archive, time(NULL))); - - framework_releaseBundleLock(framework, bundle); - - status = CELIX_DO_IF(status, fw_fireBundleEvent(framework, OSGI_FRAMEWORK_BUNDLE_EVENT_UNINSTALLED, bundle)); - - if (status == CELIX_SUCCESS) { - locked = framework_acquireGlobalLock(framework); - if (locked) { - bundle_pt bundles[] = { bundle }; - celix_status_t refreshStatus = fw_refreshBundles(framework, bundles, 1); - if (refreshStatus != CELIX_SUCCESS) { - printf("Could not refresh bundle"); - } else { - bundleArchive_destroy(archive); - status = CELIX_DO_IF(status, bundle_destroy(bundle)); - } - - status = CELIX_DO_IF(status, framework_releaseGlobalLock(framework)); - } - } - - - if (status != CELIX_SUCCESS) { -// module_pt module = NULL; -// char *symbolicName = NULL; -// long id = 0; -// bundle_getCurrentModule(bundle, &module); -// module_getSymbolicName(module, &symbolicName); -// bundle_getBundleId(bundle, &id); - - framework_logIfError(framework->logger, status, error, "Cannot uninstall bundle"); - } - - return status; -} - -celix_status_t fw_refreshBundles(framework_pt framework, bundle_pt bundles[], int size) { - celix_status_t status = CELIX_SUCCESS; - - bool locked = framework_acquireGlobalLock(framework); - if (!locked) { - framework_releaseGlobalLock(framework); - status = CELIX_ILLEGAL_STATE; - } else { - hash_map_values_pt values; - bundle_pt *newTargets; - unsigned int nrofvalues; - bool restart = false; - hash_map_pt map = hashMap_create(NULL, NULL, NULL, NULL); - int targetIdx = 0; - for (targetIdx = 0; targetIdx < size; targetIdx++) { - bundle_pt bundle = bundles[targetIdx]; - hashMap_put(map, bundle, bundle); - fw_populateDependentGraph(framework, bundle, &map); - } - values = hashMapValues_create(map); - hashMapValues_toArray(values, (void ***) &newTargets, &nrofvalues); - hashMapValues_destroy(values); - - hashMap_destroy(map, false, false); - - if (newTargets != NULL) { - int i = 0; - struct fw_refreshHelper * helpers; - for (i = 0; i < nrofvalues && !restart; i++) { - bundle_pt bundle = (bundle_pt) newTargets[i]; - if (framework->bundle == bundle) { - restart = true; - } - } - - helpers = (struct fw_refreshHelper * )malloc(nrofvalues * sizeof(struct fw_refreshHelper)); - for (i = 0; i < nrofvalues && !restart; i++) { - bundle_pt bundle = (bundle_pt) newTargets[i]; - helpers[i].framework = framework; - helpers[i].bundle = bundle; - helpers[i].oldState = OSGI_FRAMEWORK_BUNDLE_INSTALLED; - } - - for (i = 0; i < nrofvalues; i++) { - struct fw_refreshHelper helper = helpers[i]; - fw_refreshHelper_stop(&helper); - fw_refreshHelper_refreshOrRemove(&helper); - } - - for (i = 0; i < nrofvalues; i++) { - struct fw_refreshHelper helper = helpers[i]; - fw_refreshHelper_restart(&helper); - } - - if (restart) { - bundle_update(framework->bundle, NULL); - } - free(helpers); - free(newTargets); - } - - framework_releaseGlobalLock(framework); - } - - framework_logIfError(framework->logger, status, NULL, "Cannot refresh bundles"); - - return status; -} - -celix_status_t fw_refreshBundle(framework_pt framework, bundle_pt bundle) { - celix_status_t status = CELIX_SUCCESS; - bundle_state_e state; - - status = framework_acquireBundleLock(framework, bundle, OSGI_FRAMEWORK_BUNDLE_INSTALLED | OSGI_FRAMEWORK_BUNDLE_RESOLVED); - if (status != CELIX_SUCCESS) { - printf("Cannot refresh bundle"); - framework_releaseBundleLock(framework, bundle); - } else { - bool fire; - bundle_getState(bundle, &state); - fire = (state != OSGI_FRAMEWORK_BUNDLE_INSTALLED); - bundle_refresh(bundle); - - if (fire) { - framework_setBundleStateAndNotify(framework, bundle, OSGI_FRAMEWORK_BUNDLE_INSTALLED); - fw_fireBundleEvent(framework, OSGI_FRAMEWORK_BUNDLE_EVENT_UNRESOLVED, bundle); - } - - framework_releaseBundleLock(framework, bundle); - } - - framework_logIfError(framework->logger, status, NULL, "Cannot refresh bundle"); - - return status; -} - -celix_status_t fw_refreshHelper_stop(struct fw_refreshHelper * refreshHelper) { - bundle_state_e state; - bundle_getState(refreshHelper->bundle, &state); - if (state == OSGI_FRAMEWORK_BUNDLE_ACTIVE) { - refreshHelper->oldState = OSGI_FRAMEWORK_BUNDLE_ACTIVE; - fw_stopBundle(refreshHelper->framework, refreshHelper->bundle, false); - } - - return CELIX_SUCCESS; -} - -celix_status_t fw_refreshHelper_refreshOrRemove(struct fw_refreshHelper * refreshHelper) { - bundle_state_e state; - bundle_getState(refreshHelper->bundle, &state); - if (state == OSGI_FRAMEWORK_BUNDLE_UNINSTALLED) { - bundle_closeAndDelete(refreshHelper->bundle); - refreshHelper->bundle = NULL; - } else { - fw_refreshBundle(refreshHelper->framework, refreshHelper->bundle); - } - return CELIX_SUCCESS; -} - -celix_status_t fw_refreshHelper_restart(struct fw_refreshHelper * refreshHelper) { - if ((refreshHelper->bundle != NULL) && (refreshHelper->oldState == OSGI_FRAMEWORK_BUNDLE_ACTIVE)) { - fw_startBundle(refreshHelper->framework, refreshHelper->bundle, 0); - } - return CELIX_SUCCESS; -} - -celix_status_t fw_getDependentBundles(framework_pt framework, bundle_pt exporter, array_list_pt *list) { - celix_status_t status = CELIX_SUCCESS; - - if (*list != NULL || exporter == NULL || framework == NULL) { - return CELIX_ILLEGAL_ARGUMENT; - } - - array_list_pt modules; - unsigned int modIdx = 0; - arrayList_create(list); - - modules = bundle_getModules(exporter); - for (modIdx = 0; modIdx < arrayList_size(modules); modIdx++) { - module_pt module = (module_pt) arrayList_get(modules, modIdx); - array_list_pt dependents = module_getDependents(module); - if(dependents!=NULL){ - unsigned int depIdx = 0; - for (depIdx = 0; depIdx < arrayList_size(dependents); depIdx++) { - module_pt dependent = (module_pt) arrayList_get(dependents, depIdx); - arrayList_add(*list, module_getBundle(dependent)); - } - arrayList_destroy(dependents); - } - } - - framework_logIfError(framework->logger, status, NULL, "Cannot get dependent bundles"); - - return status; -} - -celix_status_t fw_populateDependentGraph(framework_pt framework, bundle_pt exporter, hash_map_pt *map) { - celix_status_t status = CELIX_SUCCESS; - - if(framework == NULL || exporter == NULL){ - return CELIX_ILLEGAL_ARGUMENT; - } - - array_list_pt dependents = NULL; - if ((status = fw_getDependentBundles(framework, exporter, &dependents)) == CELIX_SUCCESS) { - if(dependents!=NULL){ - unsigned int depIdx = 0; - for (depIdx = 0; depIdx < arrayList_size(dependents); depIdx++) { - if (!hashMap_containsKey(*map, arrayList_get(dependents, depIdx))) { - hashMap_put(*map, arrayList_get(dependents, depIdx), arrayList_get(dependents, depIdx)); - fw_populateDependentGraph(framework, (bundle_pt) arrayList_get(dependents, depIdx), map); - } - } - arrayList_destroy(dependents); - } - } - - framework_logIfError(framework->logger, status, NULL, "Cannot populate dependent graph"); - - return status; -} - -celix_status_t fw_registerService(framework_pt framework, service_registration_pt *registration, bundle_pt bundle, const char* serviceName, const void* svcObj, properties_pt properties) { - celix_status_t status = CELIX_SUCCESS; - char *error = NULL; - if (serviceName == NULL || svcObj == NULL) { - status = CELIX_ILLEGAL_ARGUMENT; - error = "ServiceName and SvcObj cannot be null"; - } - - status = CELIX_DO_IF(status, framework_acquireBundleLock(framework, bundle, OSGI_FRAMEWORK_BUNDLE_STARTING|OSGI_FRAMEWORK_BUNDLE_ACTIVE)); - status = CELIX_DO_IF(status, serviceRegistry_registerService(framework->registry, bundle, serviceName, svcObj, properties, registration)); - bool res = framework_releaseBundleLock(framework, bundle); - if (!res) { - status = CELIX_ILLEGAL_STATE; - error = "Could not release bundle lock"; - } - - if (status == CELIX_SUCCESS) { - // If this is a listener hook, invoke the callback with all current listeners - if (strcmp(serviceName, OSGI_FRAMEWORK_LISTENER_HOOK_SERVICE_NAME) == 0) { - unsigned int i; - array_list_pt infos = NULL; - service_reference_pt ref = NULL; - listener_hook_service_pt hook = NULL; - - status = CELIX_DO_IF(status, arrayList_create(&infos)); - - if (status == CELIX_SUCCESS) { - celix_status_t subs = CELIX_SUCCESS; - - for (i = 0; i < arrayList_size(framework->serviceListeners); i++) { - fw_service_listener_pt listener =(fw_service_listener_pt) arrayList_get(framework->serviceListeners, i); - bundle_context_pt context = NULL; - listener_hook_info_pt info = NULL; - bundle_context_pt lContext = NULL; - - subs = CELIX_DO_IF(subs, bundle_getContext(bundle, &context)); - if (subs == CELIX_SUCCESS) { - info = (listener_hook_info_pt) malloc(sizeof(*info)); - if (info == NULL) { - subs = CELIX_ENOMEM; - } - } - - subs = CELIX_DO_IF(subs, bundle_getContext(listener->bundle, &lContext)); - if (subs == CELIX_SUCCESS) { - info->context = lContext; - info->removed = false; - } - subs = CELIX_DO_IF(subs, filter_getString(listener->filter, (const char**)&info->filter)); - - if (subs == CELIX_SUCCESS) { - arrayList_add(infos, info); - } - else{ - fw_logCode(framework->logger, OSGI_FRAMEWORK_LOG_ERROR, status, "Could not pass all listeners to the hook: %s", serviceName); - free(info); - } - } - - status = CELIX_DO_IF(status, serviceRegistry_getServiceReference(framework->registry, framework->bundle, - *registration, &ref)); - status = CELIX_DO_IF(status, fw_getService(framework,framework->bundle, ref, (const void **) &hook)); - if (status == CELIX_SUCCESS) { - hook->added(hook->handle, infos); - } - status = CELIX_DO_IF(status, serviceRegistry_ungetService(framework->registry, framework->bundle, ref, NULL)); - status = CELIX_DO_IF(status, serviceRegistry_ungetServiceReference(framework->registry, framework->bundle, ref)); - - int i = 0; - for (i = 0; i < arrayList_size(infos); i++) { - listener_hook_info_pt info = arrayList_get(infos, i); - free(info); - } - arrayList_destroy(infos); - } - } - } - - framework_logIfError(framework->logger, status, error, "Cannot register service: %s", serviceName); - - return status; -} - -celix_status_t fw_registerServiceFactory(framework_pt framework, service_registration_pt *registration, bundle_pt bundle, const char* serviceName, service_factory_pt factory, properties_pt properties) { - celix_status_t status = CELIX_SUCCESS; - char *error = NULL; - if (serviceName == NULL || factory == NULL) { - status = CELIX_ILLEGAL_ARGUMENT; - error = "Service name and factory cannot be null"; - } - - status = CELIX_DO_IF(status, framework_acquireBundleLock(framework, bundle, OSGI_FRAMEWORK_BUNDLE_STARTING|OSGI_FRAMEWORK_BUNDLE_ACTIVE)); - status = CELIX_DO_IF(status, serviceRegistry_registerServiceFactory(framework->registry, bundle, serviceName, factory, properties, registration)); - if (!framework_releaseBundleLock(framework, bundle)) { - status = CELIX_ILLEGAL_STATE; - error = "Could not release bundle lock"; - } - - framework_logIfError(framework->logger, status, error, "Cannot register service factory: %s", serviceName); - - return CELIX_SUCCESS; -} - -celix_status_t fw_getServiceReferences(framework_pt framework, array_list_pt *references, bundle_pt bundle, const char * serviceName, const char * sfilter) { - celix_status_t status = CELIX_SUCCESS; - - filter_pt filter = NULL; - unsigned int refIdx = 0; - - if (sfilter != NULL) { - filter = filter_create(sfilter); - } - - status = CELIX_DO_IF(status, serviceRegistry_getServiceReferences(framework->registry, bundle, serviceName, filter, references)); - - if (filter != NULL) { - filter_destroy(filter); - } - - if (status == CELIX_SUCCESS) { - for (refIdx = 0; (*references != NULL) && refIdx < arrayList_size(*references); refIdx++) { - service_reference_pt ref = (service_reference_pt) arrayList_get(*references, refIdx); - service_registration_pt reg = NULL; - const char* serviceName; - properties_pt props = NULL; - status = CELIX_DO_IF(status, serviceReference_getServiceRegistration(ref, ®)); - status = CELIX_DO_IF(status, serviceRegistration_getProperties(reg, &props)); - if (status == CELIX_SUCCESS) { - serviceName = properties_get(props, OSGI_FRAMEWORK_OBJECTCLASS); - if (!serviceReference_isAssignableTo(ref, bundle, serviceName)) { - arrayList_remove(*references, refIdx); - refIdx--; - } - } - } - } - - framework_logIfError(framework->logger, status, NULL, "Failed to get service references"); - - return status; -} - -celix_status_t framework_ungetServiceReference(framework_pt framework, bundle_pt bundle, service_reference_pt reference) { - return serviceRegistry_ungetServiceReference(framework->registry, bundle, reference); -} - -celix_status_t fw_getService(framework_pt framework, bundle_pt bundle, service_reference_pt reference, const void **service) { - return serviceRegistry_getService(framework->registry, bundle, reference, service); -} - -celix_status_t fw_getBundleRegisteredServices(framework_pt framework, bundle_pt bundle, array_list_pt *services) { - return serviceRegistry_getRegisteredServices(framework->registry, bundle, services); -} - -celix_status_t fw_getBundleServicesInUse(framework_pt framework, bundle_pt bundle, array_list_pt *services) { - celix_status_t status = CELIX_SUCCESS; - status = serviceRegistry_getServicesInUse(framework->registry, bundle, services); - return status; -} - -celix_status_t framework_ungetService(framework_pt framework, bundle_pt bundle, service_reference_pt reference, bool *result) { - return serviceRegistry_ungetService(framework->registry, bundle, reference, result); -} - -void fw_addServiceListener(framework_pt framework, bundle_pt bundle, service_listener_pt listener, const char* sfilter) { - array_list_pt listenerHooks = NULL; - listener_hook_info_pt info; - unsigned int i; - - fw_service_listener_pt fwListener = (fw_service_listener_pt) calloc(1, sizeof(*fwListener)); - bundle_context_pt context = NULL; - - fwListener->bundle = bundle; - arrayList_create(&fwListener->retainedReferences); - if (sfilter != NULL) { - filter_pt filter = filter_create(sfilter); - fwListener->filter = filter; - } else { - fwListener->filter = NULL; - } - fwListener->listener = listener; - - arrayList_add(framework->serviceListeners, fwListener); - - serviceRegistry_getListenerHooks(framework->registry, framework->bundle, &listenerHooks); - - info = (listener_hook_info_pt) malloc(sizeof(*info)); - - bundle_getContext(bundle, &context); - info->context = context; - - info->removed = false; - info->filter = sfilter == NULL ? NULL : strdup(sfilter); - - for (i = 0; i < arrayList_size(listenerHooks); i++) { - service_reference_pt ref = (service_reference_pt) arrayList_get(listenerHooks, i); - listener_hook_service_pt hook = NULL; - array_list_pt infos = NULL; - bool ungetResult = false; - - fw_getService(framework, framework->bundle, ref, (const void **) &hook); - - arrayList_create(&infos); - arrayList_add(infos, info); - hook->added(hook->handle, infos); - serviceRegistry_ungetService(framework->registry, framework->bundle, ref, &ungetResult); - serviceRegistry_ungetServiceReference(framework->registry, framework->bundle, ref); - arrayList_destroy(infos); - } - - if (info->filter != NULL) { - free(info->filter); - } - free(info); - - arrayList_destroy(listenerHooks); -} - -void fw_removeServiceListener(framework_pt framework, bundle_pt bundle, service_listener_pt listener) { - listener_hook_info_pt info = NULL; - unsigned int i; - fw_service_listener_pt element; - - bundle_context_pt context; - bundle_getContext(bundle, &context); - - for (i = 0; i < arrayList_size(framework->serviceListeners); i++) { - element = (fw_service_listener_pt) arrayList_get(framework->serviceListeners, i); - if (element->listener == listener && element->bundle == bundle) { - bundle_context_pt lContext = NULL; - - info = (listener_hook_info_pt) malloc(sizeof(*info)); - - bundle_getContext(element->bundle, &lContext); - info->context = lContext; - - // TODO Filter toString; - filter_getString(element->filter, (const char**)&info->filter); - info->removed = true; - - arrayList_remove(framework->serviceListeners, i); - i--; - - //unregistering retained service references. For these refs a unregister event will not be triggered. - int k; - int rSize = arrayList_size(element->retainedReferences); - for (k = 0; k < rSize; k += 1) { - service_reference_pt ref = arrayList_get(element->retainedReferences, k); - if (ref != NULL) { - serviceRegistry_ungetServiceReference(framework->registry, element->bundle, ref); // decrease retain counter - } - } - - element->bundle = NULL; - filter_destroy(element->filter); - arrayList_destroy(element->retainedReferences); - element->filter = NULL; - element->listener = NULL; - free(element); - element = NULL; - break; - } - } - - if (info != NULL) { - unsigned int i; - array_list_pt listenerHooks = NULL; - serviceRegistry_getListenerHooks(framework->registry, framework->bundle, &listenerHooks); - - for (i = 0; i < arrayList_size(listenerHooks); i++) { - service_reference_pt ref = (service_reference_pt) arrayList_get(listenerHooks, i); - listener_hook_service_pt hook = NULL; - array_list_pt infos = NULL; - bool ungetResult; - - fw_getService(framework, framework->bundle, ref, (const void **) &hook); - - arrayList_create(&infos); - arrayList_add(infos, info); - hook->removed(hook->handle, infos); - serviceRegistry_ungetService(framework->registry, framework->bundle, ref, &ungetResult); - serviceRegistry_ungetServiceReference(framework->registry, framework->bundle, ref); - arrayList_destroy(infos); - } - - arrayList_destroy(listenerHooks); - free(info); - } -} - -celix_status_t fw_addBundleListener(framework_pt framework, bundle_pt bundle, bundle_listener_pt listener) { - celix_status_t status = CELIX_SUCCESS; - fw_bundle_listener_pt bundleListener = NULL; - - bundleListener = (fw_bundle_listener_pt) malloc(sizeof(*bundleListener)); - if (!bundleListener) { - status = CELIX_ENOMEM; - } else { - bundleListener->listener = listener; - bundleListener->bundle = bundle; - - if (celixThreadMutex_lock(&framework->bundleListenerLock) != CELIX_SUCCESS) { - status = CELIX_FRAMEWORK_EXCEPTION; - } else { - arrayList_add(framework->bundleListeners, bundleListener); - - if (celixThreadMutex_unlock(&framework->bundleListenerLock)) { - status = CELIX_FRAMEWORK_EXCEPTION; - } - } - } - - framework_logIfError(framework->logger, status, NULL, "Failed to add bundle listener"); - - return status; -} - -celix_status_t fw_removeBundleListener(framework_pt framework, bundle_pt bundle, bundle_listener_pt listener) { - celix_status_t status = CELIX_SUCCESS; - - unsigned int i; - fw_bundle_listener_pt bundleListener; - - if (celixThreadMutex_lock(&framework->bundleListenerLock) != CELIX_SUCCESS) { - status = CELIX_FRAMEWORK_EXCEPTION; - } - else { - for (i = 0; i < arrayList_size(framework->bundleListeners); i++) { - bundleListener = (fw_bundle_listener_pt) arrayList_get(framework->bundleListeners, i); - if (bundleListener->listener == listener && bundleListener->bundle == bundle) { - arrayList_remove(framework->bundleListeners, i); - - bundleListener->bundle = NULL; - bundleListener->listener = NULL; - free(bundleListener); - } - } - if (celixThreadMutex_unlock(&framework->bundleListenerLock)) { - status = CELIX_FRAMEWORK_EXCEPTION; - } - } - - framework_logIfError(framework->logger, status, NULL, "Failed to remove bundle listener"); - - return status; -} - -celix_status_t fw_addFrameworkListener(framework_pt framework, bundle_pt bundle, framework_listener_pt listener) { - celix_status_t status = CELIX_SUCCESS; - fw_framework_listener_pt frameworkListener = NULL; - - frameworkListener = (fw_framework_listener_pt) malloc(sizeof(*frameworkListener)); - if (!frameworkListener) { - status = CELIX_ENOMEM; - } else { - frameworkListener->listener = listener; - frameworkListener->bundle = bundle; - - arrayList_add(framework->frameworkListeners, frameworkListener); - } - - framework_logIfError(framework->logger, status, NULL, "Failed to add framework listener"); - - return status; -} - -celix_status_t fw_removeFrameworkListener(framework_pt framework, bundle_pt bundle, framework_listener_pt listener) { - celix_status_t status = CELIX_SUCCESS; - - unsigned int i; - fw_framework_listener_pt frameworkListener; - - for (i = 0; i < arrayList_size(framework->frameworkListeners); i++) { - frameworkListener = (fw_framework_listener_pt) arrayList_get(framework->frameworkListeners, i); - if (frameworkListener->listener == listener && frameworkListener->bundle == bundle) { - arrayList_remove(framework->frameworkListeners, i); - - frameworkListener->bundle = NULL; - frameworkListener->listener = NULL; - free(frameworkListener); - } - } - - framework_logIfError(framework->logger, status, NULL, "Failed to remove framework listener"); - - return status; -} - -void fw_serviceChanged(framework_pt framework, service_event_type_e eventType, service_registration_pt registration, properties_pt oldprops) { - unsigned int i; - fw_service_listener_pt element; - - if (arrayList_size(framework->serviceListeners) > 0) { - for (i = 0; i < arrayList_size(framework->serviceListeners); i++) { - int matched = 0; - properties_pt props = NULL; - bool matchResult = false; - - element = (fw_service_listener_pt) arrayList_get(framework->serviceListeners, i); - serviceRegistration_getProperties(registration, &props); - if (element->filter != NULL) { - filter_match(element->filter, props, &matchResult); - } - matched = (element->filter == NULL) || matchResult; - if (matched) { - service_reference_pt reference = NULL; - service_event_pt event; - - event = (service_event_pt) malloc(sizeof (*event)); - - serviceRegistry_getServiceReference(framework->registry, element->bundle, registration, &reference); - - //NOTE: that you are never sure that the UNREGISTERED event will by handle by an service_listener. listener could be gone - //Every reference retained is therefore stored and called when a service listener is removed from the framework. - if (eventType == OSGI_FRAMEWORK_SERVICE_EVENT_REGISTERED) { - serviceRegistry_retainServiceReference(framework->registry, element->bundle, reference); - arrayList_add(element->retainedReferences, reference); //TODO improve by using set (or hashmap) instead of list - } - - event->type = eventType; - event->reference = reference; - - element->listener->serviceChanged(element->listener, event); - - serviceRegistry_ungetServiceReference(framework->registry, element->bundle, reference); - - if (eventType == OSGI_FRAMEWORK_SERVICE_EVENT_UNREGISTERING) { - //if service listener was active when service was registered, release the retained reference - if (arrayList_removeElement(element->retainedReferences, reference)) { - serviceRegistry_ungetServiceReference(framework->registry, element->bundle, reference); // decrease retain counter - } - } - - free(event); - - } else if (eventType == OSGI_FRAMEWORK_SERVICE_EVENT_MODIFIED) { - bool matchResult = false; - int matched = 0; - if (element->filter != NULL) { - filter_match(element->filter, oldprops, &matchResult); - } - matched = (element->filter == NULL) || matchResult; - if (matched) { - service_reference_pt reference = NULL; - service_event_pt endmatch = (service_event_pt) malloc(sizeof (*endmatch)); - - serviceRegistry_getServiceReference(framework->registry, element->bundle, registration, &reference); - - endmatch->reference = reference; - endmatch->type = OSGI_FRAMEWORK_SERVICE_EVENT_MODIFIED_ENDMATCH; - element->listener->serviceChanged(element->listener, endmatch); - - serviceRegistry_ungetServiceReference(framework->registry, element->bundle, reference); - free(endmatch); - - } - } - } - } - -} - -//celix_status_t fw_isServiceAssignable(framework_pt fw, bundle_pt requester, service_reference_pt reference, bool *assignable) { -// celix_status_t status = CELIX_SUCCESS; -// -// *assignable = true; -// service_registration_pt registration = NULL; -// status = serviceReference_getServiceRegistration(reference, ®istration); -// if (status == CELIX_SUCCESS) { -// char *serviceName = properties_get(registration->properties, (char *) OBJECTCLASS); -// if (!serviceReference_isAssignableTo(reference, requester, serviceName)) { -// *assignable = false; -// } -// } -// -// return status; -//} - -long framework_getNextBundleId(framework_pt framework) { - long id = framework->nextBundleId; - framework->nextBundleId++; - return id; -} - -celix_status_t framework_markResolvedModules(framework_pt framework, linked_list_pt resolvedModuleWireMap) { - if (resolvedModuleWireMap != NULL) { - // hash_map_iterator_pt iterator = hashMapIterator_create(resolvedModuleWireMap); - linked_list_iterator_pt iterator = linkedListIterator_create(resolvedModuleWireMap, linkedList_size(resolvedModuleWireMap)); - while (linkedListIterator_hasPrevious(iterator)) { - importer_wires_pt iw = linkedListIterator_previous(iterator); - // hash_map_entry_pt entry = hashMapIterator_nextEntry(iterator); - module_pt module = iw->importer; - -// bundle_pt bundle = module_getBundle(module); -// bundle_archive_pt archive = NULL; -// bundle_getArchive(bundle, &archive); -// bundle_revision_pt revision = NULL; -// bundleArchive_getCurrentRevision(archive, &revision); -// char *root = NULL; -// bundleRevision_getRoot(revision, &root); -// manifest_pt manifest = NULL; -// bundleRevision_getManifest(revision, &manifest); -// -// char *private = manifest_getValue(manifest, OSGI_FRAMEWORK_PRIVATE_LIBRARY); -// char *export = manifest_getValue(manifest, OSGI_FRAMEWORK_EXPORT_LIBRARY); -// -// printf("Root %s\n", root); - - // for each library update the reference to the wires, if there are any - - linked_list_pt wires = iw->wires; - -// linked_list_iterator_pt wit = linkedListIterator_create(wires, 0); -// while (linkedListIterator_hasNext(wit)) { -// wire_pt wire = linkedListIterator_next(wit); -// module_pt importer = NULL; -// requirement_pt requirement = NULL; -// module_pt exporter = NULL; -// capability_pt capability = NULL; -// wire_getImporter(wire, &importer); -// wire_getRequirement(wire, &requirement); -// -// wire_getExporter(wire, &exporter); -// wire_getCapability(wire, &capability); -// -// char *importerName = NULL; -// module_getSymbolicName(importer, &importerName); -// -// char *exporterName = NULL; -// module_getSymbolicName(exporter, &exporterName); -// -// version_pt version = NULL; -// char *name = NULL; -// capability_getServiceName(capability, &name); -// capability_getVersion(capability, &version); -// char *versionString = NULL; -// version_toString(version, framework->mp, &versionString); -// -// printf("Module %s imports library %s:%s from %s\n", importerName, name, versionString, exporterName); -// } - - module_setWires(module, wires); - - module_setResolved(module); - resolver_moduleResolved(module); - - const char *mname = NULL; - module_getSymbolicName(module, &mname); - framework_markBundleResolved(framework, module); - linkedListIterator_remove(iterator); - free(iw); - } - linkedListIterator_destroy(iterator); - linkedList_destroy(resolvedModuleWireMap); - } - return CELIX_SUCCESS; -} - -celix_status_t framework_markBundleResolved(framework_pt framework, module_pt module) { - celix_status_t status = CELIX_SUCCESS; - bundle_pt bundle = module_getBundle(module); - bundle_state_e state; - char *error = NULL; - - if (bundle != NULL) { - framework_acquireBundleLock(framework, bundle, OSGI_FRAMEWORK_BUNDLE_INSTALLED|OSGI_FRAMEWORK_BUNDLE_RESOLVED|OSGI_FRAMEWORK_BUNDLE_ACTIVE); - bundle_getState(bundle, &state); - if (state != OSGI_FRAMEWORK_BUNDLE_INSTALLED) { - printf("Trying to resolve a resolved bundle"); - status = CELIX_ILLEGAL_STATE; - } else { - // Load libraries of this module - bool isSystemBundle = false; - bundle_isSystemBundle(bundle, &isSystemBundle); - if (!isSystemBundle) { - 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, fw_fireBundleEvent(framework, OSGI_FRAMEWORK_BUNDLE_EVENT_RESOLVED, bundle)); - } - - if (status != CELIX_SUCCESS) { - module_pt module = NULL; - const char *symbolicName = NULL; - long id = 0; - module_getSymbolicName(module, &symbolicName); - bundle_getBundleId(bundle, &id); - if (error != NULL) { - fw_logCode(framework->logger, OSGI_FRAMEWORK_LOG_ERROR, status, "Could not start bundle: %s [%ld]; cause: %s", symbolicName, id, error); - } else { - fw_logCode(framework->logger, OSGI_FRAMEWORK_LOG_ERROR, status, "Could not start bundle: %s [%ld]", symbolicName, id); - } - } - - framework_releaseBundleLock(framework, bundle); - } - - return CELIX_SUCCESS; -} - -array_list_pt framework_getBundles(framework_pt framework) { - array_list_pt bundles = NULL; - hash_map_iterator_pt iterator; - arrayList_create(&bundles); - - celixThreadMutex_lock(&framework->installedBundleMapLock); - - iterator = hashMapIterator_create(framework->installedBundleMap); - while (hashMapIterator_hasNext(iterator)) { - bundle_pt bundle = (bundle_pt) hashMapIterator_nextValue(iterator); - arrayList_add(bundles, bundle); - } - hashMapIterator_destroy(iterator); - - celixThreadMutex_unlock(&framework->installedBundleMapLock); - - return bundles; -} - -bundle_pt framework_getBundle(framework_pt framework, const char* location) { - celixThreadMutex_lock(&framework->installedBundleMapLock); - bundle_pt bundle = (bundle_pt) hashMap_get(framework->installedBundleMap, location); - celixThreadMutex_unlock(&framework->installedBundleMapLock); - return bundle; -} - -bundle_pt framework_getBundleById(framework_pt framework, long id) { - celixThreadMutex_lock(&framework->installedBundleMapLock); - hash_map_iterator_pt iter = hashMapIterator_create(framework->installedBundleMap); - bundle_pt bundle = NULL; - while (hashMapIterator_hasNext(iter)) { - bundle_pt b = (bundle_pt) hashMapIterator_nextValue(iter); - bundle_archive_pt archive = NULL; - long bid; - bundle_getArchive(b, &archive); - bundleArchive_getId(archive, &bid); - if (bid == id) { - bundle = b; - break; - } - } - hashMapIterator_destroy(iter); - celixThreadMutex_unlock(&framework->installedBundleMapLock); - - return bundle; -} - -celix_status_t framework_acquireInstallLock(framework_pt framework, const char * location) { - celixThreadMutex_lock(&framework->installRequestLock); - - while (hashMap_get(framework->installRequestMap, location) != NULL) { - celixThreadCondition_wait(&framework->condition, &framework->installRequestLock); - } - hashMap_put(framework->installRequestMap, (char*)location, (char*)location); - - celixThreadMutex_unlock(&framework->installRequestLock); - - return CELIX_SUCCESS; -} - -celix_status_t framework_releaseInstallLock(framework_pt framework, const char* location) { - celixThreadMutex_lock(&framework->installRequestLock); - - hashMap_remove(framework->installRequestMap, location); - celixThreadCondition_broadcast(&framework->condition); - - celixThreadMutex_unlock(&framework->installRequestLock); - - return CELIX_SUCCESS; -} - -celix_status_t framework_setBundleStateAndNotify(framework_pt framework, bundle_pt bundle, int state) { - int ret = CELIX_SUCCESS; - - int err = celixThreadMutex_lock(&framework->bundleLock); - if (err != 0) { - fw_log(framework->logger, OSGI_FRAMEWORK_LOG_ERROR, "Failed to lock"); - return CELIX_BUNDLE_EXCEPTION; - } - - bundle_setState(bundle, state); - err = celixThreadCondition_broadcast(&framework->condition); - if (err != 0) { - fw_log(framework->logger, OSGI_FRAMEWORK_LOG_ERROR, "Failed to broadcast"); - ret = CELIX_BUNDLE_EXCEPTION; - } - - err = celixThreadMutex_unlock(&framework->bundleLock); - if (err != 0) { - fw_log(framework->logger, OSGI_FRAMEWORK_LOG_ERROR, "Failed to unlock"); - return CELIX_BUNDLE_EXCEPTION; - } - return ret; -} - -celix_status_t framework_acquireBundleLock(framework_pt framework, bundle_pt bundle, int desiredStates) { - celix_status_t status = CELIX_SUCCESS; - - bool locked; - celix_thread_t lockingThread = celix_thread_default; - - int err = celixThreadMutex_lock(&framework->bundleLock); - if (err != CELIX_SUCCESS) { - fw_log(framework->logger, OSGI_FRAMEWORK_LOG_ERROR, "Failed to lock"); - status = CELIX_BUNDLE_EXCEPTION; - } else { - bool lockable = false; - bool isSelf = false; - - bundle_isLockable(bundle, &lockable); - thread_equalsSelf(framework->globalLockThread, &isSelf); - - while (!lockable - || (( celixThread_initalized(framework->globalLockThread) == true) - && !isSelf)) - { - bundle_state_e state; - bundle_getState(bundle, &state); - if ((desiredStates & state) == 0) { - status = CELIX_ILLEGAL_STATE; - break; - } - - bundle_getLockingThread(bundle, &lockingThread); - if (isSelf && (celixThread_initalized(lockingThread) == true) - && arrayList_contains(framework->globalLockWaitersList, &lockingThread)) { - framework->interrupted = true; -// celixThreadCondition_signal_thread_np(&framework->condition, bundle_getLockingThread(bundle)); - celixThreadCondition_signal(&framework->condition); - } - - celixThreadCondition_wait(&framework->condition, &framework->bundleLock); - - status = bundle_isLockable(bundle, &lockable); - if (status != CELIX_SUCCESS) { - break; - } - } - - if (status == CELIX_SUCCESS) { - bundle_state_e state; - bundle_getState(bundle, &state); - if ((desiredStates & state) == 0) { - status = CELIX_ILLEGAL_STATE; - } else { - if (bundle_lock(bundle, &locked)) { - if (!locked) { - status = CELIX_ILLEGAL_STATE; - } - } - } - } - celixThreadMutex_unlock(&framework->bundleLock); - } - - framework_logIfError(framework->logger, status, NULL, "Failed to get bundle lock"); - - return status; -} - -bool framework_releaseBundleLock(framework_pt framework, bundle_pt bundle) { - bool unlocked; - celix_thread_t lockingThread = celix_thread_default; - - celixThreadMutex_lock(&framework->bundleLock); - - bundle_unlock(bundle, &unlocked); - if (!unlocked) { - celixThreadMutex_unlock(&framework->bundleLock); - return false; - } - bundle_getLockingThread(bundle, &lockingThread); - if (celixThread_initalized(lockingThread) == false) { - celixThreadCondition_broadcast(&framework->condition); - } - - celixThreadMutex_unlock(&framework->bundleLock); - - return true; -} - -bool framework_acquireGlobalLock(framework_pt framework) { - bool interrupted = false; - bool isSelf = false; - - celixThreadMutex_lock(&framework->bundleLock); - - thread_equalsSelf(framework->globalLockThread, &isSelf); - - while (!interrupted - && (celixThread_initalized(framework->globalLockThread) == true) - && (!isSelf)) { - celix_thread_t currentThread = celixThread_self(); - arrayList_add(framework->globalLockWaitersList, ¤tThread); - celixThreadCondition_broadcast(&framework->condition); - - celixThreadCondition_wait(&framework->condition, &framework->bundleLock); - if (framework->interrupted) { - interrupted = true; - framework->interrupted = false; - } - - arrayList_removeElement(framework->globalLockWaitersList, ¤tThread); - } - - if (!interrupted) { - framework->globalLockCount++; - framework->globalLockThread = celixThread_self(); - } - - celixThreadMutex_unlock(&framework->bundleLock); - - return !interrupted; -} - -celix_status_t framework_releaseGlobalLock(framework_pt framework) { - int status = CELIX_SUCCESS; - if (celixThreadMutex_lock(&framework->bundleLock) != 0) { - fw_log(framework->logger, OSGI_FRAMEWORK_LOG_ERROR, "Error locking framework bundle lock"); - return CELIX_FRAMEWORK_EXCEPTION; - } - - if (celixThread_equals(framework->globalLockThread, celixThread_self())) { - framework->globalLockCount--; - if (framework->globalLockCount == 0) { - framework->globalLockThread = celix_thread_default; - if (celixThreadCondition_broadcast(&framework->condition) != 0) { - fw_log(framework->logger, OSGI_FRAMEWORK_LOG_ERROR, "Failed to broadcast global lock release."); - status = CELIX_FRAMEWORK_EXCEPTION; - // still need to unlock before returning - } - } - } else { - printf("The current thread does not own the global lock"); - } - - if (celixThreadMutex_unlock(&framework->bundleLock) != 0) { - fw_log(framework->logger, OSGI_FRAMEWORK_LOG_ERROR, "Error unlocking framework bundle lock"); - return CELIX_FRAMEWORK_EXCEPTION; - } - - framework_logIfError(framework->logger, status, NULL, "Failed to release global lock"); - - return status; -} - -celix_status_t framework_waitForStop(framework_pt framework) { - if (celixThreadMutex_lock(&framework->mutex) != 0) { - fw_log(framework->logger, OSGI_FRAMEWORK_LOG_ERROR, "Error locking the framework, shutdown gate not set."); - return CELIX_FRAMEWORK_EXCEPTION; - } - while (!framework->shutdown) { - celix_status_t status = celixThreadCondition_wait(&framework->shutdownGate, &framework->mutex); - if (status != 0) { - fw_log(framework->logger, OSGI_FRAMEWORK_LOG_ERROR, "Error waiting for shutdown gate."); - return CELIX_FRAMEWORK_EXCEPTION; - } - } - if (celixThreadMutex_unlock(&framework->mutex) != 0) { - fw_log(framework->logger, OSGI_FRAMEWORK_LOG_ERROR, "Error unlocking the framework."); - return CELIX_FRAMEWORK_EXCEPTION; - } - - celixThread_join(framework->shutdownThread, NULL); - - fw_log(framework->logger, OSGI_FRAMEWORK_LOG_INFO, "FRAMEWORK: Successful shutdown"); - return CELIX_SUCCESS; -} - -static void *framework_shutdown(void *framework) { - framework_pt fw = (framework_pt) framework; - int err; - - fw_log(fw->logger, OSGI_FRAMEWORK_LOG_INFO, "FRAMEWORK: Shutdown"); - celixThreadMutex_lock(&fw->installedBundleMapLock); - - hash_map_iterator_pt iter = hashMapIterator_create(fw->installedBundleMap); - bundle_pt bundle = NULL; - while ((bundle = hashMapIterator_nextValue(iter)) != NULL) { - bundle_state_e state; - bundle_getState(bundle, &state); - if (state == OSGI_FRAMEWORK_BUNDLE_ACTIVE || state == OSGI_FRAMEWORK_BUNDLE_STARTING) { - celixThreadMutex_unlock(&fw->installedBundleMapLock); - fw_stopBundle(fw, bundle, 0); - celixThreadMutex_lock(&fw->installedBundleMapLock); - hashMapIterator_destroy(iter); - iter = hashMapIterator_create(fw->installedBundleMap); - } - } - hashMapIterator_destroy(iter); - - iter = hashMapIterator_create(fw->installedBundleMap); - bundle = NULL; - while ((bundle = hashMapIterator_nextValue(iter)) != NULL) { - bundle_close(bundle); - } - hashMapIterator_destroy(iter); - celixThreadMutex_unlock(&fw->installedBundleMapLock); - - err = celixThreadMutex_lock(&fw->mutex); - if (err != 0) { - fw_log(fw->logger, OSGI_FRAMEWORK_LOG_ERROR, "Error locking the framework, cannot exit clean."); - celixThread_exit(NULL); - return NULL; - } - - if (celixThreadMutex_lock(&fw->dispatcherLock) != CELIX_SUCCESS) { - fw_log(fw->logger, OSGI_FRAMEWORK_LOG_ERROR, "Error locking the dispatcherThread."); - } - else { - fw->shutdown = true; - - if (celixThreadCondition_broadcast(&fw->dispatcher)) { - fw_log(fw->logger, OSGI_FRAMEWORK_LOG_ERROR, "Error broadcasting ."); - } - - if (celixThreadMutex_unlock(&fw->dispatcherLock)) { - fw_log(fw->logger, OSGI_FRAMEWORK_LOG_ERROR, "Error unlocking the dispatcherThread."); - } - - celixThread_join(fw->dispatcherThread, NULL); - } - - - err = celixThreadCondition_broadcast(&fw->shutdownGate); - if (err != 0) { - fw_log(fw->logger, OSGI_FRAMEWORK_LOG_ERROR, "Error waking the shutdown gate, cannot exit clean."); - err = celixThreadMutex_unlock(&fw->mutex); - if (err != 0) { - fw_log(fw->logger, OSGI_FRAMEWORK_LOG_ERROR, "Error unlocking the framework, cannot exit clean."); - } - - celixThread_exit(NULL); - return NULL; - } - err = celixThreadMutex_unlock(&fw->mutex); - if (err != 0) { -// fw_log(fw->logger, OSGI_FRAMEWORK_LOG_ERROR, "Error unlocking the framework, cannot exit clean."); - } - -// fw_log(fw->logger, OSGI_FRAMEWORK_LOG_INFO, "FRAMEWORK: Shutdown done\n"); - celixThread_exit((void *) CELIX_SUCCESS); - - return NULL; -} - -celix_status_t framework_getFrameworkBundle(framework_pt framework, bundle_pt *bundle) { - celix_status_t status = CELIX_SUCCESS; - - if (framework != NULL && *bundle == NULL) { - *bundle = framework->bundle; - } else { - status = CELIX_ILLEGAL_ARGUMENT; - } - - return status; -} - -celix_status_t fw_fireBundleEvent(framework_pt framework, bundle_event_type_e eventType, bundle_pt bundle) { - celix_status_t status = CELIX_SUCCESS; - - if ((eventType != OSGI_FRAMEWORK_BUNDLE_EVENT_STARTING) - && (eventType != OSGI_FRAMEWORK_BUNDLE_EVENT_STOPPING) - && (eventType != OSGI_FRAMEWORK_BUNDLE_EVENT_LAZY_ACTIVATION)) { - request_pt request = (request_pt) calloc(1, sizeof(*request)); - if (!request) { - status = CELIX_ENOMEM; - } else { - bundle_archive_pt archive = NULL; - module_pt module = NULL; - - request->eventType = eventType; - request->filter = NULL; - request->listeners = framework->bundleListeners; - request->type = BUNDLE_EVENT_TYPE; - request->error = NULL; - request->bundleId = -1; - - status = bundle_getArchive(bundle, &archive); - - if (status == CELIX_SUCCESS) { - long bundleId; - - status = bundleArchive_getId(archive, &bundleId); - - if (status == CELIX_SUCCESS) { - request->bundleId = bundleId; - } - } - - if (status == CELIX_SUCCESS) { - status = bundle_getCurrentModule(bundle, &module); - - if (status == CELIX_SUCCESS) { - const char *symbolicName = NULL; - status = module_getSymbolicName(module, &symbolicName); - if (status == CELIX_SUCCESS) { - request->bundleSymbolicName = strdup(symbolicName); - } - } - } - - if (celixThreadMutex_lock(&framework->dispatcherLock) != CELIX_SUCCESS) { - status = CELIX_FRAMEWORK_EXCEPTION; - } else { - arrayList_