init und deinit is not blocking anymore when they will be called multiple times
authorIngo Huerner <ingo.huerner@xse.de>
Fri, 7 Feb 2014 08:14:32 +0000 (09:14 +0100)
committerIngo Huerner <ingo.huerner@xse.de>
Fri, 7 Feb 2014 08:14:32 +0000 (09:14 +0100)
src/persistence_client_library.c
src/persistence_client_library_dbus_service.c
src/persistence_client_library_dbus_service.h
test/persistence_client_library_test.c

index f267b26..868db91 100644 (file)
 /// debug log and trace (DLT) setup
 DLT_DECLARE_CONTEXT(gDLTContext);
 
-// declared in persistence_client_library_dbus_service.c
-// used to end dbus library
-extern int bContinue;
-
 static int gShutdownMode = 0;
 
 
@@ -171,10 +167,6 @@ int pclInitLibrary(const char* appName, int shutdownMode)
       strncpy(gAppId, appName, MaxAppNameLen);
       gAppId[MaxAppNameLen-1] = '\0';
 
-      // destory mutex
-      pthread_mutex_destroy(&gDbusInitializedMtx);
-      pthread_cond_destroy(&gDbusInitializedCond);
-
       gPclInitialized++;
    }
    else if(gPclInitialized >= PCLinitialized)
@@ -183,7 +175,6 @@ int pclInitLibrary(const char* appName, int shutdownMode)
       DLT_LOG(gDLTContext, DLT_LOG_INFO, DLT_STRING("pclInitLibrary => I N I T  Persistence Client Library - "), DLT_STRING(gAppId),
                            DLT_STRING("- ONLY INCREMENT init counter: "), DLT_INT(gPclInitialized) );
    }
-
    return rval;
 }
 
@@ -195,8 +186,10 @@ int pclDeinitLibrary(void)
 
    if(gPclInitialized == PCLinitialized)
    {
+      int* retval;
       DLT_LOG(gDLTContext, DLT_LOG_INFO, DLT_STRING("pclDeinitLibrary -> D E I N I T  client library - "), DLT_STRING(gAppId),
                                          DLT_STRING("- init counter: "), DLT_INT(gPclInitialized));
+
       // unregister for lifecycle and persistence admin service dbus messages
       if(gShutdownMode != PCL_SHUTDOWN_TYPE_NONE)
          rval = unregister_lifecycle(gShutdownMode);
@@ -224,6 +217,17 @@ int pclDeinitLibrary(void)
 
       // close opend database
       pers_db_close_all();
+      // end dbus library
+      bContinue = 0;
+
+      // send quit command to dbus mainloop
+      deliverToMainloop_NM(CMD_QUIT, 0, 0);
+
+      // wait until the dbus mainloop has ended
+      pthread_join(gMainLoopThread, (void**)&retval);
+
+      pthread_mutex_unlock(&gDbusPendingRegMtx);
+      pthread_mutex_unlock(&gDbusInitializedMtx);
 
       gPclInitialized = PCLnotInitialized;
 
@@ -239,11 +243,6 @@ int pclDeinitLibrary(void)
    {
       rval = PCLnotInitialized;
    }
-
-   // end dbus library
-   bContinue = FALSE;
-
-   pthread_mutex_destroy(&gDbusPendingRegMtx);
    return rval;
 }
 
index ae45186..e802714 100644 (file)
@@ -34,7 +34,10 @@ pthread_mutex_t gDbusInitializedMtx  = PTHREAD_MUTEX_INITIALIZER;
 pthread_mutex_t gDbusPendingRegMtx   = PTHREAD_MUTEX_INITIALIZER;
 
 pthread_mutex_t gMainLoopMtx         = PTHREAD_MUTEX_INITIALIZER;
-pthread_cond_t  gMainLoopCond = PTHREAD_COND_INITIALIZER;
+pthread_cond_t  gMainLoopCond        = PTHREAD_COND_INITIALIZER;
+
+pthread_t gMainLoopThread;
+
 
 int gEfds;  // communication channel int dbus mainloop
 
@@ -243,8 +246,6 @@ void* run_mainloop(void* dataPtr)
    // setup the dbus
    mainLoop(vtablePersAdmin, vtableLifecycle, vtableFallback, dataPtr);
 
-   printf("<== run_mainloop\n");
-
    return NULL;
 }
 
@@ -253,7 +254,6 @@ void* run_mainloop(void* dataPtr)
 int setup_dbus_mainloop(void)
 {
    int rval = 0;
-   pthread_t thread;
    DBusError err;
    DBusConnection* conn = NULL;
 
@@ -261,7 +261,7 @@ int setup_dbus_mainloop(void)
 
    dbus_error_init(&err);
 
-   // wain until dbus main loop has been setup and running
+   // wait until dbus main loop has been setup and running
    pthread_mutex_lock(&gDbusInitializedMtx);
 
    // Connect to the bus and check for errors
@@ -297,7 +297,7 @@ int setup_dbus_mainloop(void)
    }
 
    // create here the dbus connection and pass to main loop
-   rval = pthread_create(&thread, NULL, run_mainloop, conn);
+   rval = pthread_create(&gMainLoopThread, NULL, run_mainloop, conn);
    if(rval)
    {
      DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("pthread_create( DBUS run_mainloop ) returned an error:"), DLT_INT(rval) );
@@ -662,7 +662,6 @@ int mainLoop(DBusObjectPathVTable vtable, DBusObjectPathVTable vtable2,
 
    pthread_cond_signal(&gDbusInitializedCond);
    pthread_mutex_unlock(&gDbusInitializedMtx);
-   printf("End Mainloop\n");
    return 0;
 }
 
index 6bce02c..12551b5 100644 (file)
@@ -30,6 +30,15 @@ extern pthread_mutex_t gDbusInitializedMtx;
 extern pthread_cond_t  gDbusInitializedCond;
 extern pthread_mutex_t gDbusPendingRegMtx;
 
+extern pthread_mutex_t gMainLoopMtx;
+
+// declared in persistence_client_library_dbus_service.c
+// used to end dbus library
+extern int bContinue;
+
+extern pthread_t gMainLoopThread;
+
+
 /// command definitions for main loop
 typedef enum ECmd
 {
@@ -78,4 +87,5 @@ 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 0ee9f24..fbb36ba 100644 (file)
@@ -28,7 +28,6 @@
 #include <dlt/dlt.h>
 #include <dlt/dlt_common.h>
 
-
 #include "persCheck.h"
 
 
@@ -59,7 +58,7 @@ char* dayOfWeek[] = { "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "F
  * Each resource below has an entry in the resource configuration table where the
  * storage location (cached or write through) and type (e.g. custom) has been configured.
  */
-START_TEST (test_GetData)
+START_TEST(test_GetData)
 {
    X_TEST_REPORT_TEST_NAME("persistence_client_library_test");
    X_TEST_REPORT_COMP_NAME("libpersistence_client_library");
@@ -1080,6 +1079,33 @@ START_TEST(test_GetPath)
 END_TEST
 
 
+
+START_TEST(test_InitDeinit)
+{
+   int ret = 0, i = 0;
+   unsigned int shutdownReg = PCL_SHUTDOWN_TYPE_FAST | PCL_SHUTDOWN_TYPE_NORMAL;
+
+   for(i=0; i< 3; i++)
+   {
+      // initialize and deinitialize 1. time
+      ret = pclInitLibrary(gTheAppId, shutdownReg);
+      pclDeinitLibrary();
+
+
+      // initialize and deinitialize 2. time
+      ret = pclInitLibrary(gTheAppId, shutdownReg);
+      pclDeinitLibrary();
+
+
+      // initialize and deinitialize 3. time
+      ret = pclInitLibrary(gTheAppId, shutdownReg);
+      pclDeinitLibrary();
+   }
+}
+END_TEST
+
+
+
 static Suite * persistencyClientLib_suite()
 {
    Suite * s  = suite_create("Persistency client library");
@@ -1129,6 +1155,9 @@ static Suite * persistencyClientLib_suite()
    TCase * tc_GetPath = tcase_create("GetPath");
    tcase_add_test(tc_GetPath, test_GetPath);
 
+   TCase * tc_InitDeinit = tcase_create("InitDeinit");
+   tcase_add_test(tc_InitDeinit, test_InitDeinit);
+
    suite_add_tcase(s, tc_persSetData);
    suite_add_tcase(s, tc_persGetData);
    suite_add_tcase(s, tc_persSetDataNoPRCT);
@@ -1143,6 +1172,7 @@ static Suite * persistencyClientLib_suite()
    suite_add_tcase(s, tc_ReadDefault);
    suite_add_tcase(s, tc_ReadConfDefault);
    suite_add_tcase(s, tc_GetPath);
+   suite_add_tcase(s, tc_InitDeinit);
    //suite_add_tcase(s, tc_Plugin); // activate only if the plugins are available
    return s;
 }