[PATCH 1.1] mama.c : Added locking around mama_open() and mama_close()


John Gray <jgray@...>
 

Improved the reference counting logic and added locking around mama_open() and

mama_close(). The change ensures that all initialization (one-time) and cleanup

only occurs once. It also ensures that the reference count never goes belowe

zero.

 

Index: c_cpp/src/c/mama.c

===================================================================

RCS file: /cvsroot/products/mama/c_cpp/src/c/mama.c,v

retrieving revision 1.128.4.7.2.2.4.19.4.5

diff -u -r1.128.4.7.2.2.4.19.4.5 mama.c

--- c_cpp/src/c/mama.c                7 Jan 2012 03:28:35 -0000              1.128.4.7.2.2.4.19.4.5

+++ c_cpp/src/c/mama.c             7 Jan 2012 03:39:39 -0000

@@ -654,6 +654,8 @@

     const char*     statsLogging            = "false";

               const char*                         catchCallbackExceptions = NULL;

+    pthread_mutex_lock (&gImpl.myLock);

+

     if (pthread_key_create(&last_err_key, NULL) != 0)

     {

         mama_log (MAMA_LOG_LEVEL_NORMAL, "WARNING!!! - CANNOT ALLOCATE KEY FOR ERRORS");

@@ -689,7 +691,14 @@

             "********************************************************");

#endif

-   if (gImpl.myRefCount++)  return result;

+    if (0 != gImpl.myRefCount)

+    {

+        if (MAMA_STATUS_OK == result)

+            gImpl.myRefCount++;

+        pthread_mutex_unlock (&gImpl.myLock);

+        return result;

+    }

+    /* Code after this point is one-time initialization */

 #ifdef WITH_INACTIVE_CHECK

     mama_log (MAMA_LOG_LEVEL_WARN,

@@ -748,10 +757,10 @@

             mama_log (MAMA_LOG_LEVEL_ERROR,

                       "mama_openWithProperties(): "

                       "Could not create stats generator.");

+            pthread_mutex_unlock (&gImpl.myLock);

             return result;

         }

-

         globalLogging           = properties_Get (gProperties, "mama.statslogging.global.logging");

         globalPublishing        = properties_Get (gProperties, "mama.statslogging.global.publishing");

         transportLogging        = properties_Get (gProperties, "mama.statslogging.transport.logging");

@@ -842,7 +851,6 @@

             }

         }

-

         if (mamaInternal_statsPublishingEnabled())

         {

             mamaInternal_loadStatsPublisher();

@@ -866,16 +874,16 @@

         mama_log (MAMA_LOG_LEVEL_SEVERE,

                   "mama_openWithProperties(): "

                   "At least one bridge must be specified");

+        pthread_mutex_unlock (&gImpl.myLock);

         return MAMA_STATUS_NO_BRIDGE_IMPL;

     }

     if (!gDefaultPayload)

     {

-

-

         mama_log (MAMA_LOG_LEVEL_SEVERE,

                   "mama_openWithProperties(): "

                   "At least one payload must be specified");

+        pthread_mutex_unlock (&gImpl.myLock);

         return MAMA_STATUS_NO_BRIDGE_IMPL;

     }

@@ -893,6 +901,7 @@

                   "mama_openWithProperties(): "

                   "Error connecting to Entitlements Server");

         mama_close();

+        pthread_mutex_unlock (&gImpl.myLock);

         return result;

     }

#endif /* WITH_ENTITLEMENTS */

@@ -929,6 +938,7 @@

             if (MAMA_STATUS_OK != (result = mamaBridgeImpl_getInternalEventQueue (bridge,

                                                                &statsGenQueue)))

             {

+                pthread_mutex_unlock (&gImpl.myLock);

                 return result;

             }

         }

@@ -938,6 +948,7 @@

             mama_log (MAMA_LOG_LEVEL_ERROR,

                       "mama_openWithProperties(): "

                       "Could not set queue for stats generator.");

+            pthread_mutex_unlock (&gImpl.myLock);

             return result;

         }

@@ -946,10 +957,13 @@

             mama_log (MAMA_LOG_LEVEL_ERROR,

                       "mama_openWithProperties(): "

                       "Failed to enable stats logging");

+            pthread_mutex_unlock (&gImpl.myLock);

             return result;

         }

     }

+    gImpl.myRefCount++;

+    pthread_mutex_unlock (&gImpl.myLock);

     return result;

}

@@ -1071,7 +1085,14 @@

     mamaMiddleware middleware = 0;

     int payload = 0;

-    if( !--gImpl.myRefCount )

+    pthread_mutex_lock (&gImpl.myLock);

+    if (gImpl.myRefCount == 0)

+    {

+        pthread_mutex_unlock (&gImpl.myLock);

+        return MAMA_STATUS_OK;

+    }

+

+    if (!--gImpl.myRefCount)

     {

#ifdef WITH_ENTITLEMENTS

         if( gEntitlementClient != 0 )

@@ -1120,7 +1141,6 @@

             gUnknownMsgStat = NULL;

         }

-

         if (gMessageStat)

         {

             mamaStat_destroy (gMessageStat);

@@ -1224,10 +1244,7 @@

         mama_freeAppContext(&appContext);

     }

-    if (gImpl.myRefCount < 0)

-    {

-        gImpl.myRefCount = 0;

-    }

+    pthread_mutex_unlock (&gImpl.myLock);

     return result;

}

 

Signed-off-by: John Gray <jgray@...>