This is an automated email from the ASF dual-hosted git repository.

pengzheng pushed a commit to branch feature/refactor_bundle_cache
in repository https://gitbox.apache.org/repos/asf/celix.git


The following commit(s) were added to refs/heads/feature/refactor_bundle_cache 
by this push:
     new 381f7ad3 Fix corner case deadlock and simplify 
`celix_bundleArchive_getLastModifiedInternal`
381f7ad3 is described below

commit 381f7ad3fa2cc99e1f454e54a85475edf0c53744
Author: PengZheng <[email protected]>
AuthorDate: Fri Mar 24 16:17:13 2023 +0800

    Fix corner case deadlock and simplify 
`celix_bundleArchive_getLastModifiedInternal`
---
 libs/framework/include/bundle_archive.h |  2 +-
 libs/framework/src/bundle_archive.c     | 38 +++++++++++++++------------------
 libs/framework/src/framework.c          | 11 +---------
 3 files changed, 19 insertions(+), 32 deletions(-)

diff --git a/libs/framework/include/bundle_archive.h 
b/libs/framework/include/bundle_archive.h
index 74358a37..93c371c6 100644
--- a/libs/framework/include/bundle_archive.h
+++ b/libs/framework/include/bundle_archive.h
@@ -87,7 +87,7 @@ FRAMEWORK_EXPORT celix_status_t 
bundleArchive_getPersistentState(bundle_archive_
  * @param[in] archive The bundle archive.
  * @param[out] lastModified The last modified time of the bundle archive.
  * @return CELIX_SUCCESS if the last modified time could be retrieved, 
CELIX_FILE_IO_EXCEPTION if the last modified
- * time could not be retrieved.
+ * time could not be retrieved. Check errno for more specific error 
information.
  */
 FRAMEWORK_EXPORT celix_status_t 
celix_bundleArchive_getLastModified(bundle_archive_pt archive, struct timespec* 
lastModified);
 
diff --git a/libs/framework/src/bundle_archive.c 
b/libs/framework/src/bundle_archive.c
index 43cbc8c8..d644f5b9 100644
--- a/libs/framework/src/bundle_archive.c
+++ b/libs/framework/src/bundle_archive.c
@@ -92,7 +92,7 @@ celix_status_t celix_bundleArchive_extractBundle(
     bool extractBundle = true;
 
     //check if bundle location is newer than current revision
-    if (revisionModificationTime->tv_sec != 0 && 
revisionModificationTime->tv_nsec != 0) {
+    if (revisionModificationTime != NULL) {
         extractBundle = 
celix_framework_utils_isBundleUrlNewerThan(archive->fw, bundleUrl, 
revisionModificationTime);
     }
 
@@ -168,13 +168,14 @@ celix_status_t 
celix_bundleArchive_createCacheDirectory(bundle_archive_pt archiv
     //get revision mod time;
     struct timespec revisionMod;
     status = celix_bundleArchive_getLastModifiedInternal(archive, 
&revisionMod);
-    if (status != CELIX_SUCCESS) {
+    if (status != CELIX_SUCCESS && errno != ENOENT) {
         fw_logCode(archive->fw->logger, CELIX_LOG_LEVEL_ERROR, status, "Failed 
to get last modified time for bundle archive revision directory '%s'", 
archive->resourceCacheRoot);
         return status;
     }
 
     //extract bundle zip to revision directory
-    status = celix_bundleArchive_extractBundle(archive, 
archive->resourceCacheRoot, archive->location, &revisionMod);
+    status = celix_bundleArchive_extractBundle(archive, 
archive->resourceCacheRoot, archive->location,
+                                               status == CELIX_SUCCESS ? 
&revisionMod : NULL);
     if (status != CELIX_SUCCESS) {
         fw_log(archive->fw->logger, CELIX_LOG_LEVEL_ERROR, "Failed to 
initialize archive. Failed to extract bundle.");
         return status;
@@ -374,12 +375,7 @@ celix_status_t 
celix_bundleArchive_getLastModifiedInternal(bundle_archive_pt arc
     celix_status_t status = CELIX_SUCCESS;
     char manifestPathBuffer[CELIX_DEFAULT_STRING_CREATE_BUFFER_SIZE];
     char* manifestPath = celix_utils_writeOrCreateString(manifestPathBuffer, 
sizeof(manifestPathBuffer), "%s/%s", archive->resourceCacheRoot, 
CELIX_BUNDLE_MANIFEST_REL_PATH);
-    if (celix_utils_fileExists(manifestPath)) {
-        status = celix_utils_getLastModified(manifestPath, lastModified);
-    } else {
-        lastModified->tv_sec = 0;
-        lastModified->tv_nsec = 0;
-    }
+    status = celix_utils_getLastModified(manifestPath, lastModified);
     celix_utils_freeStringIfNotEqual(manifestPathBuffer, manifestPath);
     return status;
 }
@@ -396,39 +392,42 @@ celix_status_t 
bundleArchive_setLastModified(bundle_archive_pt archive __attribu
     return celix_utils_touch(archive->archiveRoot);
 }
 
-celix_status_t bundleArchive_revise(bundle_archive_pt archive, const char * 
location, const char *updatedBundleUrl) {
+celix_status_t bundleArchive_revise(bundle_archive_pt archive, const char * 
location __attribute__((unused)), const char *updatedBundleUrl) {
     celixThreadMutex_lock(&archive->lock);
 
     const char* updateUrl = archive->location;
-    if (updatedBundleUrl != NULL && strcmp(archive->location, 
updatedBundleUrl) != 0) {
+    if (updatedBundleUrl != NULL && strcmp(updateUrl, updatedBundleUrl) != 0) {
         fw_log(archive->fw->logger, CELIX_LOG_LEVEL_INFO, "Updating bundle 
archive bundle url location to %s", updatedBundleUrl);
         updateUrl = updatedBundleUrl;
     }
 
     struct timespec lastModified;
+    const char *reason = NULL;
     celix_bundleArchive_getLastModifiedInternal(archive, &lastModified);
     celix_status_t status = celix_bundleArchive_extractBundle(archive, 
archive->resourceCacheRoot, updateUrl, &lastModified);
     if (status == CELIX_SUCCESS) {
         bundle_revision_t* current = archive->revision;
-        bundle_revision_t* revised = bundleRevision_revise(current, 
updatedBundleUrl);
+        bundle_revision_t* revised = bundleRevision_revise(current, updateUrl);
         if (revised != NULL) {
             archive->revision = revised;
             bundleRevision_destroy(current);
         } else {
             status = CELIX_BUNDLE_EXCEPTION;
-            fw_logCode(archive->fw->logger, CELIX_LOG_LEVEL_ERROR, status, 
"Cannot revise bundle archive %s", archive->location);
-            return status;
+            reason = "bundle revision creation";
         }
     } else {
-        fw_log(archive->fw->logger, CELIX_LOG_LEVEL_ERROR,
-               "Cannot update bundle archive %s, error during bundle 
extraction.", updateUrl);
-        return status;
+        reason = "bundle extraction";
+    }
+    if (status != CELIX_SUCCESS) {
+        goto revise_finished;
     }
     if (archive->location != updateUrl) {
         free(archive->location);
         archive->location = celix_utils_strdup(updateUrl);
     }
+revise_finished:
     celixThreadMutex_unlock(&archive->lock);
+    framework_logIfError(archive->fw->logger, status, reason, "Cannot update 
bundle archive %s", updatedBundleUrl);
     return status;
 }
 
@@ -465,10 +464,7 @@ const char* 
celix_bundleArchive_getPersistentStoreRoot(bundle_archive_t* archive
 }
 
 const char* celix_bundleArchive_getCurrentRevisionRoot(bundle_archive_t* 
archive) {
-    celixThreadMutex_lock(&archive->lock);
-    const char* revRoot = archive->resourceCacheRoot;
-    celixThreadMutex_unlock(&archive->lock);
-    return revRoot;
+    return archive->resourceCacheRoot;
 }
 
 
diff --git a/libs/framework/src/framework.c b/libs/framework/src/framework.c
index f9a686bc..ee80fabe 100644
--- a/libs/framework/src/framework.c
+++ b/libs/framework/src/framework.c
@@ -2354,16 +2354,7 @@ celix_status_t 
celix_framework_bundleEntry_refreshBundleEntry(celix_framework_t*
         return status;
     }
 
-    const char* location = NULL;
-    status = bundleArchive_getLocation(archive, &location);
-    if (!location) {
-        fw_log(framework->logger, CELIX_LOG_LEVEL_ERROR, "Cannot refresh 
bundle %s (id=%li), bundle has no location",
-               celix_bundle_getSymbolicName(entry->bnd),
-               entry->bndId);
-        return status;
-    }
-
-    status = bundleArchive_revise(archive, location, updatedBundleUrl);
+    status = bundleArchive_revise(archive, NULL, updatedBundleUrl);
     if (status != CELIX_SUCCESS) {
         fw_log(framework->logger, CELIX_LOG_LEVEL_ERROR, "Cannot refresh 
bundle %s (id=%li), bundle archive revision failed",
                celix_bundle_getSymbolicName(entry->bnd),

Reply via email to