From a4f29c85a0a85e46a055dee7337f9bda1756a17b Mon Sep 17 00:00:00 2001 From: Ingo Huerner Date: Wed, 27 Nov 2013 14:52:46 +0100 Subject: [PATCH] Fix a deadlock when receiving shutdown mode --- src/persistence_client_library_dbus_cmd.c | 6 ++++-- src/persistence_client_library_dbus_service.c | 26 +++++++++++++++++--------- src/persistence_client_library_dbus_service.h | 2 ++ src/persistence_client_library_lc_interface.c | 9 ++++----- src/persistence_client_library_pas_interface.c | 2 +- src/persistence_client_library_prct_access.c | 11 ++++++++++- src/persistence_client_library_prct_access.h | 26 ++++++++++++++++++++++++-- 7 files changed, 62 insertions(+), 20 deletions(-) diff --git a/src/persistence_client_library_dbus_cmd.c b/src/persistence_client_library_dbus_cmd.c index eee0722..dc1e5ff 100644 --- a/src/persistence_client_library_dbus_cmd.c +++ b/src/persistence_client_library_dbus_cmd.c @@ -170,7 +170,6 @@ void process_block_and_write_data_back(unsigned int requestID, unsigned int stat void process_prepare_shutdown(unsigned char requestId, unsigned int status) { int i = 0; - //GvdbTable* resourceTable = NULL; itzam_btree* resourceTable = NULL; itzam_state state = ITZAM_FAILED; @@ -193,9 +192,10 @@ void process_prepare_shutdown(unsigned char requestId, unsigned int status) { resourceTable = get_resource_cfg_table_by_idx(i); // dereference opend database - if(resourceTable != NULL) + if(resourceTable != NULL && get_resource_cfg_table_status(i) == 1) { state = itzam_btree_close(resourceTable); + invalidate_resource_cfg_table(i); if (state != ITZAM_OKAY) { DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("process_prepare_shutdown => itzam_btree_close: Itzam problem"), DLT_STRING(STATE_MESSAGES[state])); @@ -216,6 +216,8 @@ void process_prepare_shutdown(unsigned char requestId, unsigned int status) gPersCustomFuncs[i].custom_plugin_deinit(); // close library handle dlclose(gPersCustomFuncs[i].handle); + + gPersCustomFuncs[i].custom_plugin_deinit = NULL; } } diff --git a/src/persistence_client_library_dbus_service.c b/src/persistence_client_library_dbus_service.c index 9b86343..81963bd 100644 --- a/src/persistence_client_library_dbus_service.c +++ b/src/persistence_client_library_dbus_service.c @@ -578,6 +578,9 @@ int mainLoop(DBusObjectPathVTable vtable, DBusObjectPathVTable vtable2, case CMD_LC_PREPARE_SHUTDOWN: process_prepare_shutdown((buf[2]), buf[1]); break; + case CMD_SEND_LC_REQUEST: + process_send_lifecycle_request(conn, (buf[2]), buf[1]); + break; case CMD_SEND_NOTIFY_SIGNAL: process_send_notification_signal(conn); break; @@ -590,9 +593,6 @@ int mainLoop(DBusObjectPathVTable vtable, DBusObjectPathVTable vtable2, case CMD_SEND_PAS_REGISTER: process_send_pas_register(conn, (buf[1]), buf[2]); break; - case CMD_SEND_LC_REQUEST: - process_send_lifecycle_request(conn, (buf[2]), buf[1]); - break; case CMD_SEND_LC_REGISTER: process_send_lifecycle_register(conn, (buf[1]), buf[2]); break; @@ -657,11 +657,23 @@ int mainLoop(DBusObjectPathVTable vtable, DBusObjectPathVTable vtable2, int deliverToMainloop(tCmd mainloopCmd, unsigned int param1, unsigned int param2) { int rval = 0; - uint64_t cmd; - uint16_t* cmd_chk; pthread_mutex_lock(&gMainLoopMtx); + deliverToMainloop_NM(mainloopCmd, param1, param2); + + // wait for condition variable + pthread_cond_wait(&gMainLoopCond, &gMainLoopMtx); + pthread_mutex_unlock(&gMainLoopMtx); + + return rval; +} + +int deliverToMainloop_NM(tCmd mainloopCmd, unsigned int param1, unsigned int param2) +{ + int rval = 0; + uint64_t cmd; + cmd = ( ((uint64_t)param2 << 32) | ((uint64_t)param1 << 16) | mainloopCmd); if(-1 == write(gEfds, &cmd, (sizeof(uint64_t)))) @@ -670,10 +682,6 @@ int deliverToMainloop(tCmd mainloopCmd, unsigned int param1, unsigned int param2 rval = -1; } - // wait for condition variable - pthread_cond_wait(&gMainLoopCond, &gMainLoopMtx); - pthread_mutex_unlock(&gMainLoopMtx); - return rval; } diff --git a/src/persistence_client_library_dbus_service.h b/src/persistence_client_library_dbus_service.h index f80c7c9..e5eff44 100644 --- a/src/persistence_client_library_dbus_service.h +++ b/src/persistence_client_library_dbus_service.h @@ -75,4 +75,6 @@ int setup_dbus_mainloop(void); int deliverToMainloop(tCmd mainloopCmd, unsigned int param1, unsigned int param2); + +int deliverToMainloop_NM(tCmd mainloopCmd, unsigned int param1, unsigned int param2); #endif /* PERSISTENCE_CLIENT_LIBRARY_DBUS_SERVICE_H_ */ diff --git a/src/persistence_client_library_lc_interface.c b/src/persistence_client_library_lc_interface.c index 50324a2..0c19936 100644 --- a/src/persistence_client_library_lc_interface.c +++ b/src/persistence_client_library_lc_interface.c @@ -44,7 +44,7 @@ int check_lc_request(int request, int requestID) { case NsmShutdownNormal: { - if(-1 == deliverToMainloop(CMD_LC_PREPARE_SHUTDOWN, request, requestID) ) + if(-1 == deliverToMainloop_NM(CMD_LC_PREPARE_SHUTDOWN, request, requestID) ) { DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("check_lc_request => failed to write to pipe"), DLT_INT(errno)); rval = NsmErrorStatus_Fail; @@ -124,14 +124,13 @@ int msg_lifecycleRequest(DBusConnection *connection, DBusMessage *message) - DBusHandlerResult checkLifecycleMsg(DBusConnection * connection, DBusMessage * message, void * user_data) { DBusHandlerResult result = DBUS_HANDLER_RESULT_NOT_YET_HANDLED; - if((0==strncmp("org.genivi.NodeStateManager.LifeCycleConsumer", dbus_message_get_interface(message), 20))) + if((0==strncmp("org.genivi.NodeStateManager.LifeCycleConsumer", dbus_message_get_interface(message), 46))) { - if((0==strncmp("LifecycleRequest", dbus_message_get_member(message), 18))) + if((0==strncmp("LifecycleRequest", dbus_message_get_member(message), 16))) { result = msg_lifecycleRequest(connection, message); } @@ -161,6 +160,6 @@ int unregister_lifecycle(int shutdownMode) int send_prepare_shutdown_complete(int requestId, int status) { - return deliverToMainloop(CMD_SEND_LC_REQUEST, status, requestId); + return deliverToMainloop_NM(CMD_SEND_LC_REQUEST, status, requestId); } diff --git a/src/persistence_client_library_pas_interface.c b/src/persistence_client_library_pas_interface.c index f9a7099..3fb8ff1 100644 --- a/src/persistence_client_library_pas_interface.c +++ b/src/persistence_client_library_pas_interface.c @@ -58,7 +58,7 @@ int check_pas_request(unsigned int request, unsigned int requestID) { case (PasMsg_Block|PasMsg_WriteBack): { - if(-1 == deliverToMainloop(CMD_PAS_BLOCK_AND_WRITE_BACK, request, requestID)) + if(-1 == deliverToMainloop_NM(CMD_PAS_BLOCK_AND_WRITE_BACK, request, requestID)) { DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("write failed w/ errno "), DLT_INT(errno), DLT_STRING(strerror(errno))); rval = PasErrorStatus_FAIL; diff --git a/src/persistence_client_library_prct_access.c b/src/persistence_client_library_prct_access.c index c0e450a..d8f169b 100644 --- a/src/persistence_client_library_prct_access.c +++ b/src/persistence_client_library_prct_access.c @@ -26,7 +26,7 @@ /// pointer to resource table database -itzam_btree gResource_table[PrctDbTableSize]; +itzam_btree gResource_table[PrctDbTableSize] = {0}; /// array to hold the information of database is already open int gResourceOpen[PrctDbTableSize] = {0}; @@ -66,6 +66,15 @@ itzam_btree* get_resource_cfg_table_by_idx(int i) return &gResource_table[i]; } +int get_resource_cfg_table_status(int i) +{ + return gResourceOpen[i]; +} + +void invalidate_resource_cfg_table(int i) +{ + gResourceOpen[i] = 0; +} // status: OK itzam_btree* get_resource_cfg_table(PersistenceRCT_e rct, int group) diff --git a/src/persistence_client_library_prct_access.h b/src/persistence_client_library_prct_access.h index 85d4b68..44982f3 100644 --- a/src/persistence_client_library_prct_access.h +++ b/src/persistence_client_library_prct_access.h @@ -62,12 +62,34 @@ int get_db_context(PersistenceInfo_s* dbContext, const char* resource_id, unsign /** - * @brief get the resource configuration table gvbd database by id + * @brief get the resource configuration table database by id * - * @return pointer to the gvdb database table or NULL if no valid database has been found + * @param i the index + * + * @return pointer to the database table or NULL if no valid database has been found */ itzam_btree* get_resource_cfg_table_by_idx(int i); +/** + * @brief get the resource configuration table status + * + * @param i the index + * + * @return status of database, 1 is db is opened and 0 is closed + */ +int get_resource_cfg_table_status(int i); + + + +/** + * @brief mark the resource configuration table as closed + * + * @param i the index + */ +void invalidate_resource_cfg_table(int i); + + + #endif /* PERSISTENCE_CLIENT_LIBRARY_ACCESS_HELPER_H */ -- 2.7.4