PengZheng commented on code in PR #476: URL: https://github.com/apache/celix/pull/476#discussion_r1112722663
########## libs/framework/src/module.c: ########## @@ -319,4 +351,172 @@ array_list_pt module_getDependents(module_pt module) { arrayList_addAll(dependents, module->dependentImporters); return dependents; -} \ No newline at end of file +} + +celix_status_t celix_module_closeLibraries(celix_module_t* module) { + celix_status_t status = CELIX_SUCCESS; + celix_bundle_context_t *fwCtx = celix_framework_getFrameworkContext(module->fw); + celixThreadMutex_lock(&module->handlesLock); + for (int i = 0; i < celix_arrayList_size(module->libraryHandles); i++) { + void *handle = celix_arrayList_get(module->libraryHandles, i); + celix_libloader_close(fwCtx, handle); + } + celix_arrayList_clear(module->libraryHandles); + module->bundleActivatorHandle = NULL; + celixThreadMutex_unlock(&module->handlesLock); + return status; +} + +static celix_status_t celix_module_loadLibrary(celix_module_t* module, const char* path, void** handle) { + celix_status_t status = CELIX_SUCCESS; + celix_bundle_context_t *fwCtx = celix_framework_getFrameworkContext(module->fw); + void *libHandle = celix_libloader_open(fwCtx, path); + if (libHandle == NULL) { + status = CELIX_BUNDLE_EXCEPTION; + const char* error = celix_libloader_getLastError(); + fw_logCode(module->fw->logger, CELIX_LOG_LEVEL_ERROR, status, "Cannot open library %s: %s", path, error); + } else { + celixThreadMutex_lock(&module->handlesLock); + celix_arrayList_add(module->libraryHandles, libHandle); + celixThreadMutex_unlock(&module->handlesLock); + *handle = libHandle; + } + return status; +} + + +static celix_status_t celix_module_loadLibraryForManifestEntry(celix_module_t* module, const char *library, bundle_archive_pt archive, void **handle) { + celix_status_t status = CELIX_SUCCESS; + + const char *error = NULL; + char libraryPath[512]; + const char* revRoot = celix_bundleArchive_getCurrentRevisionRoot(archive); + + if (!revRoot) { + fw_logCode(module->fw->logger, CELIX_LOG_LEVEL_ERROR, status, "Could not get bundle archive information"); + return status; + } + + char* path; + if (strstr(library, CELIX_LIBRARY_EXTENSION)) { + path = celix_utils_writeOrCreateString(libraryPath, sizeof(libraryPath), "%s/%s", revRoot, library); + } else { + path = celix_utils_writeOrCreateString(libraryPath, sizeof(libraryPath), "%s/%s%s%s", revRoot, CELIX_LIBRARY_PREFIX, library, CELIX_LIBRARY_EXTENSION); + } + + if (!path) { + fw_logCode(module->fw->logger, CELIX_LOG_LEVEL_ERROR, status, "Cannot create full library path"); + return status; + } + + status = celix_module_loadLibrary(module, path, handle); + celix_utils_freeStringIfNeeded(libraryPath, path); + framework_logIfError(module->fw->logger, status, error, "Could not load library: %s", libraryPath); + return status; +} + +static celix_status_t celix_module_loadLibrariesInManifestEntry(celix_module_t* module, const char *librariesIn, const char *activator, bundle_archive_pt archive, void **activatorHandle) { + celix_status_t status = CELIX_SUCCESS; + celix_bundle_context_t* fwCtx = celix_framework_getFrameworkContext(module->fw); + + char* last; + char* libraries = strndup(librariesIn, 1024*10); + char* token = strtok_r(libraries, ",", &last); + while (token != NULL) { + void *handle = NULL; + char lib[128]; + lib[127] = '\0'; + + char *path = NULL; + char *pathToken = strtok_r(token, ";", &path); + strncpy(lib, pathToken, 127); + pathToken = strtok_r(NULL, ";", &path); + + while (pathToken != NULL) { + + /*Disable version should be part of the lib name + if (strncmp(pathToken, "version", 7) == 0) { + char *ver = strdup(pathToken); + char version[strlen(ver) - 9]; + strncpy(version, ver+9, strlen(ver) - 10); + version[strlen(ver) - 10] = '\0'; + + strcat(lib, "-"); + strcat(lib, version); + }*/ + pathToken = strtok_r(NULL, ";", &path); + } + + char *trimmedLib = utils_stringTrim(lib); + status = celix_module_loadLibraryForManifestEntry(module, trimmedLib, archive, &handle); + + if ( (status == CELIX_SUCCESS) && (activator != NULL) && (strcmp(trimmedLib, activator) == 0) ) { + *activatorHandle = handle; + } + else if (handle!=NULL) { + celix_libloader_close(fwCtx, handle); Review Comment: `handle` has already been added to `module->libraryHandles`, closing it will lead to double-close in `celix_module_closeLibraries`. This is reported by @tira-misu in #479. ########## libs/framework/src/module.c: ########## @@ -319,4 +351,172 @@ array_list_pt module_getDependents(module_pt module) { arrayList_addAll(dependents, module->dependentImporters); return dependents; -} \ No newline at end of file +} + +celix_status_t celix_module_closeLibraries(celix_module_t* module) { + celix_status_t status = CELIX_SUCCESS; + celix_bundle_context_t *fwCtx = celix_framework_getFrameworkContext(module->fw); + celixThreadMutex_lock(&module->handlesLock); + for (int i = 0; i < celix_arrayList_size(module->libraryHandles); i++) { + void *handle = celix_arrayList_get(module->libraryHandles, i); + celix_libloader_close(fwCtx, handle); + } + celix_arrayList_clear(module->libraryHandles); + module->bundleActivatorHandle = NULL; + celixThreadMutex_unlock(&module->handlesLock); + return status; +} + +static celix_status_t celix_module_loadLibrary(celix_module_t* module, const char* path, void** handle) { + celix_status_t status = CELIX_SUCCESS; + celix_bundle_context_t *fwCtx = celix_framework_getFrameworkContext(module->fw); + void *libHandle = celix_libloader_open(fwCtx, path); + if (libHandle == NULL) { + status = CELIX_BUNDLE_EXCEPTION; + const char* error = celix_libloader_getLastError(); + fw_logCode(module->fw->logger, CELIX_LOG_LEVEL_ERROR, status, "Cannot open library %s: %s", path, error); + } else { + celixThreadMutex_lock(&module->handlesLock); + celix_arrayList_add(module->libraryHandles, libHandle); + celixThreadMutex_unlock(&module->handlesLock); + *handle = libHandle; + } + return status; +} + + +static celix_status_t celix_module_loadLibraryForManifestEntry(celix_module_t* module, const char *library, bundle_archive_pt archive, void **handle) { + celix_status_t status = CELIX_SUCCESS; + + const char *error = NULL; + char libraryPath[512]; + const char* revRoot = celix_bundleArchive_getCurrentRevisionRoot(archive); + + if (!revRoot) { + fw_logCode(module->fw->logger, CELIX_LOG_LEVEL_ERROR, status, "Could not get bundle archive information"); + return status; + } + + char* path; + if (strstr(library, CELIX_LIBRARY_EXTENSION)) { + path = celix_utils_writeOrCreateString(libraryPath, sizeof(libraryPath), "%s/%s", revRoot, library); + } else { + path = celix_utils_writeOrCreateString(libraryPath, sizeof(libraryPath), "%s/%s%s%s", revRoot, CELIX_LIBRARY_PREFIX, library, CELIX_LIBRARY_EXTENSION); + } + + if (!path) { + fw_logCode(module->fw->logger, CELIX_LOG_LEVEL_ERROR, status, "Cannot create full library path"); + return status; + } + + status = celix_module_loadLibrary(module, path, handle); + celix_utils_freeStringIfNeeded(libraryPath, path); + framework_logIfError(module->fw->logger, status, error, "Could not load library: %s", libraryPath); + return status; +} + +static celix_status_t celix_module_loadLibrariesInManifestEntry(celix_module_t* module, const char *librariesIn, const char *activator, bundle_archive_pt archive, void **activatorHandle) { + celix_status_t status = CELIX_SUCCESS; + celix_bundle_context_t* fwCtx = celix_framework_getFrameworkContext(module->fw); + + char* last; + char* libraries = strndup(librariesIn, 1024*10); + char* token = strtok_r(libraries, ",", &last); + while (token != NULL) { + void *handle = NULL; + char lib[128]; + lib[127] = '\0'; + + char *path = NULL; + char *pathToken = strtok_r(token, ";", &path); + strncpy(lib, pathToken, 127); + pathToken = strtok_r(NULL, ";", &path); + + while (pathToken != NULL) { + + /*Disable version should be part of the lib name + if (strncmp(pathToken, "version", 7) == 0) { + char *ver = strdup(pathToken); + char version[strlen(ver) - 9]; + strncpy(version, ver+9, strlen(ver) - 10); + version[strlen(ver) - 10] = '\0'; + + strcat(lib, "-"); + strcat(lib, version); + }*/ + pathToken = strtok_r(NULL, ";", &path); + } + + char *trimmedLib = utils_stringTrim(lib); + status = celix_module_loadLibraryForManifestEntry(module, trimmedLib, archive, &handle); + + if ( (status == CELIX_SUCCESS) && (activator != NULL) && (strcmp(trimmedLib, activator) == 0) ) { + *activatorHandle = handle; + } + else if (handle!=NULL) { + celix_libloader_close(fwCtx, handle); + } + + token = strtok_r(NULL, ",", &last); + } + + free(libraries); + return status; +} + +celix_status_t celix_module_loadLibraries(celix_module_t* module) { + celix_status_t status = CELIX_SUCCESS; + celix_bundle_context_t* fwCtx = celix_framework_getFrameworkContext(module->fw); + + celix_library_handle_t* activatorHandle = NULL; + bundle_archive_pt archive = NULL; + bundle_revision_pt revision = NULL; + manifest_pt manifest = NULL; + + status = CELIX_DO_IF(status, bundle_getArchive(module->bundle, &archive)); + status = CELIX_DO_IF(status, bundleArchive_getCurrentRevision(archive, &revision)); + status = CELIX_DO_IF(status, bundleRevision_getManifest(revision, &manifest)); + if (status == CELIX_SUCCESS) { + const char *privateLibraries = NULL; + const char *exportLibraries = NULL; + const char *activator = NULL; + + privateLibraries = manifest_getValue(manifest, CELIX_FRAMEWORK_PRIVATE_LIBRARY); + exportLibraries = manifest_getValue(manifest, CELIX_FRAMEWORK_EXPORT_LIBRARY); + //@note not import yet + activator = manifest_getValue(manifest, CELIX_FRAMEWORK_BUNDLE_ACTIVATOR); + + if (exportLibraries != NULL) { + status = CELIX_DO_IF(status, celix_module_loadLibrariesInManifestEntry(module, exportLibraries, activator, archive, &activatorHandle)); + } + + if (privateLibraries != NULL) { + status = CELIX_DO_IF(status, + celix_module_loadLibrariesInManifestEntry(module, privateLibraries, activator, archive, &activatorHandle)); + } + + if (status == CELIX_SUCCESS) { + bundle_setHandle(module->bundle, activatorHandle); //note deprecated + celixThreadMutex_lock(&module->handlesLock); + module->bundleActivatorHandle = activatorHandle; + celixThreadMutex_unlock(&module->handlesLock); + } else if (activatorHandle != NULL) { + celix_libloader_close(fwCtx, activatorHandle); Review Comment: Double-close? -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: dev-unsubscr...@celix.apache.org For queries about this service, please contact Infrastructure at: us...@infra.apache.org