⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 win32thread.cpp

📁 最新osg包
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/* -*-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  * (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  * OpenSceneGraph Public License for more details.*///// Win32Thread.c++// ~~~~~~~~~~~#include <memory>#include <string>#include <iostream>#include <process.h>#include <stdlib.h>#if defined(_MSC_VER) && (_MSC_VER < 1300)#ifdef __SGI_STLusing std::size_t;#endif#elseusing std::size_t;#endif#if defined(_MSC_VER)    #pragma warning( disable : 4996 )#endif#include "Win32ThreadPrivateData.h"struct Win32ThreadCanceled{};using namespace OpenThreads;DWORD OpenThreads::cooperativeWait(HANDLE waitHandle, unsigned long timeout){    Thread* current = Thread::CurrentThread();    DWORD dwResult ;    if(current)    {        HANDLE cancelHandle = static_cast<Win32ThreadPrivateData*>(current->getImplementation())->cancelEvent.get();        HANDLE handleSet[2] = {waitHandle, cancelHandle};        dwResult = WaitForMultipleObjects(2,handleSet,FALSE,timeout);        if(dwResult == WAIT_OBJECT_0 + 1 ) throw Win32ThreadCanceled();    }    else    {        dwResult = WaitForSingleObject(waitHandle,timeout);    }    return dwResult;}Win32ThreadPrivateData::TlsHolder Win32ThreadPrivateData::TLS;Win32ThreadPrivateData::~Win32ThreadPrivateData(){}const std::string OPENTHREAD_VERSION_STRING = "OpenThread v1.2preAlpha, WindowThreads (Public Implementation)";//-----------------------------------------------------------------------------// Initialize thread master priority level//Thread::ThreadPriority Thread::s_masterThreadPriority =  Thread::THREAD_PRIORITY_DEFAULT;bool Thread::s_isInitialized = false;//-----------------------------------------------------------------------------// Class to support some static methods necessary for pthread's to work// correctly.//namespace OpenThreads {    class ThreadPrivateActions {        //-------------------------------------------------------------------------        // We're friendly to Thread, so it can issue the methods.        //        friend class Thread;    private:        //-------------------------------------------------------------------------        // Win32Threads standard start routine.        //        static unsigned int __stdcall StartThread(void *data) {            Thread *thread = static_cast<Thread *>(data);                    Win32ThreadPrivateData *pd =                static_cast<Win32ThreadPrivateData *>(thread->_prvData);            if (thread->_prvData==0) return 0;            TlsSetValue(Win32ThreadPrivateData::TLS.ID ,data);            //---------------------------------------------------------------------            // Set the proper scheduling priorities            //            SetThreadSchedulingParams(thread);            pd->isRunning = true;                        // release the thread that created this thread.            pd->threadStartedBlock.release();            try{                thread->run();            }            catch(Win32ThreadCanceled&)            {                // thread is canceled do cleanup                try {                    thread->cancelCleanup();                } catch(...) { }            }            catch(...)            {                // abnormal termination but must be caught in win32 anyway            }            pd->isRunning = false;            return 0;        };        //-------------------------------------------------------------------------        // Print information related to thread schduling parameters.        //        static void PrintThreadSchedulingInfo(Thread *thread) {            Win32ThreadPrivateData *pd =                static_cast<Win32ThreadPrivateData *>(thread->_prvData);            std::cout<<"Thread "<< thread <<" priority : ";            switch(thread->getSchedulePriority()) {            case Thread::THREAD_PRIORITY_MAX:                std::cout<<"MAXIMAL"<<std::endl;                break;            case Thread::THREAD_PRIORITY_HIGH:                std::cout<<"HIGH"<<std::endl;                break;            case Thread::THREAD_PRIORITY_DEFAULT:            case Thread::THREAD_PRIORITY_NOMINAL:                std::cout<<"NORMAL"<<std::endl;                break;            case Thread::THREAD_PRIORITY_LOW:                std::cout<<"LOW"<<std::endl;                break;            case Thread::THREAD_PRIORITY_MIN:                std::cout<<"MINIMAL"<<std::endl;                break;            }        }        //--------------------------------------------------------------------------        // Set thread scheduling parameters.        // Note that time-critical priority is ommited :        // 1) It's not sensible thing to do        // 2) there's no enum for that in Thread interface        // Also, on Windows, effective thread priority is :        // process priority (manipulated with Get/SetProrityClass) + thread priority (here).        //        //        static int SetThreadSchedulingParams(Thread *thread) {            Win32ThreadPrivateData *pd =                static_cast<Win32ThreadPrivateData *>(thread->_prvData);            int prio = THREAD_PRIORITY_NORMAL;            switch(thread->getSchedulePriority()) {            case Thread::THREAD_PRIORITY_MAX:                prio = THREAD_PRIORITY_HIGHEST;                break;            case Thread::THREAD_PRIORITY_HIGH:                prio = THREAD_PRIORITY_ABOVE_NORMAL;                break;            case Thread::THREAD_PRIORITY_NOMINAL:                prio = THREAD_PRIORITY_NORMAL;                break;            case Thread::THREAD_PRIORITY_LOW:                prio = THREAD_PRIORITY_BELOW_NORMAL;                break;            case Thread::THREAD_PRIORITY_MIN:                prio = THREAD_PRIORITY_IDLE;                break;            }            int status = SetThreadPriority( pd->tid.get(), prio);            if(getenv("OUTPUT_THREADLIB_SCHEDULING_INFO") != 0)                PrintThreadSchedulingInfo(thread);            return status!=0;        };    };};Thread* Thread::CurrentThread(){    return (Thread* )TlsGetValue(Win32ThreadPrivateData::TLS.ID);};//----------------------------------------------------------------------------//// Description: Set the concurrency level (no-op)//// Use static public//int Thread::SetConcurrency(int) {    return -1;};//----------------------------------------------------------------------------//// Description: Get the concurrency level//// Use static public//int Thread::GetConcurrency() {    return -1;};//----------------------------------------------------------------------------//// Description: Constructor//// Use: public.//Thread::Thread() {    // there's no need for this    //    if(!s_isInitialized) Init();    Win32ThreadPrivateData *pd = new Win32ThreadPrivateData();    pd->stackSize = 0;    pd->isRunning = false;    pd->cancelMode = 0;    pd->uniqueId = 0;    pd->threadPriority = Thread::THREAD_PRIORITY_DEFAULT;    pd->threadPolicy = Thread::THREAD_SCHEDULE_DEFAULT;    pd->detached = false;    pd->cancelEvent.set(CreateEvent(NULL,TRUE,FALSE,NULL));    _prvData = static_cast<void *>(pd);}//----------------------------------------------------------------------------//// Description: Destructor//// Use: public.//Thread::~Thread(){    Win32ThreadPrivateData *pd = static_cast<Win32ThreadPrivateData *>(_prvData);    if(pd->isRunning)    {        std::cout<<"Error: Thread "<<this<<" still running in destructor"<<std::endl;        pd->cancelMode = 0;        cancel();    }    delete pd;        _prvData = 0;}//-----------------------------------------------------------------------------//// Description: Initialize Threading//// Use: public.//void Thread::Init() {//    if(s_isInitialized) return;//        s_masterThreadPriority = Thread::THREAD_PRIORITY_DEFAULT;    s_isInitialized = true;}//-----------------------------------------------------------------------------//// Description: Get a unique identifier for this thread.//// Use: public//int Thread::getThreadId() {    Win32ThreadPrivateData *pd = static_cast<Win32ThreadPrivateData *> (_prvData);    return pd->uniqueId;}//-----------------------------------------------------------------------------//// Description: Get the thread's process id//// Use: public//size_t Thread::getProcessId() {    return (size_t) GetCurrentProcessId();}//-----------------------------------------------------------------------------//// Description: Determine if the thread is running//// Use: public//bool Thread::isRunning() {    Win32ThreadPrivateData *pd = static_cast<Win32ThreadPrivateData *> (_prvData);    return pd->isRunning;}//-----------------------------------------------------------------------------//// Description: Start the thread.//// Use: public//int Thread::start() {    Win32ThreadPrivateData *pd = static_cast<Win32ThreadPrivateData *> (_prvData);    //-------------------------------------------------------------------------    // 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     // pd->stackSizeLocked = true;    unsigned int ID;        pd->threadStartedBlock.reset();    pd->tid.set( (void*)_beginthreadex(NULL,pd->stackSize,ThreadPrivateActions::StartThread,static_cast<void *>(this),0,&ID));    pd->uniqueId = (int)ID;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -