Replaced use of while(isRunning()) { YieldCurrentThread(); } style loops with use of join() to avoid false positives being reported by valgrind when using the helgrind tool for thread debugging.

git-svn-id: http://svn.openscenegraph.org/osg/OpenSceneGraph/trunk@14460 16af8721-9629-0410-8352-f15c8da7e697
This commit is contained in:
Robert Osfield 2014-11-04 10:46:59 +00:00
parent 997ee30039
commit 28a676e105
17 changed files with 195 additions and 233 deletions

View File

@ -59,10 +59,10 @@ class ViewerFrameThread : public OpenThreads::Thread
~ViewerFrameThread()
{
cancel();
while(isRunning())
if (isRunning())
{
OpenThreads::Thread::YieldCurrentThread();
cancel();
join();
}
}

View File

@ -37,33 +37,37 @@ public:
_done(false)
{
}
virtual ~ReadThread()
{
_done = true;
while(isRunning()) OpenThreads::Thread::YieldCurrentThread();
if (isRunning())
{
cancel();
join();
}
}
void addFileName(const std::string& filename)
{
_fileNames.push_back(filename);
}
void setStartBarrier(RefBarrier* barrier) { _startBarrier = barrier; }
void setEndBarrier(RefBarrier* barrier) { _endBarrier = barrier; }
virtual void run()
{
if (_startBarrier.valid())
if (_startBarrier.valid())
{
#if VERBOSE
#if VERBOSE
std::cout<<"Waiting on start block "<<this<<std::endl;
#endif
_startBarrier->block();
}
#if VERBOSE
#if VERBOSE
std::cout<<"Starting "<<this<<std::endl;
#endif
@ -75,31 +79,31 @@ public:
std::string filename = _fileNames.front();
_fileNames.erase(_fileNames.begin());
#if VERBOSE
#if VERBOSE
std::cout<<"Reading "<<filename;
#endif
osg::ref_ptr<osg::Node> node = osgDB::readNodeFile(filename);
#if VERBOSE
#if VERBOSE
if (node.valid()) std::cout<<".. OK"<<std::endl;
else std::cout<<".. FAILED"<<std::endl;
#endif
}
} while (!testCancel() && !_fileNames.empty() && !_done);
if (_endBarrier.valid())
if (_endBarrier.valid())
{
#if VERBOSE
#if VERBOSE
std::cout<<"Waiting on end block "<<this<<std::endl;
#endif
_endBarrier->block();
}
#if VERBOSE
#if VERBOSE
std::cout<<"Completed"<<this<<std::endl;
#endif
}
typedef std::list<std::string> FileNames;
FileNames _fileNames;
bool _done;
@ -151,7 +155,7 @@ public:
protected:
virtual ~SerializerReadFileCallback() {}
OpenThreads::Mutex _mutex;
};
@ -159,13 +163,13 @@ protected:
void runMultiThreadReadTests(int numThreads, osg::ArgumentParser& arguments)
{
#if VERBOSE
#if VERBOSE
osg::notify(osg::NOTICE)<<"runMultiThreadReadTests() -- running"<<std::endl;
#endif
if (arguments.read("preload"))
{
{
osgDB::Registry::instance()->loadLibrary(osgDB::Registry::instance()->createLibraryNameForExtension("osg"));
osgDB::Registry::instance()->loadLibrary(osgDB::Registry::instance()->createLibraryNameForExtension("rgb"));
osgDB::Registry::instance()->loadLibrary(osgDB::Registry::instance()->createLibraryNameForExtension("jpeg"));
@ -195,17 +199,17 @@ void runMultiThreadReadTests(int numThreads, osg::ArgumentParser& arguments)
readThread->addFileName("cessna.osgt");
readThread->addFileName("glider.osgt");
readThread->addFileName("town.ive");
readThreads.push_back(readThread.get());
readThread->start();
}
startBarrier->block();
endBarrier->block();
#if VERBOSE
#if VERBOSE
osg::notify(osg::NOTICE)<<"runMultiThreadReadTests() -- completed."<<std::endl;
#endif
}

View File

@ -46,8 +46,8 @@ void testFrustum(double left,double right,double bottom,double top,double zNear,
double c_bottom=0;
double c_zNear=0;
double c_zFar=0;
std::cout << "testFrustum"<<f.getFrustum(c_left,c_right,c_bottom,c_top,c_zNear,c_zFar)<<std::endl;
std::cout << " left = "<<left<<" compute "<<c_left<<std::endl;
std::cout << " right = "<<right<<" compute "<<c_right<<std::endl;
@ -57,7 +57,7 @@ void testFrustum(double left,double right,double bottom,double top,double zNear,
std::cout << " zNear = "<<zNear<<" compute "<<c_zNear<<std::endl;
std::cout << " zFar = "<<zFar<<" compute "<<c_zFar<<std::endl;
std::cout << std::endl;
}
@ -82,7 +82,7 @@ void testOrtho(double left,double right,double bottom,double top,double zNear,do
std::cout << " zNear = "<<zNear<<" compute "<<c_zNear<<std::endl;
std::cout << " zFar = "<<zFar<<" compute "<<c_zFar<<std::endl;
std::cout << std::endl;
}
@ -102,7 +102,7 @@ void testPerspective(double fovy,double aspect,double zNear,double zFar)
std::cout << " zNear = "<<zNear<<" compute "<<c_zNear<<std::endl;
std::cout << " zFar = "<<zFar<<" compute "<<c_zFar<<std::endl;
std::cout << std::endl;
}
@ -110,17 +110,17 @@ void testLookAt(const osg::Vec3& eye,const osg::Vec3& center,const osg::Vec3& up
{
osg::Matrix mv;
mv.makeLookAt(eye,center,up);
osg::Vec3 c_eye,c_center,c_up;
mv.getLookAt(c_eye,c_center,c_up);
std::cout << "testLookAt"<<std::endl;
std::cout << " eye "<<eye<< " compute "<<c_eye<<std::endl;
std::cout << " center "<<center<< " compute "<<c_center<<std::endl;
std::cout << " up "<<up<< " compute "<<c_up<<std::endl;
std::cout << std::endl;
}
@ -170,15 +170,15 @@ void sizeOfTest()
/// Exercise the Matrix.getRotate function.
/// Compare the output of:
/// q1 * q2
/// q1 * q2
/// versus
/// (mat(q1)*mat(q2)*scale).getRotate()
/// for a range of rotations
void testGetQuatFromMatrix(const osg::Vec3d& scale)
void testGetQuatFromMatrix(const osg::Vec3d& scale)
{
// Options
// acceptable error range
double eps=1e-6;
@ -187,7 +187,7 @@ void testGetQuatFromMatrix(const osg::Vec3d& scale)
// Not sure if 0's or negative values are acceptable
osg::Matrixd scalemat;
scalemat.makeScale(scale);
// range of rotations
#if 1
// wide range
@ -290,7 +290,7 @@ void testGetQuatFromMatrix(const osg::Vec3d& scale)
if(out_quat1.w()<0) out_quat1 = out_quat1 * -1.0;
if(out_quat2.w()<0) out_quat2 = out_quat2 * -1.0;
// if the output quat length is not one
// if the output quat length is not one
// or if the components do not match,
// something is amiss
@ -346,10 +346,10 @@ void testQuatRotate(const osg::Vec3d& from, const osg::Vec3d& to)
{
osg::Quat q_nicolas;
q_nicolas.makeRotate(from,to);
osg::Quat q_original;
q_original.makeRotate_original(from,to);
std::cout<<"osg::Quat::makeRotate("<<from<<", "<<to<<")"<<std::endl;
std::cout<<" q_nicolas = "<<q_nicolas<<std::endl;
std::cout<<" q_original = "<<q_original<<std::endl;
@ -370,16 +370,16 @@ void testQuat(const osg::Vec3d& quat_scale)
osg::Matrix m1 = osg::Matrix::rotate(q1);
osg::Matrix m2 = osg::Matrix::rotate(q2);
osg::Matrix m1_2 = m1*m2;
osg::Matrix m2_1 = m2*m1;
osg::Quat qm1_2;
qm1_2.set(m1_2);
osg::Quat qm2_1;
qm2_1.set(m2_1);
std::cout<<"q1*q2 = "<<q1_2<<std::endl;
std::cout<<"q2*q1 = "<<q2_1<<std::endl;
std::cout<<"m1*m2 = "<<qm1_2<<std::endl;
@ -406,10 +406,10 @@ void testQuat(const osg::Vec3d& quat_scale)
0.0, 0.5, 0.0, 0.0,
0.0, 0.0, 0.5, 0.0,
1.0, 1.0, 1.0, 1.0);
osg::Quat quat;
matrix.get(quat);
osg::notify(osg::NOTICE)<<"Matrix = "<<matrix<<"rotation = "<<quat<<", expected quat = (0,0,0,1)"<<std::endl;
}
@ -475,9 +475,10 @@ public:
~NotifyThread()
{
_done = true;
while(isRunning())
if (isRunning())
{
OpenThreads::Thread::YieldCurrentThread();
cancel();
join();
}
}
@ -487,7 +488,7 @@ public:
unsigned int count=0;
while(!_done)
while(!_done)
{
++count;
#if 1
@ -503,7 +504,7 @@ public:
bool _done;
osg::NotifySeverity _level;
std::string _message;
};
void testThreadInitAndExit()
@ -514,10 +515,10 @@ void testThreadInitAndExit()
MyThread thread;
thread.startThread();
}
// add a sleep to allow the thread start to fall over it its going to.
OpenThreads::Thread::microSleep(500000);
std::cout<<"pass thread start and delete test"<<std::endl<<std::endl;
@ -572,7 +573,7 @@ int main( int argc, char** argv )
arguments.getApplicationUsage()->addCommandLineOption("matrix","Display qualified tests.");
arguments.getApplicationUsage()->addCommandLineOption("performance","Display qualified tests.");
arguments.getApplicationUsage()->addCommandLineOption("read-threads <numthreads>","Run multi-thread reading test.");
if (arguments.argc()<=1)
{
@ -580,35 +581,35 @@ int main( int argc, char** argv )
return 1;
}
bool printQualifiedTest = false;
while (arguments.read("qt")) printQualifiedTest = true;
bool printQualifiedTest = false;
while (arguments.read("qt")) printQualifiedTest = true;
bool printMatrixTest = false;
while (arguments.read("matrix")) printMatrixTest = true;
bool printMatrixTest = false;
while (arguments.read("matrix")) printMatrixTest = true;
bool printSizeOfTest = false;
bool printSizeOfTest = false;
while (arguments.read("sizeof")) printSizeOfTest = true;
bool printFileNameUtilsTests = false;
while (arguments.read("filenames")) printFileNameUtilsTests = true;
bool printQuatTest = false;
bool printQuatTest = false;
while (arguments.read("quat")) printQuatTest = true;
int numReadThreads = 0;
int numReadThreads = 0;
while (arguments.read("read-threads", numReadThreads)) {}
bool printPolytopeTest = false;
bool printPolytopeTest = false;
while (arguments.read("polytope")) printPolytopeTest = true;
bool doTestThreadInitAndExit = false;
while (arguments.read("thread")) doTestThreadInitAndExit = true;
osg::Vec3d quat_scale(1.0,1.0,1.0);
while (arguments.read("quat_scaled", quat_scale.x(), quat_scale.y(), quat_scale.z() )) printQuatTest = true;
osg::Vec3d quat_scale(1.0,1.0,1.0);
while (arguments.read("quat_scaled", quat_scale.x(), quat_scale.y(), quat_scale.z() )) printQuatTest = true;
bool performanceTest = false;
while (arguments.read("p") || arguments.read("performance")) performanceTest = true;
bool performanceTest = false;
while (arguments.read("p") || arguments.read("performance")) performanceTest = true;
// if user request help write it out to cout.
if (arguments.read("-h") || arguments.read("--help"))
@ -627,7 +628,7 @@ int main( int argc, char** argv )
arguments.writeErrorMessages(std::cout);
return 1;
}
if (printQuatTest)
{
testQuat(quat_scale);
@ -648,7 +649,7 @@ int main( int argc, char** argv )
testLookAt(osg::Vec3(10.0,4.0,2.0),osg::Vec3(10.0,4.0,2.0)+osg::Vec3(0.0,1.0,0.0),osg::Vec3(0.0,0.0,1.0));
testLookAt(osg::Vec3(10.0,4.0,2.0),osg::Vec3(10.0,4.0,2.0)+osg::Vec3(1.0,1.0,0.0),osg::Vec3(0.0,0.0,1.0));
testMatrixInvert(osg::Matrix(0.999848, -0.002700, 0.017242, -0.1715,
0, 0.987960, 0.154710, 0.207295,
-0.017452, -0.154687, 0.987809, -0.98239,
@ -662,11 +663,11 @@ int main( int argc, char** argv )
testDecompose();
}
if (printSizeOfTest)
{
std::cout<<"**** sizeof() tests ******"<<std::endl;
sizeOfTest();
std::cout<<std::endl;
@ -676,7 +677,7 @@ int main( int argc, char** argv )
if (performanceTest)
{
std::cout<<"**** performance tests ******"<<std::endl;
runPerformanceTests();
}
@ -693,12 +694,12 @@ int main( int argc, char** argv )
}
if (printQualifiedTest)
if (printQualifiedTest)
{
std::cout<<"***** Qualified Tests ******"<<std::endl;
osgUtx::QualifiedTestPrinter printer;
osgUtx::TestGraph::instance().root()->accept( printer );
osgUtx::TestGraph::instance().root()->accept( printer );
std::cout<<std::endl;
}

View File

@ -21,21 +21,21 @@
#include <iostream>
// The idea of user stats is that you record times or values in the viewer's
// stats, and you also tell the stats handler to watch those values each
// The idea of user stats is that you record times or values in the viewer's
// stats, and you also tell the stats handler to watch those values each
// frame. The stats handler can display the stats in three ways:
// - A numeric time beside the stat name
// Requires that an elapsed time be recorded in the viewer's stats for the
// Requires that an elapsed time be recorded in the viewer's stats for the
// "timeTakenName".
// - A bar in the top bar graph
// Requires that two times (relative to the viewer's start tick) be
// Requires that two times (relative to the viewer's start tick) be
// recorded in the viewer's stats for the "beginTimeName" and "endTimeName".
// - A line in the bottom graph
// Requires that an elapsed time be recorded in the viewer's stats for the
// Requires that an elapsed time be recorded in the viewer's stats for the
// "timeTakenName".
// Anything you want to time has to use a consistent name in both the stats
// Anything you want to time has to use a consistent name in both the stats
// handler and the viewer stats, so it's a good idea to use constants to make
// sure the names are the same everywhere.
const std::string frameNumberName = "Custom Frame Number";
@ -49,54 +49,54 @@ const std::string otherThreadTimeName = "Thread";
void initUserStats(osgViewer::StatsHandler* statsHandler)
{
// This line displays the frame number. It's not averaged, just displayed as is.
statsHandler->addUserStatsLine("Frame", osg::Vec4(0.7,0.7,0.7,1), osg::Vec4(0.7,0.7,0.7,0.5),
statsHandler->addUserStatsLine("Frame", osg::Vec4(0.7,0.7,0.7,1), osg::Vec4(0.7,0.7,0.7,0.5),
frameNumberName, 1.0, false, false, "", "", 0.0);
// This line displays the frame time (from beginning of event to end of draw). No bars.
statsHandler->addUserStatsLine("MS/frame", osg::Vec4(1,0,1,1), osg::Vec4(1,0,1,0.5),
statsHandler->addUserStatsLine("MS/frame", osg::Vec4(1,0,1,1), osg::Vec4(1,0,1,0.5),
frameTimeName, 1000.0, true, false, "", "", 0.02);
// This line displays the sum of update and main camera cull times.
statsHandler->addUserStatsLine("Custom", osg::Vec4(1,1,1,1), osg::Vec4(1,1,1,0.5),
statsHandler->addUserStatsLine("Custom", osg::Vec4(1,1,1,1), osg::Vec4(1,1,1,0.5),
customTimeName + " time taken", 1000.0, true, false, customTimeName + " begin", customTimeName + " end", 0.016);
// This line displays the time taken by a function below ( doSomethingAndTimeIt() )
statsHandler->addUserStatsLine("Sleep1", osg::Vec4(1,0,0,1), osg::Vec4(1,0,0,0.5),
statsHandler->addUserStatsLine("Sleep1", osg::Vec4(1,0,0,1), osg::Vec4(1,0,0,0.5),
operation1TimeName + " time taken", 1000.0, true, false, operation1TimeName + " begin", operation1TimeName + " end", 0.016);
// This line displays the time taken by a function below ( doSomethingAndTimeIt() )
statsHandler->addUserStatsLine("Sleep2", osg::Vec4(1,0.5,0.5,1), osg::Vec4(1,0.5,0.5,0.5),
statsHandler->addUserStatsLine("Sleep2", osg::Vec4(1,0.5,0.5,1), osg::Vec4(1,0.5,0.5,0.5),
operation2TimeName + " time taken", 1000.0, true, false, operation2TimeName + " begin", operation2TimeName + " end", 0.016);
// This line displays the time taken by a function below ( doSomethingAndTimeIt() )
statsHandler->addUserStatsLine("Thread", osg::Vec4(0,0.5,0,1), osg::Vec4(0,0.5,0,0.5),
statsHandler->addUserStatsLine("Thread", osg::Vec4(0,0.5,0,1), osg::Vec4(0,0.5,0,0.5),
otherThreadTimeName + " time taken", 1000.0, true, false, otherThreadTimeName + " begin", otherThreadTimeName + " end", 0.016);
}
void updateUserStats(osgViewer::Viewer& viewer)
{
// Test the custom stats line by just adding up the update and cull
// Test the custom stats line by just adding up the update and cull
// times for the viewer main camera for the previous frame.
if (viewer.getViewerStats()->collectStats("update") && viewer.getCamera()->getStats()->collectStats("rendering"))
{
// First get the frame number. The code below assumes that
// First get the frame number. The code below assumes that
// updateUserStats() is called after advance(), so the frame number
// that will be returned is for the frame that has just started and is
// not rendered yet. The previous frame is framenumber-1, but we can't
// use that frame's timings because it's probably not finished
// use that frame's timings because it's probably not finished
// rendering yet (in multithreaded viewer modes). So we'll use the
// timings for framenumber-2 for this demo.
unsigned int framenumber = viewer.getFrameStamp()->getFrameNumber();
// Get the update time and the viewer main camera's cull time. We use
// getAveragedAttribute() in order to get the actual time elapsed as
// Get the update time and the viewer main camera's cull time. We use
// getAveragedAttribute() in order to get the actual time elapsed as
// calculated by the stats.
double update = 0.0, cull = 0.0;
viewer.getViewerStats()->getAveragedAttribute("Update traversal time taken", update);
viewer.getCamera()->getStats()->getAveragedAttribute("Cull traversal time taken", cull);
// Get various begin and end times, note these are not elapsed times
// Get various begin and end times, note these are not elapsed times
// in a frame but rather the simulation time at those moments.
double eventBegin = 0.0, updateBegin = 0.0, cullEnd = 0.0, drawEnd = 0.0;
viewer.getViewerStats()->getAttribute(framenumber-2, "Event traversal begin time", eventBegin);
@ -112,11 +112,11 @@ void updateUserStats(osgViewer::Viewer& viewer)
// This line displays the sum of update and main camera cull times.
viewer.getViewerStats()->setAttribute(framenumber-1, customTimeName + " time taken", update+cull);
// Since we give begin and end times that correspond to the begin of
// the update phase and the end of the cull phase, the bar in the
// graph will not correspond to the summed times above if something
// happened between update and cull (as in this demo). Also, we need
// to translate the updateBegin and cullEnd times by one frame since
// Since we give begin and end times that correspond to the begin of
// the update phase and the end of the cull phase, the bar in the
// graph will not correspond to the summed times above if something
// happened between update and cull (as in this demo). Also, we need
// to translate the updateBegin and cullEnd times by one frame since
// we're taking the times for framenumber-2 but using them to display
// in the framenumber-1 graph.
viewer.getViewerStats()->setAttribute(framenumber-1, customTimeName + " begin", updateBegin + (1.0/60.0));
@ -125,7 +125,7 @@ void updateUserStats(osgViewer::Viewer& viewer)
}
/// Utility function you call before something you want to time, so that the
/// Utility function you call before something you want to time, so that the
/// recorded times will all be consistent using the viewer's time.
void startTiming(osgViewer::Viewer& viewer, const std::string& name)
{
@ -136,7 +136,7 @@ void startTiming(osgViewer::Viewer& viewer, const std::string& name)
viewer.getViewerStats()->setAttribute(framenumber, name + " begin", currentTime);
}
/// Utility function you call after something you want to time, so that the
/// Utility function you call after something you want to time, so that the
/// recorded times will all be consistent using the viewer's time.
void endTiming(osgViewer::Viewer& viewer, const std::string& name)
{
@ -157,7 +157,7 @@ void endTiming(osgViewer::Viewer& viewer, const std::string& name)
}
/// Will just sleep for the given number of milliseconds in the same thread
/// Will just sleep for the given number of milliseconds in the same thread
/// as the caller, recording the time taken in the viewer's stats.
void doSomethingAndTimeIt(osgViewer::Viewer& viewer, const std::string& name, double milliseconds)
{
@ -166,7 +166,7 @@ void doSomethingAndTimeIt(osgViewer::Viewer& viewer, const std::string& name, do
//------------------------------------------------------------
// Your processing goes here.
// Do nothing for the specified number of milliseconds, just so we can
// Do nothing for the specified number of milliseconds, just so we can
// see it in the stats.
osg::Timer_t startTick = osg::Timer::instance()->tick();
while (osg::Timer::instance()->delta_m(startTick, osg::Timer::instance()->tick()) < milliseconds)
@ -179,8 +179,8 @@ void doSomethingAndTimeIt(osgViewer::Viewer& viewer, const std::string& name, do
}
/// Thread that will sleep for the given number of milliseconds, recording
/// the time taken in the viewer's stats, whenever its process() method is
/// Thread that will sleep for the given number of milliseconds, recording
/// the time taken in the viewer's stats, whenever its process() method is
/// called.
class UselessThread : public OpenThreads::Thread
{
@ -204,7 +204,7 @@ public:
//------------------------------------------------------------
// Your processing goes here.
// Do nothing for the specified number of milliseconds, just so we can
// Do nothing for the specified number of milliseconds, just so we can
// see it in the stats.
osg::Timer_t startTick = osg::Timer::instance()->tick();
while (osg::Timer::instance()->delta_m(startTick, osg::Timer::instance()->tick()) < _timeToRun)
@ -337,7 +337,7 @@ int main(int argc, char** argv)
viewer.realize();
// Start up a thread that will just run for a fixed time each frame, in
// Start up a thread that will just run for a fixed time each frame, in
// parallel to the frame loop.
UselessThread thread(viewer, 6.0);
thread.start();
@ -357,7 +357,7 @@ int main(int argc, char** argv)
viewer.eventTraversal();
viewer.updateTraversal();
// Eat up some time on the viewer thread between the update and cull
// Eat up some time on the viewer thread between the update and cull
// phases.
doSomethingAndTimeIt(viewer, operation2TimeName, 3.0);
@ -365,9 +365,6 @@ int main(int argc, char** argv)
}
thread.cancel();
while (thread.isRunning())
{
OpenThreads::Thread::YieldCurrentThread();
}
thread.join();
}

View File

@ -5,7 +5,7 @@
cOSG::cOSG(HWND hWnd) :
m_hWnd(hWnd)
m_hWnd(hWnd)
{
}
@ -73,7 +73,7 @@ void cOSG::InitCameraConfig(void)
// Add a Stats Handler to the viewer
mViewer->addEventHandler(new osgViewer::StatsHandler);
// Get the current window size
::GetWindowRect(m_hWnd, &rect);
@ -161,8 +161,8 @@ void cOSG::PostFrameUpdate()
//Sleep(10); // Use this command if you need to allow other processes to have cpu time
}
// For some reason this has to be here to avoid issue:
// if you have multiple OSG windows up
// For some reason this has to be here to avoid issue:
// if you have multiple OSG windows up
// and you exit one then all stop rendering
AfxMessageBox("Exit Rendering Thread");
@ -177,8 +177,11 @@ CRenderingThread::CRenderingThread( cOSG* ptr )
CRenderingThread::~CRenderingThread()
{
_done = true;
while( isRunning() )
OpenThreads::Thread::YieldCurrentThread();
if (isRunning())
{
cancel();
join();
}
}
void CRenderingThread::run()

View File

@ -201,7 +201,7 @@ class OSG_EXPORT OperationThread : public Referenced, public OpenThreads::Thread
void setDone(bool done);
bool getDone() const { return _done; }
bool getDone() const { return _done!=0; }
/** Cancel this graphics thread.*/
virtual int cancel();
@ -212,7 +212,7 @@ class OSG_EXPORT OperationThread : public Referenced, public OpenThreads::Thread
observer_ptr<Object> _parent;
bool _done;
OpenThreads::Atomic _done;
OpenThreads::Mutex _threadMutex;
osg::ref_ptr<OperationQueue> _operationQueue;

View File

@ -456,6 +456,10 @@ Thread::~Thread()
// Kill the thread when it is destructed
//
cancel();
// wait till the thread is stopped before finishing.
join();
}
delete pd;

View File

@ -1,13 +1,13 @@
/* -*-c++-*- OpenThreads library, Copyright (C) 2002 - 2007 The Open Thread Group
*
* This library is open source and may be redistributed and/or modified under
* the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
* This library is open source and may be redistributed and/or modified under
* the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
* (at your option) any later version. The full license is in LICENSE file
* included with this distribution, and on the openscenegraph.org website.
*
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* OpenSceneGraph Public License for more details.
*/
@ -54,7 +54,7 @@ int Thread::GetConcurrency()
Thread::Thread()
{
if (!s_isInitialized) Init();
QtThreadPrivateData* pd = new QtThreadPrivateData(this);
pd->isRunning = false;
pd->detached = false;
@ -65,7 +65,7 @@ Thread::Thread()
pd->stackSize = 0;
pd->threadPolicy = Thread::THREAD_SCHEDULE_DEFAULT;
pd->threadPriority = Thread::THREAD_PRIORITY_DEFAULT;
_prvData = static_cast<void*>(pd);
}
@ -82,6 +82,8 @@ Thread::~Thread()
{
std::cout<<"Error: Thread "<< this <<" still running in destructor"<<std::endl;
cancel();
join();
}
delete pd;
_prvData = 0;
@ -90,7 +92,7 @@ Thread::~Thread()
Thread* Thread::CurrentThread()
{
if (!s_isInitialized) Thread::Init();
QtThreadPrivateData* pd = static_cast<QtThreadPrivateData*>(QThread::currentThread());
return (pd ? pd->getMasterThread() : 0);
}
@ -151,10 +153,10 @@ int Thread::start()
{
QtThreadPrivateData* pd = static_cast<QtThreadPrivateData*>(_prvData);
pd->threadStartedBlock.reset();
pd->setStackSize( pd->stackSize );
pd->start();
// wait till the thread has actually started.
pd->threadStartedBlock.block();
return 0;
@ -209,13 +211,13 @@ int Thread::testCancel()
QtThreadPrivateData* pd = static_cast<QtThreadPrivateData*>(_prvData);
if (!pd->cancelled)
return 0;
if (pd->cancelMode == 2)
return -1;
if (pd!=QThread::currentThread())
return -1;
throw QtThreadCanceled();
}
@ -232,7 +234,7 @@ int Thread::cancel()
{
if (pd->cancelMode == 2)
return -1;
pd->cancelled = true;
if (pd->cancelMode == 1)
{
@ -294,7 +296,7 @@ int Thread::setSchedulePriority(ThreadPriority priority)
{
QtThreadPrivateData* pd = static_cast<QtThreadPrivateData*>(_prvData);
pd->threadPriority = priority;
if (pd->isRunning)
pd->applyPriority();
return 0;
@ -374,7 +376,7 @@ int Thread::setProcessorAffinity(unsigned int cpunum)
QtThreadPrivateData* pd = static_cast<QtThreadPrivateData*>(_prvData);
pd->cpunum = cpunum;
if (!pd->isRunning) return 0;
// FIXME:
// Qt doesn't have a platform-independent thread affinity method at present.
// Does it automatically configure threads on different processors, or we have to do it ourselves?
@ -391,7 +393,7 @@ void Thread::printSchedulingInfo()
{
QtThreadPrivateData* pd = static_cast<QtThreadPrivateData*>(_prvData);
std::cout << "Thread "<< pd->getMasterThread() <<" priority: ";
switch (pd->threadPriority)
{
case Thread::THREAD_PRIORITY_MAX:
@ -453,7 +455,7 @@ int OpenThreads::GetNumberOfProcessors()
int OpenThreads::SetProcessorAffinityOfCurrentThread(unsigned int cpunum)
{
if (cpunum<0) return -1;
Thread::Init();
Thread* thread = Thread::CurrentThread();
if (thread)

View File

@ -1,13 +1,13 @@
/* -*-c++-*- OpenThreads library, Copyright (C) 2002 - 2007 The Open Thread Group
*
* This library is open source and may be redistributed and/or modified under
* the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
* This library is open source and may be redistributed and/or modified under
* the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
* (at your option) any later version. The full license is in LICENSE file
* included with this distribution, and on the openscenegraph.org website.
*
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* OpenSceneGraph Public License for more details.
*/
@ -156,10 +156,10 @@ void ThreadPrivateActions::StartThread(void *data)
pd->stackSizeLocked = true;
pd->isRunning = true;
// release the thread that created this thread.
pd->threadStartedBlock.release();
thread->run();
pd->isRunning = false;
@ -380,9 +380,7 @@ Thread::~Thread()
//
cancel();
while (pd->isRunning == true) {
::usleep(1);
}
join();
}
@ -520,7 +518,7 @@ int Thread::start() {
//
int Thread::startThread()
{
if (_prvData) return start();
if (_prvData) return start();
else return 0;
}
@ -808,7 +806,7 @@ int OpenThreads::SetProcessorAffinityOfCurrentThread(unsigned int cpunum)
Thread::Init();
Thread* thread = Thread::CurrentThread();
if (thread)
if (thread)
{
return thread->setProcessorAffinity(cpunum);
}

View File

@ -1,13 +1,13 @@
/* -*-c++-*- OpenThreads library, Copyright (C) 2002 - 2007 The Open Thread Group
*
* This library is open source and may be redistributed and/or modified under
* the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
* This library is open source and may be redistributed and/or modified under
* the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
* (at your option) any later version. The full license is in LICENSE file
* included with this distribution, and on the openscenegraph.org website.
*
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* OpenSceneGraph Public License for more details.
*/
@ -89,7 +89,7 @@ namespace OpenThreads {
static unsigned int __stdcall StartThread(void *data) {
Thread *thread = static_cast<Thread *>(data);
Win32ThreadPrivateData *pd =
static_cast<Win32ThreadPrivateData *>(thread->_prvData);
@ -102,7 +102,7 @@ namespace OpenThreads {
SetThreadSchedulingParams(thread);
pd->isRunning = true;
// release the thread that created this thread.
pd->threadStartedBlock.release();
@ -276,10 +276,12 @@ Thread::~Thread()
std::cout<<"Error: Thread "<<this<<" still running in destructor"<<std::endl;
pd->cancelMode = 0;
cancel();
join();
}
delete pd;
_prvData = 0;
}
//-----------------------------------------------------------------------------
@ -337,11 +339,11 @@ int Thread::start() {
//-------------------------------------------------------------------------
// Prohibit the stack size from being changed.
// (bb 5/13/2005) it actually doesn't matter.
// 1) usually setStackSize()/start() sequence is serialized.
// 2) if not than we're in trouble anyway - nothing is protected
// 1) usually setStackSize()/start() sequence is serialized.
// 2) if not than we're in trouble anyway - nothing is protected
// pd->stackSizeLocked = true;
unsigned int ID;
pd->threadStartedBlock.reset();
pd->tid.set( (void*)_beginthreadex(NULL,static_cast<unsigned>(pd->stackSize),ThreadPrivateActions::StartThread,static_cast<void *>(this),CREATE_SUSPENDED,&ID));
@ -362,7 +364,7 @@ int Thread::start() {
int Thread::startThread()
{
if (_prvData) return start();
if (_prvData) return start();
else return 0;
}
@ -685,7 +687,7 @@ int OpenThreads::SetProcessorAffinityOfCurrentThread(unsigned int cpunum)
Thread::Init();
Thread* thread = Thread::CurrentThread();
if (thread)
if (thread)
{
return thread->setProcessorAffinity(cpunum);
}

View File

@ -264,7 +264,7 @@ void OperationQueue::removeOperationThread(OperationThread* thread)
OperationThread::OperationThread():
osg::Referenced(true),
_parent(0),
_done(false)
_done(0)
{
setOperationQueue(new OperationQueue);
}
@ -293,9 +293,10 @@ void OperationThread::setOperationQueue(OperationQueue* opq)
void OperationThread::setDone(bool done)
{
if (_done==done) return;
unsigned d = done?0:1;
if (_done==d) return;
_done = true;
_done.exchange(d);
if (done)
{
@ -322,7 +323,7 @@ int OperationThread::cancel()
if( isRunning() )
{
_done = true;
_done.exchange(1);
OSG_INFO<<" Doing cancel "<<this<<std::endl;
@ -339,27 +340,7 @@ int OperationThread::cancel()
}
// then wait for the the thread to stop running.
while(isRunning())
{
#if 1
{
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_threadMutex);
if (_operationQueue.valid())
{
_operationQueue->releaseOperationsBlock();
// _operationQueue->releaseAllOperations();
}
if (_currentOperation.valid()) _currentOperation->release();
}
#endif
// commenting out debug info as it was cashing crash on exit, presumable
// due to OSG_NOTIFY or std::cout destructing earlier than this destructor.
OSG_DEBUG<<" Waiting for OperationThread to cancel "<<this<<std::endl;
OpenThreads::Thread::YieldCurrentThread();
}
join();
}
OSG_INFO<<" OperationThread::cancel() thread cancelled "<<this<<" isRunning()="<<isRunning()<<std::endl;

View File

@ -662,14 +662,7 @@ int DatabasePager::DatabaseThread::cancel()
break;
}
// then wait for the the thread to stop running.
while(isRunning())
{
// commenting out debug info as it was cashing crash on exit, presumable
// due to OSG_NOTICE or std::cout destructing earlier than this destructor.
// OSG_INFO<<"Waiting for DatabasePager::DatabaseThread to cancel"<<std::endl;
OpenThreads::Thread::YieldCurrentThread();
}
join();
// _startThreadCalled = false;
}

View File

@ -158,17 +158,11 @@ int ImagePager::ImageThread::cancel()
// _databasePagerThreadBlock->release();
// then wait for the the thread to stop running.
while(isRunning())
{
// commenting out debug info as it was cashing crash on exit, presumable
// due to osg::notify or std::cout destructing earlier than this destructor.
// OSG_DEBUG<<"Waiting for DatabasePager to cancel"<<std::endl;
OpenThreads::Thread::YieldCurrentThread();
}
join();
// _startThreadCalled = false;
}
//std::cout<<"DatabasePager::~DatabasePager() stopped running"<<std::endl;
//std::cout<<"ImagePager::cancel() thread stopped running"<<std::endl;
return result;
}

View File

@ -152,19 +152,6 @@ RenderSurface::RenderSurface( void )
RenderSurface::~RenderSurface( void )
{
#if 0
cancel();
_fini();
while (isRunning())
{
//std::cout << "waiting for RenderSurface to cancel"<<std::endl;
OpenThreads::Thread::YieldCurrentThread();
}
delete _threadReady;
#endif
}

View File

@ -95,11 +95,10 @@ public:
virtual void quit( bool waitForThreadToExit=true )
{
_done = true;
if ( waitForThreadToExit )
if (isRunning() && waitForThreadToExit)
{
while( isRunning() )
OpenThreads::Thread::YieldCurrentThread();
OSG_DEBUG<<"GifImageStream thread quitted"<<std::endl;
cancel();
join();
}
}

View File

@ -120,13 +120,9 @@ void QuicktimeImageStream::quit(bool wiatForThreadToExit)
OSG_DEBUG<<"Sending quit"<<this<<std::endl;
setCmd(THREAD_QUIT);
if (wiatForThreadToExit)
if (isRunning() && wiatForThreadToExit)
{
while(isRunning())
{
OSG_DEBUG<<"Waiting for QuicktimeImageStream to quit"<<this<<std::endl;
OpenThreads::Thread::YieldCurrentThread();
}
join();
OSG_DEBUG<<"QuicktimeImageStream has quit"<<this<<std::endl;
}
}

View File

@ -73,9 +73,10 @@ class LibVncImage : public osgWidget::VncImage
virtual ~RfbThread()
{
_done = true;
while(isRunning())
if (isRunning())
{
OpenThreads::Thread::YieldCurrentThread();
cancel();
join();
}
}
@ -97,9 +98,9 @@ class LibVncImage : public osgWidget::VncImage
{
// OSG_NOTICE<<"Timed out"<<std::endl;
}
double currentTime = _image->time();
double timeBeforeIdle = 0.1;
@ -115,7 +116,7 @@ class LibVncImage : public osgWidget::VncImage
//OSG_NOTICE<<"New: Should still be active"<<std::endl;
}
} while (!_done && !testCancel());
}
@ -321,8 +322,8 @@ rfbBool LibVncImage::resizeImage(rfbClient* client)
void LibVncImage::updateImage(rfbClient* client,int x,int y,int w,int h)
{
LibVncImage* image = (LibVncImage*)(rfbClientGetClientData(client, 0));
image->dirty();
image->dirty();
}
bool LibVncImage::sendPointerEvent(int x, int y, int buttonMask)
@ -348,9 +349,9 @@ bool LibVncImage::sendKeyEvent(int key, bool keyDown)
void LibVncImage::setFrameLastRendered(const osg::FrameStamp*)
{
_timeOfLastRender = time();
// release block
_inactiveBlock->release();
}