Revision: 41956
http://brlcad.svn.sourceforge.net/brlcad/?rev=41956&view=rev
Author: davidloman
Date: 2011-01-05 19:24:58 +0000 (Wed, 05 Jan 2011)
Log Message:
-----------
Fix up a multithread issue in ControlledRunnable. Proper mutex's are in place
for 'runCmd' and 'runStatus'
Modified Paths:
--------------
rt^3/trunk/include/ControlledThread.h
rt^3/trunk/include/GSThread.h
rt^3/trunk/src/GS/GeometryService.cxx
rt^3/trunk/src/libNet/PortalManager.cxx
rt^3/trunk/src/utility/ControlledThread.cxx
rt^3/trunk/src/utility/GSThread.cxx
Modified: rt^3/trunk/include/ControlledThread.h
===================================================================
--- rt^3/trunk/include/ControlledThread.h 2011-01-05 17:26:21 UTC (rev
41955)
+++ rt^3/trunk/include/ControlledThread.h 2011-01-05 19:24:58 UTC (rev
41956)
@@ -27,6 +27,7 @@
#include "GSThread.h"
#include <QtCore/QString>
+#include <QtCore/QMutex>
class ControlledThread : public GSThread
{
@@ -42,6 +43,9 @@
void terminate(bool block);
QString getThreadName();
+ bool getRunStatus();
+ bool getRunCmd();
+
protected:
virtual bool preStartupHook();
virtual bool postStartupHook();
@@ -54,12 +58,20 @@
virtual bool preShutdownHook();
virtual bool postShutdownHook();
+ void setRunCmd(bool newVal);
+ void setRunStatus(bool newVal);
+
+private:
+
/* fields */
QString threadName;
+
+ QMutex runCmdLock;
bool runCmd;
+
+ QMutex runStatusLock;
bool runStatus;
-private:
/* Disable copy cstr and =operator */
ControlledThread(ControlledThread const&){};
ControlledThread& operator=(ControlledThread const&){};
Modified: rt^3/trunk/include/GSThread.h
===================================================================
--- rt^3/trunk/include/GSThread.h 2011-01-05 17:26:21 UTC (rev 41955)
+++ rt^3/trunk/include/GSThread.h 2011-01-05 19:24:58 UTC (rev 41956)
@@ -39,6 +39,8 @@
static void msleep (unsigned long msecs);
static void usleep (unsigned long usecs);
+ void terminate();
+
protected:
/* For thread management */
Modified: rt^3/trunk/src/GS/GeometryService.cxx
===================================================================
--- rt^3/trunk/src/GS/GeometryService.cxx 2011-01-05 17:26:21 UTC (rev
41955)
+++ rt^3/trunk/src/GS/GeometryService.cxx 2011-01-05 19:24:58 UTC (rev
41956)
@@ -86,7 +86,7 @@
this->log->logINFO("GeometryService", "Starting PortalManager");
this->portalMan->start();
- while (this->runCmd) {
+ while (this->getRunStatus()) {
GSThread::msleep(100);
}
Modified: rt^3/trunk/src/libNet/PortalManager.cxx
===================================================================
--- rt^3/trunk/src/libNet/PortalManager.cxx 2011-01-05 17:26:21 UTC (rev
41955)
+++ rt^3/trunk/src/libNet/PortalManager.cxx 2011-01-05 19:24:58 UTC (rev
41956)
@@ -101,7 +101,7 @@
bool readyAccept = false;
bool readyException = false;
- while (this->runCmd) {
+ while (this->getRunCmd()) {
/* Set values EVERY loop since select() on *nix modifies this.
*/
timeout.tv_sec = 0;
timeout.tv_usec = 50 * 1000;
Modified: rt^3/trunk/src/utility/ControlledThread.cxx
===================================================================
--- rt^3/trunk/src/utility/ControlledThread.cxx 2011-01-05 17:26:21 UTC (rev
41955)
+++ rt^3/trunk/src/utility/ControlledThread.cxx 2011-01-05 19:24:58 UTC (rev
41956)
@@ -22,6 +22,8 @@
*/
#include "ControlledThread.h"
+#include "Logger.h"
+#include <QtCore/QMutexLocker>
ControlledThread::ControlledThread(QString threadName) {
if (threadName.length() <= 0) {
@@ -29,16 +31,16 @@
} else {
this->threadName = threadName;
}
- this->runCmd = false;
- this->runStatus = false;
+ this->setRunCmd(false);
+ this->setRunStatus(false);
}
ControlledThread::~ControlledThread() {}
void ControlledThread::start() {
bool preRetVal = this->preStartupHook();
- this->runCmd = true;
- GSThread::start(); //call super class start
+ this->setRunCmd(true);
+ GSThread::start(); /* call super class start */
bool postRetVal = this->postStartupHook();
}
@@ -53,13 +55,27 @@
}
void ControlledThread::terminate(bool block) {
+
bool preRetVal = this->preShutdownHook();
- this->runCmd = false;
+ this->setRunCmd(false);
- if (block)
- while (this->isRunning()) {
+ quint64 maxFailsafeTimeMS = 5 * 1000;
+
+ if (block) {
+
+ quint64 startT = Logger::getCurrentTime();
+ quint64 stopT = 0;
+ while (this->getRunStatus()) {
GSThread::msleep(100); //TODO need a failsafe here.
+ stopT = Logger::getCurrentTime();
+
+ if ((stopT - startT) >= maxFailsafeTimeMS) {
+
Logger::getInstance()->logWARNING("ControlledThread", "terminate(block=true)
reached failsafe. Forcefully stopping thread.");
+ GSThread::terminate();
+ break;
+ }
}
+ }
bool postRetVal = this->postShutdownHook();
}
@@ -68,24 +84,24 @@
if(!this->preRunHook())
return;
- this->runStatus = true;
- this->runCmd = true;
+ this->setRunCmd(true);
+ this->setRunStatus(true);
this->_run();
- this->runStatus = false;
+ this->setRunStatus(false);
if(!this->postRunHook())
return;
}
void ControlledThread::_run() {
- while (this->runCmd) {
+ while (this->getRunCmd()) {
this->_runLoopPass();
}
}
void ControlledThread::_runLoopPass() {
//DOES NOTHING BY DEFAULT
- GSThread::msleep(123);
+ GSThread::msleep(1);
}
/**
@@ -124,6 +140,32 @@
return this->threadName;
}
+bool
+ControlledThread::getRunCmd()
+{
+ QMutexLocker(&this->runCmdLock);
+ return this->runCmd;
+}
+
+bool
+ControlledThread::getRunStatus()
+{
+ QMutexLocker(&this->runStatusLock);
+ return this->runStatus;
+}
+
+void
+ControlledThread::setRunCmd(bool newVal) {
+ QMutexLocker(&this->runCmdLock);
+ this->runCmd = newVal;
+}
+
+void
+ControlledThread::setRunStatus(bool newVal) {
+ QMutexLocker(&this->runStatusLock);
+ this->runStatus = newVal;
+}
+
/*
* Local Variables:
* tab-width: 8
Modified: rt^3/trunk/src/utility/GSThread.cxx
===================================================================
--- rt^3/trunk/src/utility/GSThread.cxx 2011-01-05 17:26:21 UTC (rev 41955)
+++ rt^3/trunk/src/utility/GSThread.cxx 2011-01-05 19:24:58 UTC (rev 41956)
@@ -38,6 +38,12 @@
}
void
+GSThread::terminate()
+{
+ QThread::terminate();
+}
+
+void
GSThread::sleep(unsigned long secs)
{
QThread::sleep(secs);
This was sent by the SourceForge.net collaborative development platform, the
world's largest Open Source development site.
------------------------------------------------------------------------------
Learn how Oracle Real Application Clusters (RAC) One Node allows customers
to consolidate database storage, standardize their database environment, and,
should the need arise, upgrade to a full multi-node Oracle RAC database
without downtime or disruption
http://p.sf.net/sfu/oracle-sfdevnl
_______________________________________________
BRL-CAD Source Commits mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/brlcad-commits