Commit 8d9d8fa1 authored by Axel Auweter's avatar Axel Auweter
Browse files

After fixing a problem where mutexes were held when destructing

them, Boost 1.54.0 is no longer a problem.
parent 31ccfc4b
......@@ -10,12 +10,12 @@
using namespace std;
using namespace boost::system;
static boost::mutex threadMtx;
#ifdef SimpleMQTTVerbose
static boost::mutex coutMtx;
#endif
static boost::mutex launchMtx;
SimpleMQTTServerThread::SimpleMQTTServerThread()
{
/*
......@@ -25,11 +25,21 @@ SimpleMQTTServerThread::SimpleMQTTServerThread()
*
* Special care must be taken not to call the run function
* before the child has gone through its constructor. Thus,
* we lock a mutex that will cause the 'launch' function to
* wait until the mutex is released by the child's
* constructor.
* we lock a mutex (launchMtx) that will cause the 'launch'
* function to wait until the mutex is released by the
* child's constructor.
*
* A second mutex (cleanupMtx) is held to allow others to
* wait for a thread to return from its child-specific
* 'run' function. This is necessary for cases where the
* child class has local objects that can only be destroyed
* after the 'run' function has finished (to avoid access
* to these objects in the 'run'function after destroying
* them). In such cases, the child class destructor can try
* to obtain the mutex in the destructor.
*/
threadMtx.lock();
launchMtx.lock();
cleanupMtx.lock();
terminate = false;
if (pthread_create(&t, NULL, launch, this) != 0) {
......@@ -76,14 +86,19 @@ void* SimpleMQTTServerThread::launch(void *selfPtr)
* before the constructor of the child class has finished.
* The lock is released at the end of the child's constructor.
*/
threadMtx.lock();
threadMtx.unlock();
launchMtx.lock();
launchMtx.unlock();
/*
* Call the child's run function...
*/
((SimpleMQTTServerThread*)selfPtr)->run();
/*
* The thread will terminate. Unlock the cleanupMtx...
*/
((SimpleMQTTServerThread*)selfPtr)->cleanupMtx.unlock();
return NULL;
}
......@@ -210,7 +225,7 @@ SimpleMQTTServerAcceptThread::SimpleMQTTServerAcceptThread(int listenSock, Simpl
* Release the lock to indicate that the constructor has
* finished. This causes the launcher to call the run function.
*/
threadMtx.unlock();
launchMtx.unlock();
}
SimpleMQTTServerAcceptThread::~SimpleMQTTServerAcceptThread()
......@@ -423,10 +438,21 @@ SimpleMQTTServerMessageThread::SimpleMQTTServerMessageThread(SimpleMQTTMessageCa
* Release the lock to indicate that the constructor has
* finished. This causes the launcher to call the run function.
*/
threadMtx.unlock();
launchMtx.unlock();
}
SimpleMQTTServerMessageThread::~SimpleMQTTServerMessageThread()
{
/*
* When this destructor is called externally, we are likely
* holding the fdsMtx mutex and waiting in poll().
* Terminate the thread from here and acquire cleanupMtx to
* ensure that the thread's 'run' function has terminated in
* order to avoid fdsMtx to be accessed after destruction.
*/
terminate = true;
cleanupMtx.lock();
cleanupMtx.unlock();
}
......@@ -14,6 +14,8 @@ protected:
pthread_t t;
bool terminate;
boost::mutex cleanupMtx;
static void* launch(void* thisPtr);
static void yield();
virtual void run() = 0;
......
......@@ -5,7 +5,7 @@ DISTFILES = thrift-0.9.0.tar.gz;https://dist.apache.org/repos/dist/release/thrif
apache-cassandra-1.2.6.tar.gz;http://mirror.netcologne.de/apache.org/cassandra/1.2.6/apache-cassandra-1.2.6-bin.tar.gz \
mosquitto-1.1.3.tar.gz;http://mosquitto.org/files/source/mosquitto-1.1.3.tar.gz \
rudeconfig-5.0.5.tar.gz;http://rudeserver.com/config/download/rudeconfig-5.0.5.tar.gz \
boost_1_53_0.tar.gz;http://netcologne.dl.sourceforge.net/project/boost/boost/1.53.0/boost_1_53_0.tar.gz
boost_1_54_0.tar.gz;http://netcologne.dl.sourceforge.net/project/boost/boost/1.54.0/boost_1_54_0.tar.gz
FETCH = wget -c --no-check-certificate -O -
MAKETHREADS ?= 4
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment