This is an automated email from the ASF dual-hosted git repository. pengzheng pushed a commit to branch hotfix/framework-startup-optimization in repository https://gitbox.apache.org/repos/asf/celix.git
The following commit(s) were added to refs/heads/hotfix/framework-startup-optimization by this push: new 523a31a4 Force bundle cache update when using a different bundle location. 523a31a4 is described below commit 523a31a47bf63fd8f3baa9044a8971e1d7b194e9 Author: PengZheng <howto...@gmail.com> AuthorDate: Wed Aug 2 18:17:13 2023 +0800 Force bundle cache update when using a different bundle location. --- .../src/CelixBundleCacheErrorInjectionTestSuite.cc | 12 -------- .../gtest/src/CelixBundleCacheTestSuite.cc | 8 ++++-- libs/framework/src/bundle_archive.c | 33 ++++++++++++++++++++-- libs/framework/src/bundle_archive_private.h | 5 ++++ libs/framework/src/celix_bundle_cache.c | 12 ++++---- libs/framework/src/celix_bundle_cache.h | 9 ++---- libs/framework/src/framework.c | 6 +++- 7 files changed, 52 insertions(+), 33 deletions(-) diff --git a/libs/framework/gtest/src/CelixBundleCacheErrorInjectionTestSuite.cc b/libs/framework/gtest/src/CelixBundleCacheErrorInjectionTestSuite.cc index 7f0896c5..3e4d66d4 100644 --- a/libs/framework/gtest/src/CelixBundleCacheErrorInjectionTestSuite.cc +++ b/libs/framework/gtest/src/CelixBundleCacheErrorInjectionTestSuite.cc @@ -147,18 +147,6 @@ TEST_F(CelixBundleCacheErrorInjectionTestSuite, SystemArchiveCreateErrorTest) { EXPECT_EQ(CELIX_SUCCESS, celix_bundleCache_destroy(cache)); } -TEST_F(CelixBundleCacheErrorInjectionTestSuite, ArchiveDestroyErrorTest) { - celix_bundle_cache_t* cache = nullptr; - createCache(&cache); - bundle_archive_t* archive = nullptr; - EXPECT_EQ(CELIX_SUCCESS, celix_bundleCache_createArchive(cache, 1, SIMPLE_TEST_BUNDLE1_LOCATION, &archive)); - celix_ei_expect_celix_utils_deleteDirectory((void*)celix_bundleCache_destroyArchive, 1, CELIX_FILE_IO_EXCEPTION); - std::string storeRoot = celix_bundleArchive_getPersistentStoreRoot(archive); - EXPECT_EQ(CELIX_FILE_IO_EXCEPTION, celix_bundleCache_destroyArchive(cache, archive, true)); - EXPECT_TRUE(celix_utils_directoryExists(storeRoot.c_str())); - EXPECT_EQ(CELIX_SUCCESS, celix_bundleCache_destroy(cache)); -} - TEST_F(CelixBundleCacheErrorInjectionTestSuite, CreateBundleArchivesCacheErrorTest) { celix_bundle_cache_t* cache = nullptr; celix_properties_set(fw.configurationMap, CELIX_AUTO_START_1, SIMPLE_TEST_BUNDLE1_LOCATION); diff --git a/libs/framework/gtest/src/CelixBundleCacheTestSuite.cc b/libs/framework/gtest/src/CelixBundleCacheTestSuite.cc index c37ef142..42e397c5 100644 --- a/libs/framework/gtest/src/CelixBundleCacheTestSuite.cc +++ b/libs/framework/gtest/src/CelixBundleCacheTestSuite.cc @@ -58,7 +58,8 @@ TEST_F(CelixBundleCacheTestSuite, ArchiveCreateDestroyTest) { EXPECT_TRUE(celix_bundleCache_isBundleIdAlreadyUsed(fw.cache, 1)); std::string loc = celix_bundleArchive_getPersistentStoreRoot(archive); EXPECT_TRUE(celix_utils_directoryExists(loc.c_str())); - EXPECT_EQ(CELIX_SUCCESS, celix_bundleCache_destroyArchive(fw.cache, archive, true)); + celix_bundleArchive_invalidate(archive); + celix_bundleCache_destroyArchive(fw.cache, archive); EXPECT_EQ(-1, celix_bundleCache_findBundleIdForLocation(fw.cache, SIMPLE_TEST_BUNDLE1_LOCATION)); EXPECT_FALSE(celix_bundleCache_isBundleIdAlreadyUsed(fw.cache, 1)); EXPECT_FALSE(celix_utils_directoryExists(loc.c_str())); @@ -70,7 +71,7 @@ TEST_F(CelixBundleCacheTestSuite, NonPermanentDestroyTest) { EXPECT_NE(nullptr, archive); std::string loc = celix_bundleArchive_getPersistentStoreRoot(archive); EXPECT_TRUE(celix_utils_directoryExists(loc.c_str())); - EXPECT_EQ(CELIX_SUCCESS, celix_bundleCache_destroyArchive(fw.cache, archive, false)); + celix_bundleCache_destroyArchive(fw.cache, archive); EXPECT_EQ(1, celix_bundleCache_findBundleIdForLocation(fw.cache, SIMPLE_TEST_BUNDLE1_LOCATION)); EXPECT_TRUE(celix_bundleCache_isBundleIdAlreadyUsed(fw.cache, 1)); EXPECT_TRUE(celix_utils_directoryExists(loc.c_str())); @@ -85,7 +86,8 @@ TEST_F(CelixBundleCacheTestSuite, SystemArchiveCreateDestroyTest) { EXPECT_EQ(CELIX_SUCCESS, bundleArchive_getArchiveRoot(archive, &archiveRoot)); EXPECT_EQ(nullptr, archiveRoot); EXPECT_EQ(nullptr, celix_bundleArchive_getLocation(archive)); - EXPECT_EQ(CELIX_SUCCESS, celix_bundleCache_destroyArchive(fw.cache, archive, true)); + celix_bundleArchive_invalidate(archive); + celix_bundleCache_destroyArchive(fw.cache, archive); } TEST_F(CelixBundleCacheTestSuite, CreateBundleArchivesCacheTest) { diff --git a/libs/framework/src/bundle_archive.c b/libs/framework/src/bundle_archive.c index 37f5ed2c..ee60ffe0 100644 --- a/libs/framework/src/bundle_archive.c +++ b/libs/framework/src/bundle_archive.c @@ -54,10 +54,10 @@ struct bundleArchive { char* resourceCacheRoot; char* bundleSymbolicName; // read from the manifest char* bundleVersion; // read from the manifest - - celix_thread_mutex_t lock; // protects below and saving of bundle state properties bundle_revision_t* revision; // the current revision char* location; + bool cacheValid; // is the cache valid (e.g. not deleted) + bool valid; // is the archive valid (e.g. not deleted) }; static celix_status_t celix_bundleArchive_storeBundleStateProperties(bundle_archive_pt archive) { @@ -304,7 +304,8 @@ celix_status_t celix_bundleArchive_create(celix_framework_t* fw, const char *arc goto store_prop_failed; } } - + archive->cacheValid = true; + archive->valid = true; *bundle_archive = archive; return CELIX_SUCCESS; store_prop_failed: @@ -466,3 +467,29 @@ const char* celix_bundleArchive_getCurrentRevisionRoot(bundle_archive_t* archive } +void celix_bundleArchive_invalidate(bundle_archive_pt archive) { + archive->valid = false; + archive->cacheValid = false; +} + +void celix_bundleArchive_invalidateCache(bundle_archive_pt archive) { + archive->cacheValid = false; +} + +bool celix_bundleArchive_isCacheValid(bundle_archive_pt archive) { + return archive->cacheValid; +} + +void celix_bundleArchive_removeInvalidDirs(bundle_archive_pt archive) { + if (archive->id == CELIX_FRAMEWORK_BUNDLE_ID) { + return; + } + if (!archive->valid) { + celix_status_t status = CELIX_SUCCESS; + const char* err = NULL; + status = celix_utils_deleteDirectory(archive->archiveRoot, &err); + framework_logIfError(archive->fw->logger, status, NULL, "Failed to remove invalid archive root '%s': %s", archive->archiveRoot, err); + } else if (!archive->cacheValid){ + (void)celix_bundleArchive_removeResourceCache(archive); + } +} diff --git a/libs/framework/src/bundle_archive_private.h b/libs/framework/src/bundle_archive_private.h index d777ea50..1fe326fc 100644 --- a/libs/framework/src/bundle_archive_private.h +++ b/libs/framework/src/bundle_archive_private.h @@ -75,6 +75,11 @@ const char* celix_bundleArchive_getPersistentStoreRoot(bundle_archive_t *archive */ const char* celix_bundleArchive_getCurrentRevisionRoot(bundle_archive_pt archive); +void celix_bundleArchive_invalidate(bundle_archive_pt archive); +void celix_bundleArchive_invalidateCache(bundle_archive_pt archive); +bool celix_bundleArchive_isCacheValid(bundle_archive_pt archive); +void celix_bundleArchive_removeInvalidDirs(bundle_archive_pt archive); + #ifdef __cplusplus } #endif diff --git a/libs/framework/src/celix_bundle_cache.c b/libs/framework/src/celix_bundle_cache.c index 059c26a4..f69d03da 100644 --- a/libs/framework/src/celix_bundle_cache.c +++ b/libs/framework/src/celix_bundle_cache.c @@ -230,18 +230,16 @@ celix_status_t celix_bundleCache_createSystemArchive(celix_framework_t* fw, bund return celix_bundleCache_createArchive(fw->cache, CELIX_FRAMEWORK_BUNDLE_ID, NULL, archive); } -celix_status_t celix_bundleCache_destroyArchive(celix_bundle_cache_t* cache, bundle_archive_pt archive, bool permanent) { - celix_status_t status = CELIX_SUCCESS; - const char* loc = NULL; +void celix_bundleCache_destroyArchive(celix_bundle_cache_t* cache, bundle_archive_pt archive) { celixThreadMutex_lock(&cache->mutex); - if (permanent) { + if (!celix_bundleArchive_isCacheValid(archive)) { + const char* loc = NULL; (void) bundleArchive_getLocation(archive, &loc); (void) celix_stringHashMap_remove(cache->locationToBundleIdLookupMap, loc); - status = bundleArchive_closeAndDelete(archive); } + (void)celix_bundleArchive_removeInvalidDirs(archive); celixThreadMutex_unlock(&cache->mutex); - (void) bundleArchive_destroy(archive); - return status; + bundleArchive_destroy(archive); } /** diff --git a/libs/framework/src/celix_bundle_cache.h b/libs/framework/src/celix_bundle_cache.h index fb093705..309138b8 100644 --- a/libs/framework/src/celix_bundle_cache.h +++ b/libs/framework/src/celix_bundle_cache.h @@ -91,16 +91,11 @@ celix_status_t celix_bundleCache_createSystemArchive(celix_framework_t* fw, bund /** * @brief Destroy the archive from the cache. - * It releases all resources allocated in celix_bundleCache_createArchive and deletes the archive directory if requested. + * It releases all resources allocated in celix_bundleCache_createArchive and deletes the invalid directories if needed. * @param [in] cache The bundle cache to destroy archive from. * @param [in] archive The archive to destroy. - * @param [in] permanent Whether the archive directory should be deleted or not. - * @return Status code indication failure or success: - * - CELIX_SUCCESS when no errors are encountered. - * - CELIX_FILE_IO_EXCEPTION when root of the archive is not a directory. - * - errno when the directory cannot be deleted for other reasons, check error codes of fts_open/fts_read/remove. */ -celix_status_t celix_bundleCache_destroyArchive(celix_bundle_cache_t* cache, bundle_archive_pt archive, bool permanent); +void celix_bundleCache_destroyArchive(celix_bundle_cache_t* cache, bundle_archive_pt archive); /** * @brief Deletes the entire bundle cache. diff --git a/libs/framework/src/framework.c b/libs/framework/src/framework.c index 3f4c6bf7..c5fed072 100644 --- a/libs/framework/src/framework.c +++ b/libs/framework/src/framework.c @@ -2010,7 +2010,10 @@ static celix_status_t celix_framework_uninstallBundleEntryImpl(celix_framework_t celix_framework_waitForEmptyEventQueue(framework); //to ensure that the uninstall event is triggered and handled (void)bundle_closeModules(bnd); (void)bundle_destroy(bnd); - (void)celix_bundleCache_destroyArchive(framework->cache, archive, permanent); + if(permanent) { + celix_bundleArchive_invalidate(archive); + } + (void)celix_bundleCache_destroyArchive(framework->cache, archive); } framework_logIfError(framework->logger, status, "", "Cannot uninstall bundle"); return status; @@ -2359,6 +2362,7 @@ celix_status_t celix_framework_updateBundleEntry(celix_framework_t* framework, status = CELIX_ILLEGAL_STATE; break; } + celix_bundleArchive_invalidateCache(celix_bundle_getArchive(bndEntry->bnd)); } status = celix_framework_uninstallBundleEntryImpl(framework, bndEntry, false); if (status != CELIX_SUCCESS) {