PengZheng commented on code in PR #476: URL: https://github.com/apache/celix/pull/476#discussion_r1145763347
########## libs/framework/src/bundle_archive.c: ########## @@ -28,644 +28,415 @@ #include <dirent.h> #include <unistd.h> #include <string.h> +#include <assert.h> #include "celix_constants.h" #include "celix_utils_api.h" #include "linked_list_iterator.h" #include "framework_private.h" #include "celix_file_utils.h" #include "bundle_revision_private.h" +#include "celix_framework_utils_private.h" + +celix_status_t celix_bundleArchive_getLastModifiedInternal(bundle_archive_pt archive, struct timespec *lastModified); + +/** + * The bundle archive which is used to store the bundle data and can be reused when a framework is restarted. + * The lifecycle of a bundle archive is coupled to the lifecycle of the bundle that is created from the archive. + * + * @note The bundle archive is thread safe. + */ struct bundleArchive { + //initialed during creation and immutable celix_framework_t* fw; long id; - char * location; - DIR *archiveRootDir; - char * archiveRoot; - linked_list_pt revisions; - long refreshCount; - time_t lastModified; - - bundle_state_e persistentState; + char *archiveRoot; + char *savedBundleStatePropertiesPath; + char* storeRoot; + char* resourceCacheRoot; + bool isSystemBundle; + 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; }; -static celix_status_t bundleArchive_getRevisionLocation(bundle_archive_pt archive, long revNr, char **revision_location); -static celix_status_t bundleArchive_setRevisionLocation(bundle_archive_pt archive, const char * location, long revNr); - -static celix_status_t bundleArchive_initialize(bundle_archive_pt archive); - -static celix_status_t bundleArchive_createRevisionFromLocation(bundle_archive_pt archive, const char *location, const char *inputFile, long revNr, bundle_revision_pt *bundle_revision); -static celix_status_t bundleArchive_reviseInternal(bundle_archive_pt archive, bool isReload, long revNr, const char * location, const char *inputFile); - -static celix_status_t bundleArchive_readLastModified(bundle_archive_pt archive, time_t *time); -static celix_status_t bundleArchive_writeLastModified(bundle_archive_pt archive); - -celix_status_t bundleArchive_createSystemBundleArchive(celix_framework_t* fw, bundle_archive_pt *bundle_archive) { - celix_status_t status = CELIX_SUCCESS; - char *error = NULL; - bundle_archive_pt archive = NULL; - - if (*bundle_archive != NULL) { - status = CELIX_ILLEGAL_ARGUMENT; - error = "Missing required arguments and/or incorrect values"; - } else { - archive = (bundle_archive_pt) calloc(1,sizeof(*archive)); - if (archive == NULL) { - status = CELIX_ENOMEM; - } else { - status = linkedList_create(&archive->revisions); - if (status == CELIX_SUCCESS) { - archive->fw = fw; - archive->id = CELIX_FRAMEWORK_BUNDLE_ID; - archive->location = strdup("System Bundle"); - archive->archiveRoot = NULL; - archive->archiveRootDir = NULL; - archive->refreshCount = -1; - archive->persistentState = CELIX_BUNDLE_STATE_UNKNOWN; - time(&archive->lastModified); - - *bundle_archive = archive; - } - } - } - - if(status != CELIX_SUCCESS && archive != NULL){ - bundleArchive_destroy(archive); - } - - framework_logIfError(fw->logger, status, error, "Could not create archive"); - - return status; +static void celix_bundleArchive_storeBundleStateProperties(bundle_archive_pt archive) { + celix_properties_t* bundleStateProperties = celix_properties_create(); + if (bundleStateProperties != NULL) { + celixThreadMutex_lock(&archive->lock); + //set/update bundle cache state properties + celix_properties_setLong(bundleStateProperties, CELIX_BUNDLE_ARCHIVE_BUNDLE_ID_PROPERTY_NAME, archive->id); + celix_properties_set(bundleStateProperties, CELIX_BUNDLE_ARCHIVE_LOCATION_PROPERTY_NAME, archive->location); + celix_properties_set(bundleStateProperties, CELIX_BUNDLE_ARCHIVE_SYMBOLIC_NAME_PROPERTY_NAME, + archive->bundleSymbolicName); + celix_properties_set(bundleStateProperties, CELIX_BUNDLE_ARCHIVE_VERSION_PROPERTY_NAME, archive->bundleVersion); + + //save bundle cache state properties + celix_properties_store(bundleStateProperties, archive->savedBundleStatePropertiesPath, + "Bundle State Properties"); + celixThreadMutex_unlock(&archive->lock); + } + celix_properties_destroy(bundleStateProperties); } -celix_status_t bundleArchive_create(celix_framework_t* fw, const char *archiveRoot, long id, const char * location, const char *inputFile, bundle_archive_pt *bundle_archive) { - celix_status_t status = CELIX_SUCCESS; - char *error = NULL; - bundle_archive_pt archive = NULL; - - if (*bundle_archive != NULL) { - status = CELIX_ILLEGAL_ARGUMENT; - error = "bundle_archive_pt must be NULL"; - } else { - archive = (bundle_archive_pt) calloc(1,sizeof(*archive)); - if (archive == NULL) { - status = CELIX_ENOMEM; - } else { - status = linkedList_create(&archive->revisions); - if (status == CELIX_SUCCESS) { - archive->fw = fw; - archive->id = id; - archive->location = strdup(location); - archive->archiveRootDir = NULL; - archive->archiveRoot = strdup(archiveRoot); - archive->refreshCount = -1; - time(&archive->lastModified); - - status = bundleArchive_initialize(archive); - if (status == CELIX_SUCCESS) { - status = bundleArchive_revise(archive, location, inputFile); - - if (status == CELIX_SUCCESS) { - *bundle_archive = archive; - } - else{ - bundleArchive_closeAndDelete(archive); - } - } - } - } - } - - if(status != CELIX_SUCCESS && archive != NULL){ - bundleArchive_destroy(archive); - } +celix_status_t celix_bundleArchive_extractBundle( + bundle_archive_t* archive, + const char* revisionRoot, + const char* bundleUrl, + const struct timespec* revisionModificationTime) { + celix_status_t status = CELIX_SUCCESS; + bool extractBundle = true; + + //check if bundle location is newer than current revision + if (celix_utils_fileExists(revisionRoot)) { Review Comment: ```suggestion if (revisionModificationTime->tv_sec != 0 || revisionModificationTime->tv_nsec != 0) { ``` The original check always return true, since `archive->resourceCacheRoot` has already been created. I suggest the above check instead or we recover the single revision directory under resource root. -- 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