[PATCH 1.1] mama.c: Make sure that we load and unload bridges properly
These changes ensure that we hold the lock while opening and closing payload and
messaging brdiges. Additionally, we store the shared library handles so we can
close them when cleaning up.
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.8
diff -u -r1.128.4.7.2.2.4.19.4.8 mama.c
--- c_cpp/src/c/mama.c 12 Jan 2012 00:52:22 -0000 1.128.4.7.2.2.4.19.4.8
+++ c_cpp/src/c/mama.c 15 Jan 2012 04:31:33 -0000
@@ -187,6 +187,11 @@
/* Private Function Prototypes. */
/* ************************************************************************* */
+static mama_status
+mama_loadBridgeWithPathInternal (mamaBridge* impl,
+ const char* middlewareName,
+ const char* path,
+ uint8_t lock);
/* Description : This function will free any memory associated with a
* mamaApplicationContext object but will not free the
@@ -332,8 +337,12 @@
}
/* Will load the bridge if its not already loaded */
+ /* Lock is alread acquired at this point */
if (MAMA_STATUS_OK !=
- (status = mama_loadBridge (&bridge, statsLogMiddlewareName)))
+ (status = mama_loadBridgeWithPathInternal (&bridge,
+ statsLogMiddlewareName,
+ NULL,
+ 0)))
{
mama_log (MAMA_LOG_LEVEL_ERROR,
"mamaInternal_loadStatsLogger(): ",
@@ -914,12 +923,12 @@
mama_log (MAMA_LOG_LEVEL_SEVERE,
"mama_openWithProperties(): "
"Error connecting to Entitlements Server");
+ pthread_mutex_unlock (&gImpl.myLock);
mama_close();
if (count)
*count = gImpl.myRefCount;
- pthread_mutex_unlock (&gImpl.myLock);
return result;
}
#endif /* WITH_ENTITLEMENTS */
@@ -1151,6 +1160,11 @@
/* mamaPayloadBridgeImpl* impl = (mamaPayloadBridgeImpl*)
* gImpl.myPayloads [(uint8_t)payload];*/
gImpl.myPayloads[(uint8_t)payload] = NULL;
+ if(gImpl.myPayloadLibraries[(uint8_t)payload])
+ {
+ closeSharedLib (gImpl.myPayloadLibraries[(uint8_t)payload]);
+ gImpl.myPayloadLibraries[(uint8_t)payload] = NULL;
+ }
}
gDefaultPayload = NULL;
@@ -1250,8 +1264,10 @@
mamaMiddleware_convertToString (middleware));
}
+ gImpl.myBridges[middleware] = NULL;
+ closeSharedLib (gImpl.myBridgeLibraries[middleware]);
+ gImpl.myBridgeLibraries[middleware] = NULL;
}
- gImpl.myBridges[middleware] = NULL;
}
/* The properties must not be closed down until after the bridges have been destroyed. */
@@ -1803,8 +1821,9 @@
}
mama_status
-mama_loadPayloadBridge (mamaPayloadBridge* impl,
- const char* payloadName)
+mama_loadPayloadBridgeInternal (mamaPayloadBridge* impl,
+ const char* payloadName,
+ uint8_t lock)
{
char bridgeImplName [256];
char initFuncName [256];
@@ -1819,6 +1838,9 @@
snprintf (bridgeImplName, 256, "mama%simpl",
payloadName);
+ if (lock)
+ pthread_mutex_lock (&gImpl.myLock);
+
bridgeLib = openSharedLib (bridgeImplName, NULL);
if (!bridgeLib)
@@ -1829,6 +1851,8 @@
"Could not open payload bridge library [%s] [%s]",
bridgeImplName ? bridgeImplName : "",
getLibError());
+ if (lock)
+ pthread_mutex_unlock (&gImpl.myLock);
return MAMA_STATUS_NO_BRIDGE_IMPL;
}
@@ -1845,11 +1869,18 @@
initFuncName ? initFuncName : "",
bridgeImplName ? bridgeImplName : "");
closeSharedLib (bridgeLib);
+
+ if (lock)
+ pthread_mutex_unlock (&gImpl.myLock);
+
return MAMA_STATUS_NO_BRIDGE_IMPL;
}
if (MAMA_STATUS_OK != (status = initFunc (impl, &payloadChar)))
{
+ if (lock)
+ pthread_mutex_unlock (&gImpl.myLock);
+
return status;
}
@@ -1857,6 +1888,10 @@
{
mama_log (MAMA_LOG_LEVEL_ERROR,
"mama_loadPayloadBridge(): Error in [%s] ", initFuncName);
+
+ if (lock)
+ pthread_mutex_unlock (&gImpl.myLock);
+
return MAMA_STATUS_NO_BRIDGE_IMPL;
}
@@ -1866,7 +1901,11 @@
"mama_loadPayloadBridge(): "
"Payload bridge %s already loaded",
payloadName);
- return MAMA_STATUS_OK;
+
+ if (lock)
+ pthread_mutex_unlock (&gImpl.myLock);
+
+ return MAMA_STATUS_OK;
}
gImpl.myPayloads [(int)payloadChar] = *impl;
@@ -1881,10 +1920,20 @@
"mama_loadPayloadBridge(): "
"Sucessfully loaded %s payload bridge from library [%s]",
payloadName, bridgeImplName);
+
+ if (lock)
+ pthread_mutex_unlock (&gImpl.myLock);
return MAMA_STATUS_OK;
}
+mama_status
+mama_loadPayloadBridge (mamaPayloadBridge* impl,
+ const char* payloadName)
+{
+ return mama_loadPayloadBridgeInternal (impl, payloadName, 1);
+}
+
int
mamaInternal_generateLbmStats ()
{
@@ -1900,9 +1949,10 @@
}
mama_status
-mama_loadBridgeWithPath (mamaBridge* impl,
- const char* middlewareName,
- const char* path)
+mama_loadBridgeWithPathInternal (mamaBridge* impl,
+ const char* middlewareName,
+ const char* path,
+ uint8_t lock)
{
char bridgeImplName [256];
char initFuncName [256];
@@ -1924,15 +1974,19 @@
"mama_loadBridge(): Invalid middleware [%s]",
middlewareName);
}
+
+ if (lock)
+ pthread_mutex_lock (&gImpl.myLock);
/* Check if a bridge has already been initialized for the middleware */
if (gImpl.myBridges [middleware])
{
*impl = gImpl.myBridges [middleware];
+ if (lock)
+ pthread_mutex_unlock (&gImpl.myLock);
return MAMA_STATUS_OK;
}
-
snprintf (bridgeImplName, 256, "mama%simpl",
middlewareName);
@@ -1940,7 +1994,6 @@
if (!bridgeLib)
{
-
if (path)
{
mama_log (MAMA_LOG_LEVEL_ERROR,
@@ -1958,6 +2011,8 @@
bridgeImplName ? bridgeImplName : "",
getLibError());
}
+ if (lock)
+ pthread_mutex_unlock (&gImpl.myLock);
return MAMA_STATUS_NO_BRIDGE_IMPL;
}
@@ -1974,6 +2029,8 @@
initFuncName ? initFuncName : "",
bridgeImplName ? bridgeImplName : "");
closeSharedLib (bridgeLib);
+ if (lock)
+ pthread_mutex_unlock (&gImpl.myLock);
return MAMA_STATUS_NO_BRIDGE_IMPL;
}
@@ -1983,6 +2040,8 @@
{
mama_log (MAMA_LOG_LEVEL_ERROR,
"mama_loadBridge(): Error in [%s] ", initFuncName);
+ if (lock)
+ pthread_mutex_unlock (&gImpl.myLock);
return MAMA_STATUS_NO_BRIDGE_IMPL;
}
@@ -1995,22 +2054,37 @@
result = ((mamaBridgeImpl*)(*impl))->bridgeOpen (*impl);
if (MAMA_STATUS_OK != result)
+ {
+ if (lock)
+ pthread_mutex_unlock (&gImpl.myLock);
return result;
+ }
if (((mamaBridgeImpl*)(*impl))->bridgeGetDefaultPayloadId(&payloadName, &payloadId) == MAMA_STATUS_OK)
{
if (!gImpl.myPayloads [(uint8_t)payloadId])
{
mamaPayloadBridge payloadImpl;
- mama_loadPayloadBridge (&payloadImpl,payloadName);
+ mama_loadPayloadBridgeInternal (&payloadImpl,payloadName,0);
}
}
gImpl.myBridges [middleware] = *impl;
+ gImpl.myBridgeLibraries [middleware] = bridgeLib;
+ if (lock)
+ pthread_mutex_unlock (&gImpl.myLock);
return MAMA_STATUS_OK;
}
+mama_status
+mama_loadBridgeWithPath (mamaBridge* impl,
+ const char* middlewareName,
+ const char* path)
+{
+ return mama_loadBridgeWithPathInternal(impl, middlewareName, path, 1);
+}
+
/*
* Function pointer type for calling getVersion in the wrapper
*/
Signed-off-by: John Gray <jgray@...>