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

📄 thread.h

📁 浙江大学的悟空嵌入式系统模拟器
💻 H
📖 第 1 页 / 共 2 页
字号:
/////////////////////////////////////////////////////////////////////////////
// Name:        wx/thread.h
// Purpose:     Thread API
// Author:      Guilhem Lavaux
// Modified by: Vadim Zeitlin (modifications partly inspired by omnithreads
//              package from Olivetti & Oracle Research Laboratory)
// Created:     04/13/98
// RCS-ID:      $Id: thread.h,v 1.1 2005/03/16 06:49:28 kehc Exp $
// Copyright:   (c) Guilhem Lavaux
// Licence:     wxWindows licence
/////////////////////////////////////////////////////////////////////////////

#ifndef _WX_THREAD_H_
#define _WX_THREAD_H_

// ----------------------------------------------------------------------------
// headers
// ----------------------------------------------------------------------------

// get the value of wxUSE_THREADS configuration flag
#include "wx/defs.h"

#if wxUSE_THREADS

// only for wxUSE_THREADS - otherwise we'd get undefined symbols
#if defined(__GNUG__) && !defined(__APPLE__)
    #pragma interface "thread.h"
#endif

// Windows headers define it
#ifdef Yield
    #undef Yield
#endif

#include "wx/module.h"

// ----------------------------------------------------------------------------
// constants
// ----------------------------------------------------------------------------

enum wxMutexError
{
    wxMUTEX_NO_ERROR = 0,   // operation completed successfully
    wxMUTEX_INVALID,        // mutex hasn't been initialized
    wxMUTEX_DEAD_LOCK,      // mutex is already locked by the calling thread
    wxMUTEX_BUSY,           // mutex is already locked by another thread
    wxMUTEX_UNLOCKED,       // attempt to unlock a mutex which is not locked
    wxMUTEX_MISC_ERROR      // any other error
};

enum wxCondError
{
    wxCOND_NO_ERROR = 0,
    wxCOND_INVALID,
    wxCOND_TIMEOUT,         // WaitTimeout() has timed out
    wxCOND_MISC_ERROR
};

enum wxSemaError
{
    wxSEMA_NO_ERROR = 0,
    wxSEMA_INVALID,         // semaphore hasn't been initialized successfully
    wxSEMA_BUSY,            // returned by TryWait() if Wait() would block
    wxSEMA_TIMEOUT,         // returned by WaitTimeout()
    wxSEMA_OVERFLOW,        // Post() would increase counter past the max
    wxSEMA_MISC_ERROR
};

enum wxThreadError
{
    wxTHREAD_NO_ERROR = 0,      // No error
    wxTHREAD_NO_RESOURCE,       // No resource left to create a new thread
    wxTHREAD_RUNNING,           // The thread is already running
    wxTHREAD_NOT_RUNNING,       // The thread isn't running
    wxTHREAD_KILLED,            // Thread we waited for had to be killed
    wxTHREAD_MISC_ERROR         // Some other error
};

enum wxThreadKind
{
    wxTHREAD_DETACHED,
    wxTHREAD_JOINABLE
};

// defines the interval of priority
enum
{
    WXTHREAD_MIN_PRIORITY      = 0u,
    WXTHREAD_DEFAULT_PRIORITY  = 50u,
    WXTHREAD_MAX_PRIORITY      = 100u
};

// There are 2 types of mutexes: normal mutexes and recursive ones. The attempt
// to lock a normal mutex by a thread which already owns it results in
// undefined behaviour (it always works under Windows, it will almost always
// result in a deadlock under Unix). Locking a recursive mutex in such
// situation always succeeds and it must be unlocked as many times as it has
// been locked.
//
// However recursive mutexes have several important drawbacks: first, in the
// POSIX implementation, they're less efficient. Second, and more importantly,
// they CAN NOT BE USED WITH CONDITION VARIABLES under Unix! Using them with
// wxCondition will work under Windows and some Unices (notably Linux) but will
// deadlock under other Unix versions (e.g. Solaris). As it might be difficult
// to ensure that a recursive mutex is not used with wxCondition, it is a good
// idea to avoid using recursive mutexes at all. Also, the last problem with
// them is that some (older) Unix versions don't support this at all -- which
// results in a configure warning when building and a deadlock when using them.
enum wxMutexType
{
    // normal mutex: try to always use this one
    wxMUTEX_DEFAULT,

