Files
rippled/modules/beast_basics/threads/beast_InterruptibleThread.h
2013-08-07 15:16:31 -07:00

185 lines
5.1 KiB
C++

//------------------------------------------------------------------------------
/*
This file is part of Beast: https://github.com/vinniefalco/Beast
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================
#ifndef BEAST_INTERRUPTIBLETHREAD_BEASTHEADER
#define BEAST_INTERRUPTIBLETHREAD_BEASTHEADER
//==============================================================================
/**
A thread with soft interruption support.
The thread must periodically call interruptionPoint(), which returns `true`
the first time an interruption has occurred since the last call to
interruptionPoint().
To create a thread, derive your class from InterruptibleThread::EntryPoint
and implement the threadRun() function. Then, call run() with your object.
@ingroup beast_core
*/
class BEAST_API InterruptibleThread
{
public:
/** InterruptibleThread entry point.
*/
class EntryPoint
{
public:
virtual ~EntryPoint () { }
virtual void threadRun () = 0;
};
public:
typedef Thread::ThreadID id;
/** Construct an interruptible thread.
The name is used for debugger diagnostics.
@param name The name of the thread.
*/
explicit InterruptibleThread (String name);
/** Destroy the interruptible thread.
This will signal an interrupt and wait until the thread exits.
*/
~InterruptibleThread ();
/** Start the thread.
*/
void start (EntryPoint* const entryPoint);
/** Wait for the thread to exit.
*/
void join ();
/** Wait for interrupt or timeout.
This call blocks until the thread is interrupted, or until the timeout
expires if milliSeconds is non-negative.
May only be called by the thread of execution.
@param milliSeconds The amount of time to wait. Negative values mean
no timeout.
@return `true` if the interrupt occurred, or `false` if the
timeout expired.
*/
bool wait (int milliSeconds = -1);
/** Interrupt the thread of execution.
This can be called from any thread.
*/
void interrupt ();
/** Determine if an interruption is requested.
After the function returns `true`, the interrupt status is cleared.
Subsequent calls will return `false` until another interrupt is requested.
May only be called by the thread of execution.
@see CurrentInterruptibleThread::interruptionPoint
@return `true` if an interrupt was requested.
*/
bool interruptionPoint ();
/** Get the ID of the associated thread.
@return The ID of the thread.
*/
id getId () const;
/** Determine if this is the thread of execution.
@note The return value is undefined if the thread is not running.
@return `true` if the caller is this thread of execution.
*/
bool isTheCurrentThread () const;
/** Adjust the thread priority.
@note This only affects some platforms.
@param priority A number from 0..10
*/
void setPriority (int priority);
/** Get the InterruptibleThread for the thread of execution.
This will return `nullptr` when called from the message thread, or from
a thread of execution that is not an InterruptibleThread.
*/
static InterruptibleThread* getCurrentThread ();
private:
class ThreadHelper : public Thread
{
public:
ThreadHelper (String name, InterruptibleThread* owner);
InterruptibleThread* getOwner () const;
void run ();
private:
InterruptibleThread* const m_owner;
};
void run ();
ThreadHelper m_thread;
EntryPoint* m_entryPoint;
WaitableEvent m_runEvent;
id m_threadId;
enum
{
stateRun,
stateInterrupt,
stateReturn,
stateWait
};
AtomicState m_state;
};
//------------------------------------------------------------------------------
/** Global operations on the current InterruptibleThread.
Calling members of the class from a thread of execution which is not an
InterruptibleThread results in undefined behavior.
*/
class CurrentInterruptibleThread
{
public:
/** Call the current thread's interrupt point function.
*/
static bool interruptionPoint ();
};
#endif