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

📄 thread.cpp

📁 Wxpython Implemented on Windows CE, Source code
💻 CPP
📖 第 1 页 / 共 2 页
字号:

    return TRUE;
}

bool wxThreadInternal::Resume()
{
    ThreadID current ;
    OSErr err ;
    err = MacGetCurrentThread( &current ) ;

    wxASSERT( err == noErr ) ;
    wxASSERT( current != m_tid ) ;

    err = ::ThreadBeginCritical();
    wxASSERT( err == noErr ) ;

    if ( m_state != STATE_PAUSED && m_state != STATE_NEW )
    {
        err = ::ThreadEndCritical() ;
        wxASSERT( err == noErr ) ;
        wxLogSysError(_("Can not resume thread %x"), m_tid);
        return FALSE;

    }
    err = ::SetThreadStateEndCritical(m_tid, kReadyThreadState, kNoThreadID);

    m_state = STATE_RUNNING;
    err = ::ThreadEndCritical() ;
    wxASSERT( err == noErr ) ;
    ::YieldToAnyThread() ;
    return TRUE;
}

// static functions
// ----------------
wxThread *wxThread::This()
{
    wxMacStCritical critical ;

    ThreadID current ;
    OSErr err ;

    err = MacGetCurrentThread( &current ) ;

    for ( size_t i = 0 ; i < s_threads.Count() ; ++i )
    {
        if ( ( (wxThread*) s_threads[i] )->GetId() == current )
            return (wxThread*) s_threads[i] ;
    }

    wxLogSysError(_("Couldn't get the current thread pointer"));
    return NULL;
}

bool wxThread::IsMain()
{
    ThreadID current ;
    OSErr err ;

    err = MacGetCurrentThread( &current ) ;
    return current == gs_idMainThread;
}

#ifdef Yield
#undef Yield
#endif

void wxThread::Yield()
{
    ::YieldToAnyThread() ;
}

void wxThread::Sleep(unsigned long milliseconds)
{
    UnsignedWide start, now;

    Microseconds(&start);

    double mssleep = milliseconds * 1000 ;
    double msstart, msnow ;
    msstart = (start.hi * 4294967296.0 + start.lo) ;
    
    do
    {
        YieldToAnyThread();
        Microseconds(&now);
        msnow = (now.hi * 4294967296.0 + now.lo) ;
    } while( msnow - msstart < mssleep );
}

int wxThread::GetCPUCount()
{
    // we will use whatever MP API will be used for the new MP Macs
    return 1;
}

unsigned long wxThread::GetCurrentId()
{
    ThreadID current ;
    MacGetCurrentThread( &current ) ;
    return (unsigned long)current;
}

bool wxThread::SetConcurrency(size_t level)
{
    wxASSERT_MSG( IsMain(), _T("should only be called from the main thread") );

    // ok only for the default one
    if ( level == 0 )
        return 0;

    // how many CPUs have we got?
    if ( GetCPUCount() == 1 )
    {
        // don't bother with all this complicated stuff - on a single
        // processor system it doesn't make much sense anyhow
        return level == 1;
    }

    return TRUE ;
}

// ctor and dtor
// -------------

wxThread::wxThread(wxThreadKind kind)
{
    g_numberOfThreads++;
    m_internal = new wxThreadInternal();

    m_isDetached = kind == wxTHREAD_DETACHED;
    s_threads.Add( (void*) this ) ;
}

wxThread::~wxThread()
{
    if (g_numberOfThreads>0)
    {
        g_numberOfThreads--;
    }
#ifdef __WXDEBUG__
    else
    {
        wxFAIL_MSG(wxT("More threads deleted than created."));
    }
#endif

    s_threads.Remove( (void*) this ) ;
    if (m_internal != NULL) {
        delete m_internal;
        m_internal = NULL;
    }
}

// create/start thread
// -------------------

wxThreadError wxThread::Create(unsigned int stackSize)
{
    wxCriticalSectionLocker lock(m_critsect);

    if ( !m_internal->Create(this, stackSize) )
        return wxTHREAD_NO_RESOURCE;

    return wxTHREAD_NO_ERROR;
}

wxThreadError wxThread::Run()
{
    wxCriticalSectionLocker lock(m_critsect);

    if ( m_internal->GetState() != STATE_NEW )
    {
        // actually, it may be almost any state at all, not only STATE_RUNNING
        return wxTHREAD_RUNNING;
    }

    // the thread has just been created and is still suspended - let it run
    return Resume();
}

// suspend/resume thread
// ---------------------

wxThreadError wxThread::Pause()
{
    wxCriticalSectionLocker lock(m_critsect);

    return m_internal->Suspend() ? wxTHREAD_NO_ERROR : wxTHREAD_MISC_ERROR;
}

wxThreadError wxThread::Resume()
{
    wxCriticalSectionLocker lock(m_critsect);

    return m_internal->Resume() ? wxTHREAD_NO_ERROR : wxTHREAD_MISC_ERROR;
}

// stopping thread
// ---------------

wxThread::ExitCode wxThread::Wait()
{
    // although under MacOS we can wait for any thread, it's an error to
    // wait for a detached one in wxWin API
    wxCHECK_MSG( !IsDetached(), (ExitCode)-1,
                 _T("can't wait for detached thread") );

    ExitCode rc = (ExitCode)-1;

    (void)Delete(&rc);

    m_internal->Free();

    return rc;
}

