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) {

Reply via email to