diff options
author | Ingo Huerner <ingo_huerner@mentor.com> | 2017-02-16 13:10:55 +0100 |
---|---|---|
committer | Ingo Huerner <ingo_huerner@mentor.com> | 2017-02-16 13:10:55 +0100 |
commit | 3a5cfb462ae05793b748532daf585d12f3390ad5 (patch) | |
tree | 3a1c62f4e07ce5d2277e823314b76e1f475af406 | |
parent | 5f1f922696076a3f9e5a894a1c4bbc29dafa30e6 (diff) | |
download | persistence-client-library-3a5cfb462ae05793b748532daf585d12f3390ad5.tar.gz |
Replaced file handle array by simple linked list
-rw-r--r-- | src/persistence_client_library_dbus_cmd.c | 46 | ||||
-rw-r--r-- | src/persistence_client_library_file.c | 17 | ||||
-rw-r--r-- | src/persistence_client_library_handle.c | 167 | ||||
-rw-r--r-- | src/persistence_client_library_handle.h | 68 | ||||
-rw-r--r-- | test/persistence_client_library_test_file.c | 354 |
5 files changed, 575 insertions, 77 deletions
diff --git a/src/persistence_client_library_dbus_cmd.c b/src/persistence_client_library_dbus_cmd.c index 1096896..21e2ba7 100644 --- a/src/persistence_client_library_dbus_cmd.c +++ b/src/persistence_client_library_dbus_cmd.c @@ -22,6 +22,7 @@ #include "persistence_client_library_custom_loader.h" #include "persistence_client_library_pas_interface.h" #include "persistence_client_library_db_access.h" +#include "persistence_client_library_file.h" #if USE_FILECACHE @@ -191,7 +192,7 @@ void process_block_and_write_data_back(unsigned int requestID, unsigned int stat void process_prepare_shutdown(int complete) { - int i = 0, rval = 0; + int i = 0; DLT_LOG(gPclDLTContext, DLT_LOG_INFO, DLT_STRING("prepShtdwn - writing all changed data / closing all handles")); @@ -199,37 +200,26 @@ void process_prepare_shutdown(int complete) pers_lock_access(); // flush open files to disk - for(i=0; i<MaxPersHandle; i++) - { - if(gOpenFdArray[i] == FileOpen) - { #if USE_FILECACHE - if(complete == Shutdown_Full) - { - rval = pfcCloseFile(i); - } - else if(complete == Shutdown_Partial) - { - pfcWriteBackAndSync(i); - } + if(complete == Shutdown_Full) + { + rval = pfcCloseFile(i); + } + else if(complete == Shutdown_Partial) + { + pfcWriteBackAndSync(i); + } #else - if(complete == Shutdown_Full) - { - rval = close(i); - } - else if(complete == Shutdown_Partial) - { - fsync(i); - } -#endif - if(rval == -1) - { - DLT_LOG(gPclDLTContext, DLT_LOG_ERROR, DLT_STRING("prepShtdwn - failed close file: "), DLT_STRING(strerror(errno)) ); - } - - } + if(complete == Shutdown_Full) + { + list_iterate(&gOpenFdList, &pclFileClose); } + else if(complete == Shutdown_Partial) + { + list_iterate(&gOpenFdList, &fsync); + } +#endif pers_rct_close_all(); // close all opened resource configuration table diff --git a/src/persistence_client_library_file.c b/src/persistence_client_library_file.c index 8c77a4b..d73e066 100644 --- a/src/persistence_client_library_file.c +++ b/src/persistence_client_library_file.c @@ -121,8 +121,6 @@ int pclFileClose(int fd) DLT_LOG(gPclDLTContext, DLT_LOG_WARN, DLT_STRING("pclFileClose - csum remove failed!"), DLT_STRING(strerror(errno)) ); } } - if(fd < MaxPersHandle) - __sync_fetch_and_sub(&gOpenFdArray[fd], FileClosed); // set closed flag // remove form file tree; if(remove_file_handle_data(fd) != 1) @@ -144,6 +142,7 @@ int pclFileClose(int fd) fsync(fd); rval = close(fd); #endif + list_item_remove(&gOpenFdList, fd); } else { @@ -392,7 +391,7 @@ int pclFileOpenRegular(PersistenceInfo_s* dbContext, const char* resource_id, ch if(set_file_handle_data(handle, dbContext->configKey.permission, backupPath, csumPath, NULL) != -1) { set_file_backup_status(handle, wantBackup); - __sync_fetch_and_add(&gOpenFdArray[handle], FileOpen); // set open flag + list_item_insert(&gOpenFdList, handle); } else { @@ -430,7 +429,7 @@ int pclFileOpenRegular(PersistenceInfo_s* dbContext, const char* resource_id, ch if(set_file_handle_data(handle, PersistencePermission_ReadWrite, backupPath, csumPath, NULL) != -1) { set_file_backup_status(handle, 1); - __sync_fetch_and_add(&gOpenFdArray[handle], FileOpen); // set open flag + list_item_insert(&gOpenFdList, handle); } else { @@ -942,9 +941,9 @@ int pclFileCreatePath(unsigned int ldbid, const char* resource_id, unsigned int close(handle); // don't need the open file } } - __sync_fetch_and_add(&gOpenHandleArray[handle], FileOpen); // set open flag - set_ossfile_handle_data(handle, dbContext.configKey.permission, 0/*backupCreated*/, backupPath, csumPath, *path); + + list_item_insert(&gCPOpenFdList, handle); // remember open fd } else { @@ -973,7 +972,7 @@ int pclFileCreatePath(unsigned int ldbid, const char* resource_id, unsigned int snprintf(backupPath, PERS_ORG_MAX_LENGTH_PATH_FILENAME, "%s%s", dbPath, gBackupPostfix); snprintf(csumPath, PERS_ORG_MAX_LENGTH_PATH_FILENAME, "%s%s", dbPath, gBackupCsPostfix); - __sync_fetch_and_add(&gOpenHandleArray[handle], FileOpen); // set open flag + list_item_insert(&gCPOpenFdList, handle); // remember open fd set_ossfile_handle_data(handle, PersistencePermission_ReadWrite, 0/*backupCreated*/, backupPath, csumPath, NULL); } @@ -1037,12 +1036,12 @@ int pclFileReleasePath(int pathHandle) } free(get_ossfile_file_path(pathHandle)); - __sync_fetch_and_sub(&gOpenHandleArray[pathHandle], FileClosed); // set closed flag - set_persistence_handle_close_idx(pathHandle); set_ossfile_file_path(pathHandle, NULL); + list_item_remove(&gCPOpenFdList, pathHandle); // remove open fd form list + if(remove_ossfile_handle_data(pathHandle) != 1) { DLT_LOG(gPclDLTContext, DLT_LOG_WARN, DLT_STRING("pclFileReleasePath - Failed to remove from tree!"), DLT_INT(pathHandle) ); diff --git a/src/persistence_client_library_handle.c b/src/persistence_client_library_handle.c index 34e16bf..4c0832c 100644 --- a/src/persistence_client_library_handle.c +++ b/src/persistence_client_library_handle.c @@ -31,24 +31,19 @@ pthread_mutex_t gFileHandleAccessMtx = PTHREAD_MUTEX_INITIALIZER; pthread_mutex_t gOssFileHandleAccessMtx = PTHREAD_MUTEX_INITIALIZER; pthread_mutex_t gMtx = PTHREAD_MUTEX_INITIALIZER; +//list maintaining open file file handles +PersList_item_s* gCPOpenFdList = NULL; +PersList_item_s* gOpenFdList = NULL; + /// tree to store key handle information static jsw_rbtree_t *gKeyHandleTree = NULL; /// tree to store file handle information static jsw_rbtree_t *gFileHandleTree = NULL; - static jsw_rbtree_t *gOssFileHandleTree = NULL; - - - -// open file descriptor handle array -char gOpenFdArray[MaxPersHandle] = { [0 ...MaxPersHandle-1] = 0 }; -// handle array -char gOpenHandleArray[MaxPersHandle] = { [0 ...MaxPersHandle-1] = 0 }; - -// handle index +/// handle index static int gHandleIdx = 1; /// free handle array static int gFreeHandleArray[MaxPersHandle] = { [0 ...MaxPersHandle-1] = 0 }; @@ -56,6 +51,153 @@ static int gFreeHandleArray[MaxPersHandle] = { [0 ...MaxPersHandle-1] = 0 }; static int gFreeHandleIdxHead = 0; + +int list_item_insert(PersList_item_s** list, int fd) +{ + int rval = 1; + + PersList_item_s *tmp = *list; + if(tmp != NULL) // check if list is empty + { + while(tmp->next != NULL) + { + tmp = tmp->next; + } + + tmp->next = (PersList_item_s*)malloc(sizeof(PersList_item_s)); + + if(tmp->next != NULL) + { + tmp->next->fd = fd; + tmp->next->next = NULL; + } + else + { + rval = -1; + } + } + else + { + *list = (PersList_item_s *)malloc(sizeof(PersList_item_s)); + if(list != NULL) + { + (*list)->fd = fd; + (*list)->next = NULL; + } + else + { + rval = -1; + } + } + + return rval; +} + + + +int list_item_get_data(PersList_item_s** list, int fd) +{ + int rval = 0; + PersList_item_s *tmp = *list; + + if(tmp != NULL) + { + while(tmp != NULL) + { + if(tmp->fd == fd ) + { + rval = tmp->fd; + break; + } + tmp = tmp->next; + } + } + else + { + rval = -1; + } + + return rval; +} + + + +int list_item_remove(PersList_item_s** list, int fd) +{ + PersList_item_s *last = NULL; + PersList_item_s *tmp = *list; + + if(tmp != NULL) + { + while(tmp != NULL) + { + if(tmp->fd == fd ) + { + if(tmp == * list) + { + * list = tmp->next; + free(tmp); + return 1; + } + else + { + last->next = tmp->next; + free(tmp); + return 1; + } + } + else + { + last = tmp; + tmp = tmp->next; + } + } + } + + return -1; +} + + +void list_iterate(PersList_item_s** list, int(*callback)(int a)) +{ + PersList_item_s *tmp = *list; + + while(tmp != NULL) + { + callback(tmp->fd); + tmp = tmp->next; + } +} + + +int list_get_size(PersList_item_s** list) +{ + int lSize = 0; + PersList_item_s *tmp = *list; + + while(tmp != NULL) + { + tmp = tmp->next; + lSize++; + } + return lSize; +} + + +void list_destroy(PersList_item_s** list) +{ + PersList_item_s *tmp = *list; + + while(tmp != NULL) + { + PersList_item_s *nextItem = tmp->next; + free(tmp); + tmp = nextItem; + } + *list = NULL; +} + + void deleteHandleTrees(void) { if(gKeyHandleTree != NULL) @@ -125,8 +267,9 @@ void close_all_persistence_handle() { // "free" all handles memset(gFreeHandleArray, 0, sizeof(gFreeHandleArray)); - memset(gOpenHandleArray, 0, sizeof(gOpenHandleArray)); - memset(gOpenFdArray, 0, sizeof(gOpenFdArray)); + + list_destroy(&gCPOpenFdList); + list_destroy(&gOpenFdList); // reset variables gHandleIdx = 1; diff --git a/src/persistence_client_library_handle.h b/src/persistence_client_library_handle.h index b3c4481..1a1a998 100644 --- a/src/persistence_client_library_handle.h +++ b/src/persistence_client_library_handle.h @@ -22,6 +22,7 @@ #include "persistence_client_library_data_organization.h" + /// key handle structure definition typedef struct _PersistenceKeyHandle_s { @@ -36,6 +37,15 @@ typedef struct _PersistenceKeyHandle_s } PersistenceKeyHandle_s; + +typedef struct _PersList_item_s +{ + int fd; + struct _PersList_item_s *next; +} PersList_item_s; + + + /// file handle structure definition typedef struct _PersistenceFileHandle_s { @@ -55,11 +65,14 @@ typedef struct _PersistenceFileHandle_s char* filePath; } PersistenceFileHandle_s; -/// open file descriptor handle array -extern char gOpenFdArray[MaxPersHandle]; -/// handle array -extern char gOpenHandleArray[MaxPersHandle]; + +/// list to store open file handles (pclFileCreatePath and pclFileReleasePath) +extern PersList_item_s* gCPOpenFdList; + +/// list to store open file handles +extern PersList_item_s* gOpenFdList; + //---------------------------------------------------------------- //---------------------------------------------------------------- @@ -357,5 +370,52 @@ int get_ossfile_backup_status(int idx); */ int remove_ossfile_handle_data(int idx); + +//---------------------------------------------------------------- +//---------------------------------------------------------------- + +/** + * @brief insert a list item at the end of the list + * + * @param list the list to append the item to + * @param fd the file handle + */ +int list_item_insert(PersList_item_s** list, int fd); + + +/** + * @brief check if a item is in a list + * + * @param handle of the item + * @param fd the file handle + */ +int list_item_get_data(PersList_item_s** list, int fd); + + +/** + * @brief remove a list item from the given list with the matching handle + * + * @param list the list to remove the item from + * @param fd the file handle + */ +int list_item_remove(PersList_item_s** list, int fd); + + +/** + * @brief destroy a list (free all items) + * + * @param list the list to destroy + */ +void list_destroy(PersList_item_s** list); + + +/** + * @brief insert a list item at the end of the list + * + * @param list the list to append the item to + * @param fd the file handle + */ +void list_iterate(PersList_item_s** list, int(*callback)(int a)); + #endif /* PERSISTENCY_CLIENT_LIBRARY_HANDLE_H */ diff --git a/test/persistence_client_library_test_file.c b/test/persistence_client_library_test_file.c index 5d96696..83edbe9 100644 --- a/test/persistence_client_library_test_file.c +++ b/test/persistence_client_library_test_file.c @@ -522,16 +522,16 @@ START_TEST(test_DataHandle) strlen("/user/1/seat/1/media/mediaDB_write_04.db")) == 0, "Buffer not correctly read => mediaDB_write_04.db"); - ret = pclKeyHandleClose(handleArray[0]); + ret = pclFileClose(handleArray[0]); fail_unless(ret != -1, "Failed to close handle idx \"0\"!!"); - ret = pclKeyHandleClose(handleArray[1]); + ret = pclFileClose(handleArray[1]); fail_unless(ret != -1, "Failed to close handle idx \"1\"!!"); - ret = pclKeyHandleClose(handleArray[2]); + ret = pclFileClose(handleArray[2]); fail_unless(ret != -1, "Failed to close handle idx \"2\"!!"); - ret = pclKeyHandleClose(handleArray[3]); + ret = pclFileClose(handleArray[3]); fail_unless(ret != -1, "Failed to close handle idx \"3\"!!"); // test key handles @@ -583,7 +583,6 @@ START_TEST(test_DataHandle) size = pclFileWriteData(handleArray[i], writeBuffer, (int)strlen(writeBuffer)); fail_unless(size == (int)strlen(writeBuffer), "Wrong size written - %d", i); } - } // now read data @@ -596,28 +595,19 @@ START_TEST(test_DataHandle) snprintf(writeBuffer, 256, "START_TEST(test_DataHandle)_media/some_test_data_to_show_read and write is working_%d", i); pclFileSeek(handleArray[i], 0, SEEK_SET); size = pclFileReadData(handleArray[i], buffer, READ_SIZE); -#if 0 - if(strncmp((const char*)buffer, (const char*)writeBuffer, 256) != 0) - { - printf("ERROR Read: \"%s\" - \"%s\"\n", buffer, writeBuffer); - } - else - { - printf("ERROR Read: \"%s\" - \"%s\"\n", buffer, writeBuffer); - } -#endif + fail_unless(size != 256); fail_unless(strncmp((const char*)buffer, (const char*)writeBuffer, 256) == 0); } } // now close data - for(i=0; i<1024; i++) + printf("\nDo close multiple\n"); + for(i=0; i<10; i++) { if(handleArray[i] >=0 ) (void)pclFileClose(handleArray[i]); } } - } END_TEST @@ -1054,6 +1044,7 @@ static Suite * persistencyClientLib_suite() #if 1 + suite_add_tcase(s, tc_persDataFile); tcase_add_checked_fixture(tc_persDataFile, data_setup, data_teardown); @@ -1083,12 +1074,11 @@ static Suite * persistencyClientLib_suite() suite_add_tcase(s, tc_DataHandle); tcase_add_checked_fixture(tc_DataHandle, data_setup, data_teardown); - #else - //suite_add_tcase(s, tc_MultiFileReadWrite); //tcase_add_checked_fixture(tc_MultiFileReadWrite, data_setup, data_teardown); + #endif @@ -1141,7 +1131,7 @@ void* WriteOneThread(void* userData) usleep(120000); } - for(i=0; i< 20000; i++) + for(i=0; i< 7000; i++) { printf("loop One: %d\n", i); @@ -1279,7 +1269,7 @@ void* WriteThreeThread(void* userData) usleep(120000); } - for(i=0; i< 20000; i++) + for(i=0; i< 7000; i++) { printf("loop Three: %d\n", i); @@ -1403,7 +1393,7 @@ void* WriteTwoThread(void* userData) printf("Two fd2: %d\n", fd2); - for(i=0; i< 20000; i++) + for(i=0; i< 7000; i++) { memset(readbuffer, 0, bufferSize); memset(readbuffer2, 0, bufferSize2); @@ -1475,7 +1465,7 @@ void* WriteTwoThread(void* userData) -void doEndlessWrite() +void doMultithreadedReadWrite() { int* retval; pthread_t one, two, three; @@ -1507,10 +1497,322 @@ void doEndlessWrite() printf("End Test\n"); + +} + +#define NUM_OF_FILES 20 + + +void fdTest() +{ + int i = 0; + int handle[2000] = {0}; + char fileBuffer[1024] = {0}; + memset(handle, -1, sizeof(handle)); + + + + printf("\nOpen and close every second file right away\n"); + for(i=0; i < NUM_OF_FILES; i++) + { + memset(fileBuffer,0,1024); + snprintf(fileBuffer, 1024, "/tmp/fd_testFiles/file_%d.txt", i); + handle[i] = open(fileBuffer, O_CREAT | O_RDWR | O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH); + printf("1 o -> fd[%d]: %d\n", i, handle[i]); + + if(i%2) + { + close(handle[i]); + handle[i] = -1; + } + } + + printf("\nClose remaining open files\n"); + for(i=0; i < NUM_OF_FILES; i++) + { + if(handle[i] > 0) + { + printf("1 c -> fd[%d]: %d\n", i, handle[i]); + close(handle[i]); + handle[i] = -1; + } + } + + printf("\nOpen files \n"); + for(i=0; i < NUM_OF_FILES; i++) + { + memset(fileBuffer,0,1024); + snprintf(fileBuffer, 1024, "/tmp/fd_testFiles/file_%d.txt", i); + handle[i] = open(fileBuffer, O_CREAT | O_RDWR | O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH); + printf("2 o -> fd[%d]: %d\n", i, handle[i]); + } + + + printf("\nClose open files\n"); + for(i=0; i < NUM_OF_FILES; i++) + { + if(handle[i] > 0) + { + printf("2 c -> fd[%d]: %d\n", i, handle[i]); + close(handle[i]); + handle[i] = -1; + } + } + +} + + + + + + + + + + +int doPrintf(int fd) +{ + return printf(" value: %d\n", fd); +} + + +typedef struct sList_item_ +{ + int fd; + struct sList_item_ *next; +} sList_item; + + + +int list_item_insert(sList_item** list, int fd) +{ + int rval = 1; + + sList_item *tmp = *list; + if(tmp != NULL) // check if list is empty + { + while(tmp->next != NULL) + { + tmp = tmp->next; + } + + tmp->next = (sList_item *)malloc(sizeof(sList_item)); + + if(tmp->next != NULL) + { + tmp->next->fd = fd; + tmp->next->next = NULL; + } + else + { + rval = -1; + } + } + else + { + *list = (sList_item *)malloc(sizeof(sList_item)); + if(list != NULL) + { + (*list)->fd = fd; + (*list)->next = NULL; + } + else + { + rval = -1; + } + } + + return rval; } +int list_item_get_data(sList_item** list, int fd) +{ + int rval = 0; + sList_item *tmp = *list; + + if(tmp != NULL) + { + while(tmp != NULL) + { + if(tmp->fd == fd ) + { + rval = tmp->fd; + break; + } + tmp = tmp->next; + } + } + else + { + rval = -1; + } + + return rval; +} + + + +int list_item_remove(sList_item** list, int fd) +{ + sList_item *last = NULL; + sList_item *tmp = *list; + + if(tmp != NULL) + { + while(tmp != NULL) + { + if(tmp->fd == fd ) + { + if(tmp == * list) + { + * list = tmp->next; + free(tmp); + return 1; + } + else + { + last->next = tmp->next; + free(tmp); + return 1; + } + } + else + { + last = tmp; + tmp = tmp->next; + } + } + } + + return -1; +} + + + +void list_iterate(sList_item** list, int(*callback)(int a)) +{ + sList_item *tmp = *list; + + while(tmp != NULL) + { + callback(tmp->fd); + tmp = tmp->next; + } +} + +int list_get_size(sList_item** list) +{ + int lSize = 0; + sList_item *tmp = *list; + + while(tmp != NULL) + { + tmp = tmp->next; + lSize++; + } + return lSize; +} + + +void list_destroy(sList_item** list) +{ + sList_item *tmp = *list; + + while(tmp != NULL) + { + sList_item *nextItem = tmp->next; + free(tmp); + tmp = nextItem; + } + *list = NULL; +} + + + + + + +void doListTest() +{ + sList_item* myList = NULL; + sList_item* secondList = NULL; + + printf("Insert 1\n"); + printf(" Size: %d - [Soll: 0]\n", list_get_size(&myList)); + list_item_insert(&myList, 5); + list_item_insert(&myList, 1); + list_item_insert(&myList, 2); + list_item_insert(&myList, 4); + list_item_insert(&secondList, 2); + list_item_insert(&secondList, 4); + printf(" Size: %d - [Soll: 4]\n", list_get_size(&myList)); + list_item_insert(&myList, 6); + list_item_insert(&myList, 7); + list_item_insert(&myList, 8); + printf(" Size: %d - [Soll: 7]\n", list_get_size(&myList)); + list_item_insert(&myList, 9); + list_item_insert(&myList, 11); + list_item_insert(&myList, 10); + list_item_insert(&myList, 50); + list_item_insert(&secondList, 10); + list_item_insert(&secondList, 50); + printf(" Size: %d - [Soll: 11]\n", list_get_size(&myList)); + list_item_insert(&myList, 110); + list_item_insert(&myList, 100); + list_item_insert(&myList, 500); + printf(" Size: %d - [Soll: 14]\n", list_get_size(&myList)); + + + list_iterate(&myList, &doPrintf); + list_iterate(&secondList, &doPrintf); + + printf("Remove 1: 9, 11, 10, 50\n"); + list_item_remove(&myList, 9); + list_item_remove(&myList, 11); + list_item_remove(&myList, 10); + list_item_remove(&myList, 50); + list_item_remove(&secondList, 50); + list_iterate(&myList, &doPrintf); + list_iterate(&secondList, &doPrintf); + printf(" Size: %d - [Soll: 10]\n", list_get_size(&myList)); + + + printf("Remove 2: 5, 500\n"); + list_item_remove(&myList, 5); + list_item_remove(&myList, 500); + list_iterate(&myList, &doPrintf); + printf(" Size: %d - [Soll: 8]\n", list_get_size(&myList)); + + printf("Insert 2\n"); + list_item_insert(&myList, 900); + list_item_insert(&myList, 911); + list_item_insert(&myList, 910); + list_item_insert(&myList, 950); + list_iterate(&myList, &doPrintf); + printf(" Size: %d - [Soll: 12]\n", list_get_size(&myList)); + + printf("Destroy\n"); + list_destroy(&myList); + list_destroy(&secondList); + list_iterate(&myList, &doPrintf); + list_iterate(&secondList, &doPrintf); + printf(" Size: %d - [Soll: 0]\n", list_get_size(&myList)); + + + printf("Insert 3\n"); + list_item_insert(&myList, 1900); + list_item_insert(&myList, 1911); + list_iterate(&myList, &doPrintf); + + printf(" Size: %d - [Soll: 2]\n", list_get_size(&myList)); + + + list_destroy(&myList); + list_destroy(&secondList); +} + int main(int argc, char *argv[]) { @@ -1549,7 +1851,11 @@ int main(int argc, char *argv[]) } else { - doEndlessWrite(); + doMultithreadedReadWrite(); + + //fdTest(); + + //doListTest(); } DLT_LOG(gPcltDLTContext, DLT_LOG_INFO, DLT_STRING("End of PCL test")); |