wxThreadError wxThread::Delete(ExitCode *pRc)
{
    ExitCode rc = 0;

    // Delete() is always safe to call, so consider all possible states

    // has the thread started to run?
    bool shouldResume = FALSE;

    {
        wxCriticalSectionLocker lock(m_critsect);

        if ( m_internal->GetState() == STATE_NEW )
        {
            // WinThreadStart() will see it and terminate immediately
            m_internal->SetState(STATE_EXITED);

            shouldResume = TRUE;
        }
    }

    // is the thread paused?
    if ( shouldResume || IsPaused() )
        Resume();

    // does is still run?
    if ( IsRunning() )
    {
        if ( IsMain() )
        {
            // set flag for wxIsWaitingForThread()
            gs_waitingForThread = TRUE;

#if wxUSE_GUI
            wxBeginBusyCursor();
#endif // wxUSE_GUI
        }

        // ask the thread to terminate
        {
            wxCriticalSectionLocker lock(m_critsect);

            m_internal->Cancel();
        }

#if wxUSE_GUI
        // simply wait for the thread to terminate
        while( TestDestroy() )
        {
            ::YieldToAnyThread() ;
        }
#else // !wxUSE_GUI
        // simply wait for the thread to terminate
        while( TestDestroy() )
        {
            ::YieldToAnyThread() ;
        }
#endif // wxUSE_GUI/!wxUSE_GUI

        if ( IsMain() )
        {
            gs_waitingForThread = FALSE;

#if wxUSE_GUI
            wxEndBusyCursor();
#endif // wxUSE_GUI
        }
    }

    if ( IsDetached() )
    {
        // if the thread exits normally, this is done in WinThreadStart, but in
        // this case it would have been too early because
        // MsgWaitForMultipleObject() would fail if the therad handle was
        // closed while we were waiting on it, so we must do it here
        delete this;
    }

    if ( pRc )
        *pRc = rc;

    return rc == (ExitCode)-1 ? wxTHREAD_MISC_ERROR : wxTHREAD_NO_ERROR;
}

wxThreadError wxThread::Kill()
{
    if ( !IsRunning() )
        return wxTHREAD_NOT_RUNNING;

//    if ( !::TerminateThread(m_internal->GetHandle(), (DWORD)-1) )
    {
        wxLogSysError(_("Couldn't terminate thread"));

        return wxTHREAD_MISC_ERROR;
    }

    m_internal->Free();

    if ( IsDetached() )
    {
        delete this;
    }

    return wxTHREAD_NO_ERROR;
}

void wxThread::Exit(ExitCode status)
{
    m_internal->Free();

    if ( IsDetached() )
    {
        delete this;
    }

    m_internal->SetResult( status ) ;

/*
#if defined(__VISUALC__) || (defined(__BORLANDC__) && (__BORLANDC__ >= 0x500))
    _endthreadex((unsigned)status);
#else // !VC++
    ::ExitThread((DWORD)status);
#endif // VC++/!VC++
*/
    wxFAIL_MSG(wxT("Couldn't return from ExitThread()!"));
}

// priority setting
// ----------------

// since all these calls are execute cooperatively we don't have to use the critical section

void wxThread::SetPriority(unsigned int prio)
{
    m_internal->SetPriority(prio);
}

unsigned int wxThread::GetPriority() const
{
    return m_internal->GetPriority();
}

unsigned long wxThread::GetId() const
{
    return (unsigned long)m_internal->GetId();
}

bool wxThread::IsRunning() const
{
    return m_internal->GetState() == STATE_RUNNING;
}

bool wxThread::IsAlive() const
{
    return (m_internal->GetState() == STATE_RUNNING) ||
           (m_internal->GetState() == STATE_PAUSED);
}

bool wxThread::IsPaused() const
{
    return m_internal->GetState() == STATE_PAUSED;
}

bool wxThread::TestDestroy()
{
    return m_internal->GetState() == STATE_CANCELED;
}

// ----------------------------------------------------------------------------
// Automatic initialization for thread module
// ----------------------------------------------------------------------------

class wxThreadModule : public wxModule
{
public:
    virtual bool OnInit();
    virtual void OnExit();

private:
    DECLARE_DYNAMIC_CLASS(wxThreadModule)
};

IMPLEMENT_DYNAMIC_CLASS(wxThreadModule, wxModule)

bool wxThreadModule::OnInit()
{
    long response;
    bool hasThreadManager ;
    hasThreadManager = Gestalt( gestaltThreadMgrAttr, &response) == noErr && response & 1;
#if !TARGET_CARBON
#if GENERATINGCFM
    // verify presence of shared library
    hasThreadManager = hasThreadManager && ((Ptr)NewThread != (Ptr)kUnresolvedCFragSymbolAddress);
#endif
#endif
    if ( !hasThreadManager )
    {
        wxLogSysError( wxT("Thread Support is not available on this System") );
        return FALSE ;
    }

    // no error return for GetCurrentThreadId()
    MacGetCurrentThread( &gs_idMainThread ) ;

    return TRUE;
}

void wxThreadModule::OnExit()
{
}

// ----------------------------------------------------------------------------
// under MacOS we don't have currently preemptive threads, so any thread may access
// the GUI at any time
// ----------------------------------------------------------------------------

void WXDLLEXPORT wxMutexGuiEnter()
{
}

void WXDLLEXPORT wxMutexGuiLeave()
{
}

void WXDLLEXPORT wxMutexGuiLeaveOrEnter()
{
}

bool WXDLLEXPORT wxGuiOwnedByMainThread()
{
    return false ;
}

// wake up the main thread
void WXDLLEXPORT wxWakeUpMainThread()
{
    wxMacWakeUp() ;
}

bool WXDLLEXPORT wxIsWaitingForThread()
{
    return false ;
}

#include "wx/thrimpl.cpp"

#endif // wxUSE_THREADS

⌨️ 快捷键说明

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