From 28a676e10564689d5e9ea3126d28244cce452894 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Tue, 4 Nov 2014 10:46:59 +0000 Subject: [PATCH] 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 --- examples/osgQtBrowser/osgQtBrowser.cpp | 6 +- examples/osgunittests/MultiThreadRead.cpp | 48 +++++---- examples/osgunittests/osgunittests.cpp | 101 +++++++++--------- examples/osguserstats/osguserstats.cpp | 69 ++++++------ examples/osgviewerMFC/MFC_OSG.cpp | 15 +-- include/osg/OperationThread | 4 +- src/OpenThreads/pthreads/PThread.cpp | 4 + src/OpenThreads/qt/QtThread.cpp | 36 ++++--- src/OpenThreads/sproc/SprocThread.c++ | 20 ++-- src/OpenThreads/win32/Win32Thread.cpp | 26 ++--- src/osg/OperationThread.cpp | 31 ++---- src/osgDB/DatabasePager.cpp | 9 +- src/osgDB/ImagePager.cpp | 10 +- src/osgPlugins/cfg/RenderSurface.cpp | 13 --- src/osgPlugins/gif/ReaderWriterGIF.cpp | 7 +- .../quicktime/QuicktimeImageStream.cpp | 8 +- src/osgPlugins/vnc/ReaderWriterVNC.cpp | 21 ++-- 17 files changed, 195 insertions(+), 233 deletions(-) diff --git a/examples/osgQtBrowser/osgQtBrowser.cpp b/examples/osgQtBrowser/osgQtBrowser.cpp index 8f3df9fb8..73028f8f7 100644 --- a/examples/osgQtBrowser/osgQtBrowser.cpp +++ b/examples/osgQtBrowser/osgQtBrowser.cpp @@ -59,10 +59,10 @@ class ViewerFrameThread : public OpenThreads::Thread ~ViewerFrameThread() { - cancel(); - while(isRunning()) + if (isRunning()) { - OpenThreads::Thread::YieldCurrentThread(); + cancel(); + join(); } } diff --git a/examples/osgunittests/MultiThreadRead.cpp b/examples/osgunittests/MultiThreadRead.cpp index c2078dec5..c0bb228cd 100644 --- a/examples/osgunittests/MultiThreadRead.cpp +++ b/examples/osgunittests/MultiThreadRead.cpp @@ -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 "<block(); } -#if VERBOSE +#if VERBOSE std::cout<<"Starting "< node = osgDB::readNodeFile(filename); -#if VERBOSE +#if VERBOSE if (node.valid()) std::cout<<".. OK"<block(); } -#if VERBOSE +#if VERBOSE std::cout<<"Completed"< 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"<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."<addCommandLineOption("matrix","Display qualified tests."); arguments.getApplicationUsage()->addCommandLineOption("performance","Display qualified tests."); arguments.getApplicationUsage()->addCommandLineOption("read-threads ","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 ******"<accept( printer ); + osgUtx::TestGraph::instance().root()->accept( printer ); std::cout< -// 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(); } diff --git a/examples/osgviewerMFC/MFC_OSG.cpp b/examples/osgviewerMFC/MFC_OSG.cpp index 7c37af710..6baf62d2a 100644 --- a/examples/osgviewerMFC/MFC_OSG.cpp +++ b/examples/osgviewerMFC/MFC_OSG.cpp @@ -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() diff --git a/include/osg/OperationThread b/include/osg/OperationThread index c9c84cbbf..7e3ec9643 100644 --- a/include/osg/OperationThread +++ b/include/osg/OperationThread @@ -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 _parent; - bool _done; + OpenThreads::Atomic _done; OpenThreads::Mutex _threadMutex; osg::ref_ptr _operationQueue; diff --git a/src/OpenThreads/pthreads/PThread.cpp b/src/OpenThreads/pthreads/PThread.cpp index c72864c52..f01bc1675 100644 --- a/src/OpenThreads/pthreads/PThread.cpp +++ b/src/OpenThreads/pthreads/PThread.cpp @@ -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; diff --git a/src/OpenThreads/qt/QtThread.cpp b/src/OpenThreads/qt/QtThread.cpp index 0b9367b15..bcd1daad8 100644 --- a/src/OpenThreads/qt/QtThread.cpp +++ b/src/OpenThreads/qt/QtThread.cpp @@ -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(pd); } @@ -82,6 +82,8 @@ Thread::~Thread() { std::cout<<"Error: Thread "<< this <<" still running in destructor"<(QThread::currentThread()); return (pd ? pd->getMasterThread() : 0); } @@ -151,10 +153,10 @@ int Thread::start() { QtThreadPrivateData* pd = static_cast(_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(_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(_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(_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(_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) diff --git a/src/OpenThreads/sproc/SprocThread.c++ b/src/OpenThreads/sproc/SprocThread.c++ index f6a9faaf1..3a61bbc83 100644 --- a/src/OpenThreads/sproc/SprocThread.c++ +++ b/src/OpenThreads/sproc/SprocThread.c++ @@ -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); } diff --git a/src/OpenThreads/win32/Win32Thread.cpp b/src/OpenThreads/win32/Win32Thread.cpp index fbeb7d749..05ba0703d 100644 --- a/src/OpenThreads/win32/Win32Thread.cpp +++ b/src/OpenThreads/win32/Win32Thread.cpp @@ -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(data); - + Win32ThreadPrivateData *pd = static_cast(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 "<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(pd->stackSize),ThreadPrivateActions::StartThread,static_cast(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); } diff --git a/src/osg/OperationThread.cpp b/src/osg/OperationThread.cpp index 25a84aabc..556c8346c 100644 --- a/src/osg/OperationThread.cpp +++ b/src/osg/OperationThread.cpp @@ -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 "< 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 "<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"<time(); double timeBeforeIdle = 0.1; @@ -115,7 +116,7 @@ class LibVncImage : public osgWidget::VncImage //OSG_NOTICE<<"New: Should still be active"<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(); }