Questions about MamaStartCallback
Yury Batrakov
Classification: Public
Hi guys, As everybody knows there is possibility to start MAMA bridge in background thread in C++ API: function Mama::startBackground (mamaBridge bridgeImpl, MamaStartCallback* cb) There are a couple of problems with this function though: 1. We can't ignore "MAMA startup finished" event setting the value for the second argument to nullptr - this can be fixed as a simple nullptr check in void MAMACALLTYPE stopCb (mama_status status, mamaBridge, void* closure) in mamacpp.cpp 2. There is race condition between thread calling Mama::stop and internal MAMA thread spawned by startBackground function. This race may lead to program crash. Let me describe #2 - consider the following scenario: We have a simple class MyMamaConnection class MyMamaStartCallback : public MamaStartCallback { void onStartComplete (Wombat::MamaStatus status) override { // .... Some bridge specific callback code } }; class MyMamaConnection { mamaBridge m_bridge; MyMamaStartCallback m_callback; MyMamaConnection() { Mama::startBackground (m_bridge, &m_callback) } ~MyMamaConnection() { Mama::stop(m_bridge); } }; The crash occur in destructor because Mama::stop doesn't guarantee that no threads are still using m_callback pointer after this function exited. In our case MyMamaConnection's destructor destroys m_callback object while it is still in use by the thread created by Mama::startBackground. Here are more details, file mama.c: static void* mamaStartThread (void* closure) { ... rval = mama_start (cb->mBridgeImpl); // Imagine user thread Thread_1 calling ~MyMamaConnection() from our example. // Current thread may be suspended by OS at this point while Thread_1 continues its work and deletes the object pointed by closure ... if (cb->mStopCallbackEx) // cb->mClosure points to destroyed object. cb->mStopCallbackEx (rval, cb->mBridgeImpl, cb->mClosure); ... } One of the possible solutions is to move this code from mama_close() to mama_stop(): // Get name of start background thread and destroy it const char* threadName = wombatThread_getThreadName(middlewareLib->bridge->mStartBackgroundThread); wombatThread_destroy (threadName); Let me know if it's possible to have this fixed in the next release. --- This e-mail may contain confidential and/or privileged information. If you are not the intended recipient (or have received this e-mail in error) please notify the sender immediately and delete this e-mail. Any unauthorized copying, disclosure or distribution of the material in this e-mail is strictly forbidden. Please refer to https://www.db.com/disclosures for additional EU corporate and regulatory disclosures and to http://www.db.com/unitedkingdom/content/privacy.htm for information about privacy. |
|