Fix a deadlock when receiving shutdown mode
authorIngo Huerner <ingo.huerner@xse.de>
Wed, 27 Nov 2013 13:52:46 +0000 (14:52 +0100)
committerIngo Huerner <ingo.huerner@xse.de>
Wed, 27 Nov 2013 13:52:46 +0000 (14:52 +0100)
src/persistence_client_library_dbus_cmd.c
src/persistence_client_library_dbus_service.c
src/persistence_client_library_dbus_service.h
src/persistence_client_library_lc_interface.c
src/persistence_client_library_pas_interface.c
src/persistence_client_library_prct_access.c
src/persistence_client_library_prct_access.h

index eee0722..dc1e5ff 100644 (file)
@@ -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;
       }
    }
 
index 9b86343..81963bd 100644 (file)
@@ -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;
 }
 
index f80c7c9..e5eff44 100644 (file)
@@ -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_ */
index 50324a2..0c19936 100644 (file)
@@ -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);
 }
 
index f9a7099..3fb8ff1 100644 (file)
@@ -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;
index c0e450a..d8f169b 100644 (file)
@@ -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)
index 85d4b68..44982f3 100644 (file)
@@ -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 */