    // recursive mutex: don't use these ones with wxCondition
    wxMUTEX_RECURSIVE
};

// forward declarations
class WXDLLEXPORT wxConditionInternal;
class WXDLLEXPORT wxMutexInternal;
class WXDLLEXPORT wxSemaphoreInternal;
class WXDLLEXPORT wxThreadInternal;

// ----------------------------------------------------------------------------
// A mutex object is a synchronization object whose state is set to signaled
// when it is not owned by any thread, and nonsignaled when it is owned. Its
// name comes from its usefulness in coordinating mutually-exclusive access to
// a shared resource. Only one thread at a time can own a mutex object.
// ----------------------------------------------------------------------------

// you should consider wxMutexLocker whenever possible instead of directly
// working with wxMutex class - it is safer
class WXDLLEXPORT wxMutex
{
public:
    // constructor & destructor
    // ------------------------

    // create either default (always safe) or recursive mutex
    wxMutex(wxMutexType mutexType = wxMUTEX_DEFAULT);

    // destroys the mutex kernel object
    ~wxMutex();

    // test if the mutex has been created successfully
    bool IsOk() const;

    // mutex operations
    // ----------------

    // Lock the mutex, blocking on it until it is unlocked by the other thread.
    // The result of locking a mutex already locked by the current thread
    // depend on the mutex type.
    //
    // The caller must call Unlock() later if Lock() returned wxMUTEX_NO_ERROR.
    wxMutexError Lock();

    // Try to lock the mutex: if it is currently locked, return immediately
    // with an error. Otherwise the caller must call Unlock().
    wxMutexError TryLock();

    // Unlock the mutex. It is an error to unlock an already unlocked mutex
    wxMutexError Unlock();

protected:
    wxMutexInternal *m_internal;

    friend class wxConditionInternal;

    DECLARE_NO_COPY_CLASS(wxMutex)
};

// a helper class which locks the mutex in the ctor and unlocks it in the dtor:
// this ensures that mutex is always unlocked, even if the function returns or
// throws an exception before it reaches the end
class WXDLLEXPORT wxMutexLocker
{
public:
    // lock the mutex in the ctor
    wxMutexLocker(wxMutex& mutex)
        : m_isOk(FALSE), m_mutex(mutex)
        { m_isOk = ( m_mutex.Lock() == wxMUTEX_NO_ERROR ); }

    // returns TRUE if mutex was successfully locked in ctor
    bool IsOk() const
        { return m_isOk; }

    // unlock the mutex in dtor
    ~wxMutexLocker()
        { if ( IsOk() ) m_mutex.Unlock(); }

private:
    // no assignment operator nor copy ctor
    wxMutexLocker(const wxMutexLocker&);
    wxMutexLocker& operator=(const wxMutexLocker&);

    bool     m_isOk;
    wxMutex& m_mutex;
};

// ----------------------------------------------------------------------------
// Critical section: this is the same as mutex but is only visible to the
// threads of the same process. For the platforms which don't have native
// support for critical sections, they're implemented entirely in terms of
// mutexes.
//
// NB: wxCriticalSection object does not allocate any memory in its ctor
//     which makes it possible to have static globals of this class
// ----------------------------------------------------------------------------

// in order to avoid any overhead under platforms where critical sections are
// just mutexes make all wxCriticalSection class functions inline
#if !defined(__WXMSW__)
    #define wxCRITSECT_IS_MUTEX 1

    #define wxCRITSECT_INLINE inline
#else // MSW
    #define wxCRITSECT_IS_MUTEX 0

    #define wxCRITSECT_INLINE
#endif // MSW/!MSW

// you should consider wxCriticalSectionLocker whenever possible instead of
// directly working with wxCriticalSection class - it is safer
class WXDLLEXPORT wxCriticalSection
{
public:
    // ctor & dtor
    wxCRITSECT_INLINE wxCriticalSection();
    wxCRITSECT_INLINE ~wxCriticalSection();

    // enter the section (the same as locking a mutex)
    wxCRITSECT_INLINE void Enter();

    // leave the critical section (same as unlocking a mutex)
    wxCRITSECT_INLINE void Leave();

private:
#if wxCRITSECT_IS_MUTEX
    wxMutex m_mutex;
#elif defined(__WXMSW__)
    // we can't allocate any memory in the ctor, so use placement new -
    // unfortunately, we have to hardcode the sizeof() here because we can't
    // include windows.h from this public header and we also have to use the
    // union to force the correct (i.e. maximal) alignment
    //
    // if CRITICAL_SECTION size changes in Windows, you'll get an assert from
    // thread.cpp and will need to increase the buffer size
    //
    // finally, we need this typedef instead of declaring m_buffer directly
    // because otherwise the assert mentioned above wouldn't compile with some
    // compilers (notably CodeWarrior 8)
    typedef char wxCritSectBuffer[24];
    union
    {
        unsigned long m_dummy1;
        void *m_dummy2;

        wxCritSectBuffer m_buffer;
    };
#endif // Unix&OS2/Win32

    DECLARE_NO_COPY_CLASS(wxCriticalSection)
};

#if wxCRITSECT_IS_MUTEX
    // implement wxCriticalSection using mutexes
    inline wxCriticalSection::wxCriticalSection() { }
    inline wxCriticalSection::~wxCriticalSection() { }

    inline void wxCriticalSection::Enter() { (void)m_mutex.Lock(); }
    inline void wxCriticalSection::Leave() { (void)m_mutex.Unlock(); }
#endif // wxCRITSECT_IS_MUTEX

#undef wxCRITSECT_INLINE
#undef wxCRITSECT_IS_MUTEX

// wxCriticalSectionLocker is the same to critical sections as wxMutexLocker is
// to th mutexes
class WXDLLEXPORT wxCriticalSectionLocker
{
public:
    wxCriticalSectionLocker(wxCriticalSection& cs)
        : m_critsect(cs)
    {
        m_critsect.Enter();
    }

    ~wxCriticalSectionLocker()
    {
        m_critsect.Leave();
    }

private:
    wxCriticalSection& m_critsect;

    DECLARE_NO_COPY_CLASS(wxCriticalSectionLocker)
};

// ----------------------------------------------------------------------------
// wxCondition models a POSIX condition variable which allows one (or more)
// thread(s) to wait until some condition is fulfilled
// ----------------------------------------------------------------------------

class WXDLLEXPORT wxCondition
{
public:
    // Each wxCondition object is associated with a (single) wxMutex object.
    // The mutex object MUST be locked before calling Wait()
    wxCondition(wxMutex& mutex);

    // dtor is not virtual, don't use this class polymorphically
    ~wxCondition();

    // return TRUE if the condition has been created successfully
    bool IsOk() const;

    // NB: the associated mutex MUST be locked beforehand by the calling thread
    // 
    // it atomically releases the lock on the associated mutex
    // and starts waiting to be woken up by a Signal()/Broadcast()
    // once its signaled, then it will wait until it can reacquire
    // the lock on the associated mutex object, before returning.
    wxCondError Wait();

    // exactly as Wait() except that it may also return if the specified
    // timeout ellapses even if the condition hasn't been signalled: in this
    // case, the return value is FALSE, otherwise (i.e. in case of a normal
    // return) it is TRUE
    // 
    // the timeeout parameter specifies a interval that needs to be waited in
    // milliseconds
    wxCondError WaitTimeout(unsigned long milliseconds);

    // NB: the associated mutex may or may not be locked by the calling thread
    //

⌨️ 快捷键说明

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