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

📄 thread.cpp

📁 很牛的GUI源码wxWidgets-2.8.0.zip 可在多种平台下运行.
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/////////////////////////////////////////////////////////////////////////////// Name:        src/mac/classic/thread.cpp// Purpose:     wxThread Implementation// Author:      Original from Wolfram Gloger/Guilhem Lavaux/Vadim Zeitlin// Modified by: Stefan Csomor// Created:     04/22/98// RCS-ID:      $Id: thread.cpp,v 1.6 2006/08/31 19:30:49 ABX Exp $// Copyright:   (c) Wolfram Gloger (1996, 1997); Guilhem Lavaux (1998),//                  Vadim Zeitlin (1999) , Stefan Csomor (2000)// Licence:     wxWindows licence/////////////////////////////////////////////////////////////////////////////// ----------------------------------------------------------------------------// headers// ----------------------------------------------------------------------------// For compilers that support precompilation, includes "wx.h".#include "wx/wxprec.h"#if defined(__BORLANDC__)    #pragma hdrstop#endif#ifndef WX_PRECOMP    #include "wx/wx.h"    #include "wx/module.h"#endif#if wxUSE_THREADS#include "wx/thread.h"#ifdef __WXMAC__#include <Threads.h>#include "wx/mac/uma.h"#include "wx/mac/macnotfy.h"#include <Timer.h>#endif#define INFINITE 0xFFFFFFFF// ----------------------------------------------------------------------------// constants// ----------------------------------------------------------------------------// the possible states of the thread ("=>" shows all possible transitions from// this state)enum wxThreadState{    STATE_NEW,          // didn't start execution yet (=> RUNNING)    STATE_RUNNING,      // thread is running (=> PAUSED, CANCELED)    STATE_PAUSED,       // thread is temporarily suspended (=> RUNNING)    STATE_CANCELED,     // thread should terminate a.s.a.p. (=> EXITED)    STATE_EXITED        // thread is terminating};// ----------------------------------------------------------------------------// this module globals// ----------------------------------------------------------------------------static ThreadID gs_idMainThread = kNoThreadID ;static bool gs_waitingForThread = false ;size_t g_numberOfThreads = 0;// ============================================================================// MacOS implementation of thread classes// ============================================================================class wxMacStCritical{public :    wxMacStCritical()    {        if ( UMASystemIsInitialized() )        {            OSErr err = ThreadBeginCritical() ;            wxASSERT( err == noErr ) ;        }    }    ~wxMacStCritical()    {        if ( UMASystemIsInitialized() )        {            OSErr err = ThreadEndCritical() ;            wxASSERT( err == noErr ) ;    }    }};// ----------------------------------------------------------------------------// wxMutex implementation// ----------------------------------------------------------------------------class wxMutexInternal{public:    wxMutexInternal(wxMutexType WXUNUSED(mutexType))    {        m_owner = kNoThreadID ;        m_locked = 0;    }    ~wxMutexInternal()    {        if ( m_locked > 0 )        {            wxLogDebug(_T("Warning: freeing a locked mutex (%ld locks)."), m_locked);        }    }    bool IsOk() const { return true; }    wxMutexError Lock() ;    wxMutexError TryLock() ;    wxMutexError Unlock();public:    ThreadID m_owner ;    wxArrayLong m_waiters ;    long m_locked ;};wxMutexError wxMutexInternal::Lock(){    wxMacStCritical critical ;    if ( UMASystemIsInitialized() )    {        OSErr err ;        ThreadID current = kNoThreadID;        err = ::MacGetCurrentThread(&current);        // if we are not the owner, add this thread to the list of waiting threads, stop this thread        // and invoke the scheduler to continue executing the owner's thread        while ( m_owner != kNoThreadID && m_owner != current)        {            m_waiters.Add(current);            err = ::SetThreadStateEndCritical(kCurrentThreadID, kStoppedThreadState, m_owner);            err = ::ThreadBeginCritical();            wxASSERT( err == noErr ) ;        }        m_owner = current;    }    m_locked++;    return wxMUTEX_NO_ERROR;}wxMutexError wxMutexInternal::TryLock(){    wxMacStCritical critical ;    if ( UMASystemIsInitialized() )    {        ThreadID current = kNoThreadID;        ::MacGetCurrentThread(&current);        // if we are not the owner, give an error back        if ( m_owner != kNoThreadID && m_owner != current )            return wxMUTEX_BUSY;        m_owner = current;    }    m_locked++;   return wxMUTEX_NO_ERROR;}wxMutexError wxMutexInternal::Unlock(){    if ( UMASystemIsInitialized() )    {        OSErr err;        err = ::ThreadBeginCritical();        wxASSERT( err == noErr ) ;        if (m_locked > 0)            m_locked--;        // this mutex is not owned by anybody anmore        m_owner = kNoThreadID;        // now pass on to the first waiting thread        ThreadID firstWaiting = kNoThreadID;        bool found = false;        while (!m_waiters.IsEmpty() && !found)        {            firstWaiting = m_waiters[0];            err = ::SetThreadState(firstWaiting, kReadyThreadState, kNoThreadID);            // in case this was not successful (dead thread), we just loop on and reset the id            found = (err != threadNotFoundErr);            if ( !found )                firstWaiting = kNoThreadID ;            m_waiters.RemoveAt(0) ;        }        // now we have a valid firstWaiting thread, which has been scheduled to run next, just end the        // critical section and invoke the scheduler        err = ::SetThreadStateEndCritical(kCurrentThreadID, kReadyThreadState, firstWaiting);    }    else    {        if (m_locked > 0)            m_locked--;    }    return wxMUTEX_NO_ERROR;}// --------------------------------------------------------------------------// wxSemaphore// --------------------------------------------------------------------------// TODO not yet implementedclass wxSemaphoreInternal{public:    wxSemaphoreInternal(int initialcount, int maxcount);    ~wxSemaphoreInternal();    bool IsOk() const { return true ; }    wxSemaError Wait() { return WaitTimeout(INFINITE); }    wxSemaError TryWait() { return WaitTimeout(0); }    wxSemaError WaitTimeout(unsigned long milliseconds);    wxSemaError Post();private:};wxSemaphoreInternal::wxSemaphoreInternal(int initialcount, int maxcount){    if ( maxcount == 0 )    {        // make it practically infinite        maxcount = INT_MAX;    }}wxSemaphoreInternal::~wxSemaphoreInternal(){}wxSemaError wxSemaphoreInternal::WaitTimeout(unsigned long milliseconds){    return wxSEMA_MISC_ERROR;}wxSemaError wxSemaphoreInternal::Post(){    return wxSEMA_MISC_ERROR;}// ----------------------------------------------------------------------------// wxCondition implementation// ----------------------------------------------------------------------------// TODO this is not yet completedclass wxConditionInternal{public:    wxConditionInternal(wxMutex& mutex) : m_mutex(mutex)    {        m_excessSignals = 0 ;    }    ~wxConditionInternal()    {    }    bool IsOk() const { return m_mutex.IsOk() ; }    wxCondError Wait()    {        return WaitTimeout(0xFFFFFFFF );    }    wxCondError WaitTimeout(unsigned long msectimeout)    {        wxMacStCritical critical ;        if ( m_excessSignals > 0 )        {            --m_excessSignals ;            return wxCOND_NO_ERROR ;        }        else if ( msectimeout == 0 )        {            return wxCOND_MISC_ERROR ;        }        else        {        }        /*        waiters++;        // FIXME this should be MsgWaitForMultipleObjects() as well probably        DWORD rc = ::WaitForSingleObject(event, timeout);        waiters--;        return rc != WAIT_TIMEOUT;        */        return wxCOND_NO_ERROR ;    }    wxCondError Signal()    {        wxMacStCritical critical ;        return wxCOND_NO_ERROR;    }    wxCondError Broadcast()    {        wxMacStCritical critical ;        return wxCOND_NO_ERROR;    }    wxArrayLong m_waiters ;    wxInt32     m_excessSignals ;    wxMutex&    m_mutex;};// ----------------------------------------------------------------------------// wxCriticalSection implementation// ----------------------------------------------------------------------------// it's implemented as a mutex on mac os, so it is defined in the headers// ----------------------------------------------------------------------------// wxThread implementation// ----------------------------------------------------------------------------// wxThreadInternal class// ----------------------class wxThreadInternal{public:    wxThreadInternal()    {        m_tid = kNoThreadID ;        m_state = STATE_NEW;        m_priority = WXTHREAD_DEFAULT_PRIORITY;    }    ~wxThreadInternal()    {    }    void Free()    {    }    // create a new (suspended) thread (for the given thread object)    bool Create(wxThread *thread, unsigned int stackSize);    // suspend/resume/terminate    bool Suspend();    bool Resume();    void Cancel() { m_state = STATE_CANCELED; }    // thread state    void SetState(wxThreadState state) { m_state = state; }    wxThreadState GetState() const { return m_state; }    // thread priority    void SetPriority(unsigned int priority);    unsigned int GetPriority() const { return m_priority; }    void SetResult( void *res ) { m_result = res ; }    void *GetResult() { return m_result ; }    // thread handle and id    ThreadID  GetId() const { return m_tid; }    // thread function    static pascal void*    MacThreadStart(wxThread* arg);private:    wxThreadState           m_state;      // state, see wxThreadState enum    unsigned int            m_priority;   // thread priority in "wx" units    ThreadID                m_tid;        // thread id    void*                   m_result;    static ThreadEntryUPP   s_threadEntry ;};static wxArrayPtrVoid s_threads ;ThreadEntryUPP wxThreadInternal::s_threadEntry = NULL ;pascal void* wxThreadInternal::MacThreadStart(wxThread *thread){    // first of all, check whether we hadn't been cancelled already    if ( thread->m_internal->GetState() == STATE_EXITED )    {        return (void*)-1;    }    void* rc = thread->Entry();    // enter m_critsect before changing the thread state    thread->m_critsect.Enter();    bool wasCancelled = thread->m_internal->GetState() == STATE_CANCELED;    thread->m_internal->SetState(STATE_EXITED);    thread->m_critsect.Leave();    thread->OnExit();    // if the thread was cancelled (from Delete()), then it the handle is still    // needed there    if ( thread->IsDetached() && !wasCancelled )    {        // auto delete        delete thread;    }    //else: the joinable threads handle will be closed when Wait() is done    return rc;}void wxThreadInternal::SetPriority(unsigned int priority){    // Priorities don't exist on Mac}bool wxThreadInternal::Create(wxThread *thread, unsigned int stackSize){    if ( s_threadEntry == NULL )    {        s_threadEntry = NewThreadEntryUPP( (ThreadEntryProcPtr) MacThreadStart ) ;    }    OSErr err = NewThread( kCooperativeThread,                           s_threadEntry,                           (void*) thread,                           stackSize,                           kNewSuspend,                           &m_result,                           &m_tid );    if ( err != noErr )    {        wxLogSysError(_("Can't create thread"));        return false;    }    if ( m_priority != WXTHREAD_DEFAULT_PRIORITY )    {        SetPriority(m_priority);    }    m_state = STATE_NEW;    return true;}bool wxThreadInternal::Suspend(){    OSErr err ;    err = ::ThreadBeginCritical();    wxASSERT( err == noErr ) ;    if ( m_state != STATE_RUNNING )    {        err = ::ThreadEndCritical() ;        wxASSERT( err == noErr ) ;        wxLogSysError(_("Can not suspend thread %x"), m_tid);        return false;    }    m_state = STATE_PAUSED;    err = ::SetThreadStateEndCritical(m_tid, kStoppedThreadState, kNoThreadID);

⌨️ 快捷键说明

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