📄 threading.h
字号:
return WaitForSingleObject( eventHandle, INFINITE ) != WAIT_FAILED;
#elif defined(GAL_PLATFORM_NIX)
return LockSemaphore( (SysSemaphoreObject&)eventHandle );
#endif
}
/// <summary>This function is used to set event to signaled state.</summary>
/// <param name="eventHandle">reference to variable that holds reference to event.</param>
/// <return>Returns <c>true</c> if the event is successfully signaled.</returns>
inline bool SignalEvent(SysEventObject& eventHandle)
{
#if defined(GAL_PLATFORM_WIN)
return SetEvent( eventHandle ) != FALSE;
#elif defined(GAL_PLATFORM_NIX)
return UnlockSemaphore( (SysSemaphoreObject&)eventHandle, 1 );
#endif
}
/// <summary><c>DEFINE_SYNC_CLASS</c> macro inserts members to class which are needed to synchronize access to an object.
/// Synchronization is don by using <c>LOCK_OBJECT</c> and <c>LOCK_THIS_OBJECT</c> macros.</summary>
#define DEFINE_SYNC_CLASS protected: mutable Threading::GaCriticalSection _synchronizator; \
public: Threading::GaCriticalSection* GACALL GetSynchronizator() const \
{ return &_synchronizator; }
/// <summary>Macro is used to acquire access to critical section protected by synchronization object
/// (<see cref="GaSectionLock" /> and <see cref="GaCriticalSection" />).</summary>
/// <param name="LOCK_NAME">synchronization object.</param>
#define LOCK(LOCK_NAME) ( LOCK_NAME ).Lock()
/// <summary>Macro is used when thread exits critical section and releases access to synchronization object
/// (<see cref="GaSectionLock" /> and <see cref="GaCriticalSection" />).</summary>
/// <param name="LOCK_NAME">synchronization object.</param>
#define UNLOCK(LOCK_NAME) ( LOCK_NAME ).Unlock()
/// <summary>Macro acquires access to an object with built-in synchronizator and prevents concurrent access.
/// It instantiate <see cref="GaSectionLock" /> object with name lock and acquire access to the object, when
/// execution leave the scope in which <c>LOCK_OBJECT</c> is specified, <see cref="GaSectionLock" /> object
/// is destroyed and access to the locked object is released. Unlocking access to the object before leaving
/// scope can be done by calling <c>UNLOCK(lock_name)</c> macro.</summary>
/// <param name="LOCK_NAME">object which is synchronized.</param>
/// <param name="OBJECT">name of <c>GaSectionLock</c> object.</param>
#define LOCK_OBJECT(LOCK_NAME, OBJECT) Threading::GaSectionLock LOCK_NAME( ( OBJECT )->GetSynchronizator(), true )
/// <summary>Macro acquires access to this and prevents concurrent access.
/// It declares and instantiates <see cref="GaSectionLock" /> object with name lock and acquire access to
/// this object, when execution leave the scope in which <c>LOCK_OBJECT</c> is specified,
/// <see cref="GaSectionLock" /> object is destroyed and access to this object is released. Unlocking
/// access to this before leaving scope can be done by calling <c>UNLOCK(lock_name)</c> macro.</summary>
/// <param name="LOCK_NAME">name of <c>GaSectionLock</c> object.</param>
#define LOCK_THIS_OBJECT(LOCK_NAME) Threading::GaSectionLock LOCK_NAME( &this->_synchronizator, true )
class GaThread;
/// <summary><c>ThreadFunctionPointer</c> is pointer to function used as thread's entry point. Entry point function must obey restriction of this type:
/// <br>1. Function must return value of <see cref="ThreadFunctionReturn" /> type.
/// <br>2. Function must use <c>GACALL</c> calling convention.
/// <br>3. Function must have two parameters.
/// <br>4. First parameter must be pointer <see cref="GaThread" /> (<see cref="GaThread" />*).
/// <br>5. Second parameter must be pointer to <c>void</c> (<c>void</c>*).</summary>
typedef ThreadFunctionReturn (GACALL *ThreadFunctionPointer)(GaThread*, void*);
/// <summary><c>GaThreadParameter</c> structure contains information needed to start new thread.
/// It has pointer to function which is entry point of thread and pointer to parameters which will be passed to the function.
/// Restrictions of entry point's function of a thread are described by <c>GaThreadFunctionPointer</c> type.</summary>
struct GaThreadParameter
{
public:
/// <summary>Pointer to entry point's function of thread.</summary>
ThreadFunctionPointer _functionPointer;
/// <summary>Pointer to parameters which will be passed to the entry point's function.</summary>
void* _functionParameters;
};// END STRUCTURE DEFINITION GaThreadParameter
/// <summary>This enumeration defines possible states of threads.</summary>
enum GaThreadStatus
{
/// <summary>Thread is running.</summary>
GATS_RUNNING = 0x1,
/// <summary>Thread execution is terminated, but thread object still exists and can be used to restart execution.</summary>
GATS_STOPPED = 0x2,
/// <summary>Thread execution is temporary is suspended.</summary>
GATS_PAUSED = 0x4,
/// <summary>Used for checking running state of thread.</summary>
GATS_NOT_RUNNING = GATS_STOPPED | GATS_PAUSED
};
/// <summary><c>GaCriticalSection</c> class is wrapper class for system synchronization object.
///
/// This class provides basic synchronization and protection from concurrent access to the objects and resources.
/// Built-in synchronizators used in other classes are instances of <c>GaCriticalSection</c> class. <c>LOCK</c> and
/// <c>UNLOCK</c> macros can operate on instances of this class.</summary>
class GaCriticalSection
{
private:
/// <summary>System specific object used for synchronization of critical section.</summary>
SysSyncObject _section;
public:
/// <summary>Constructor performs system specific initialization of synchronization object if needed.</summary>
GaCriticalSection()
{
#if defined(GAL_PLATFORM_WIN)
InitializeCriticalSection( (LPCRITICAL_SECTION)&_section );
#elif defined(GAL_PLATFORM_NIX)
pthread_mutex_init( &_section, NULL );
#endif
}
/// <summary>Frees resources used by system synchronization object.</summary>
~GaCriticalSection()
{
#if defined(GAL_PLATFORM_WIN)
DeleteCriticalSection( (LPCRITICAL_SECTION)&_section );
#elif defined(GAL_PLATFORM_NIX)
pthread_mutex_destroy( &_section );
#endif
}
/// <summary><c>Lock</c> method acquires synchronization object and prevents other thread to access protected section simultaneously.
/// If another thread had already acquired synchronization object current thread is put to sleep, and is waked when synchronization
/// object is released. </summary>
inline void GACALL Lock()
{
#if defined(GAL_PLATFORM_WIN)
EnterCriticalSection( (LPCRITICAL_SECTION)&_section );
#elif defined(GAL_PLATFORM_NIX)
pthread_mutex_lock( &_section );
#endif
}
/// <summary><c>Unlock</c> method release synchronization object and wakes threads which was put to wait for release of the object.</summary>
inline void GACALL Unlock()
{
#if defined(GAL_PLATFORM_WIN)
LeaveCriticalSection( (LPCRITICAL_SECTION)&_section );
#elif defined(GAL_PLATFORM_NIX)
pthread_mutex_unlock( &_section );
#endif
}
};// END CLASS DEFINITION GaCriticalSection
/// <summary><c>GaSectionLock</c> class is used for automatic access control with help of <see cref="GaCriticalSection" /> class.
/// Synchronization object can be automatically acquired when instance of <c>GaSectionLock</c> is created. If synchronization object
/// is locked by instance of <c>GaSectionLock</c> it is released when the instance goes out of scope. This mechanism provides simple
/// way of managing critical sections because users don't have to worry about releasing of synchronization object in most cases,
/// but for more complicated cases <c>LOCK</c> and <c>UNLOCK</c> macros can be used with instances of this class or with
/// <see cref="GaCriticalSection" /> class. <c>GaSectionLock</c> is mainly employed by <c>LOCK_OBJECT</c> and <c>LOCK_THIS_OBJECT</c>.
///
/// Object of this class shouldn't be used from multiple threads simultaneously.</summary>
class GaSectionLock
{
private:
/// <summary>Pointer to underlying synchronization object which is managed by this lock.</summary>
GaCriticalSection* _section;
/// <summary>Keeps track whether underlying synchronization object is locked by this instance of <c>GaSectionLock</c> class.</summary>
bool _locked;
public:
/// <summary>Constructor associates new instance of this class with underlying synchronization object.</summary>
/// <param name="section">pointer to underlying synchronization object.</param>
/// <param name="aquireLock">if this parameter is set to <c>true</c> constructor tries to acquire underlying object immediately.</param>
GaSectionLock(GaCriticalSection* section,
bool aquireLock) : _section(section),
_locked(false)
{
if( aquireLock )
Lock();
}
/// <summary>Destructor releases underlying synchronization object if it was acquired by this instance of <c>GaSectionLock</c> class.</summary>
~GaSectionLock() { Unlock(); }
/// <summary><c>Lock</c> method locks underlying synchronization object.
/// If it was already locked by this instance of <c>GaSectionLock</c> class, call has no effect. Details of locking synchronization object
/// are described in specification of <c>GaCriticalSection::Lock</c> method.</summary>
inline void GACALL Lock()
{
if( !_locked )
{
_section->Lock();
_locked = true;
}
}
/// <summary>Unlock method unlocks underlying synchronization object.
/// If it wasn't locked by this instance of <c>GaSectionLock</c> class, call has no effect. Details of unlocking synchronization object are
/// described in specification of <c>GaCriticalSection::Unlock</c> method.</summary>
inline void GACALL Unlock()
{
if( _locked )
{
_locked = false;
_section->Unlock();
}
}
};// END CLASS DEFINITION GaSectionLock
// Controls of threads
/// <summary><c>GaThread</c> class controls system threads.
/// It wraps system specific control of threading. This class has built-in synchronizator so it is allowed to use <c>LOCK_OBJECT</c>
/// and <c>LOCK_THIS_OBJECT</c> macros with instances of this class.</summary>
class GaThread
{
DEFINE_SYNC_CLASS
private:
/// <summary>This attribute holds running status of the thread.</summary>
GaThreadStatus _status;
/// <summary>System specific the thread object or handle to it.</summary>
SystemThread _thread;
/// <summary>stores identification number of thread if it is running or it is suspended.</summary>
ThreadID _id;
/// <summary>User defined information (thread's entry point and custom parameters passed to the thread) needed to start thread.</summary>
GaThreadParameter _parameters;
public:
/// <summary>Initializes thread object and stores thread parameters.
/// If user specified, thread can be started automatically when object is created.</summary>
/// <param name="parameters">thread parameters (entry point and pointer to custom parameters passed to the thread).</param>
/// <param name="started">if this parameter is set to <c>true</c> then thread start execution immediately. </param>
GAL_API
GaThread(const GaThreadParameter& parameters,
bool started);
/// <summary>Stops thread if it is running and releases system object and closes handles to it.</summary>
GAL_API
~GaThread();
/// <summary>Method starts execution of the thread or resumes execution if it was suspended.
/// If thread already running or system is unable to start/resume thread call fails and method returns <c>false</c>.
///
/// This method is thread-safe.</summary>
/// <returns>Method returns <c>true</c> if thread is started/resumed successfully. If thread was in running state or
/// system is unable to start/resume thread method returns <c>false</c>.</returns>
GAL_API
bool GACALL Start();
/// <summary>Method suspends thread execution if it is running.
/// If thread is stopped or system cannot suspend thread, call fails and method returns <c>false</c>. Pause method is intended
/// only for debugging purposes.
///
/// This method is not implemented on *nix systems.
///
/// This method is thread-safe.</summary>
/// <returns>Method returns <c>true</c> if thread is suspended successfully. If thread was stopped or system couldn't suspend thread
/// method returns <c>false</c>.</returns>
GAL_API
bool GACALL Pause();
/// <summary>Method stops execution of thread forcibly. Calling this method can cause problems thread cannot release acquired resources
/// properly and do necessary cleanups.
///
///This method is thread-safe.</summary>
/// <returns>Method returns <c>true</c> if thread is stopped successfully.
/// If thread was stopped or system couldn't stop thread method returns <c>false</c>.</returns>
GAL_API
bool GACALL Abort();
/// <summary>Suspends execution of thread from which it was called until thread which is managed by this instance of <c>GaThread</c> class
/// finish execution.
///
/// This method is thread-safe.</summary>
/// <returns>Method returns <c>true</c> if waiting has finished successfully. If there was an error method returns <c>false</c>.</returns>
GAL_API
bool GACALL Join();
/// <summary>This method is thread-safe.</summary>
/// <returns>Method returns current status of the thread.</returns>
inline GaThreadStatus GACALL Status()
{
LOCK_THIS_OBJECT( lock );
return _status;
}
/// <summary>This method is thread-safe.</summary>
/// <returns>Method returns identification number of thread if it is running or suspended. If thread is stopped, method returns 0.</returns>
inline ThreadID GACALL GetId()
{
LOCK_THIS_OBJECT( lock );
return _id;
}
private:
/// <summary>This method is used as entry point of new thread. Operating system calls this method when it starts thread.
/// After that, when thread enters <c>ThreadFunctionWrapper</c> it calls user entry point which is specified in thread parameters.</summary>
/// <param name="">pointer to object which manages new thread.</param>
/// <returns>Method returns result of user defined thread's entry point function when thread finishes its execution.</returns>
static ThreadFunctionReturn APICALL ThreadFunctionWraper(GaThread* thread);
};// END CLASS DEFINITION GaThread
} // Threading
#endif // __GA_THREADING_H__
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -