cIsThread: Fixed a race condition on thread start.
This commit is contained in:
parent
1d593134da
commit
081e7ddd02
@ -68,11 +68,22 @@ cIsThread::~cIsThread()
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void cIsThread::DoExecute(void)
|
||||||
|
{
|
||||||
|
m_evtStart.Wait();
|
||||||
|
Execute();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool cIsThread::Start(void)
|
bool cIsThread::Start(void)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
m_Thread = std::thread(&cIsThread::Execute, this);
|
// Initialize the thread:
|
||||||
|
m_Thread = std::thread(&cIsThread::DoExecute, this);
|
||||||
|
|
||||||
#if defined (_MSC_VER) && defined(_DEBUG)
|
#if defined (_MSC_VER) && defined(_DEBUG)
|
||||||
if (!m_ThreadName.empty())
|
if (!m_ThreadName.empty())
|
||||||
@ -81,9 +92,12 @@ bool cIsThread::Start(void)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// Notify the thread that initialization is complete and it can run its code safely:
|
||||||
|
m_evtStart.Set();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
catch (std::system_error & a_Exception)
|
catch (const std::system_error & a_Exception)
|
||||||
{
|
{
|
||||||
LOGERROR("cIsThread::Start error %i: could not construct thread %s; %s", a_Exception.code().value(), m_ThreadName.c_str(), a_Exception.code().message().c_str());
|
LOGERROR("cIsThread::Start error %i: could not construct thread %s; %s", a_Exception.code().value(), m_ThreadName.c_str(), a_Exception.code().message().c_str());
|
||||||
return false;
|
return false;
|
||||||
|
@ -25,23 +25,28 @@ In the descending class' constructor call the Start() method to start the thread
|
|||||||
class cIsThread
|
class cIsThread
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
/// This is the main thread entrypoint
|
/** This is the main thread entrypoint.
|
||||||
|
This function, overloaded by the descendants, is called in the new thread. */
|
||||||
virtual void Execute(void) = 0;
|
virtual void Execute(void) = 0;
|
||||||
|
|
||||||
/// The overriden Execute() method should check this value periodically and terminate if this is true
|
/** The overriden Execute() method should check this value periodically and terminate if this is true. */
|
||||||
volatile bool m_ShouldTerminate;
|
volatile bool m_ShouldTerminate;
|
||||||
|
|
||||||
|
private:
|
||||||
|
/** Wrapper for Execute() that waits for the initialization event, to prevent race conditions in thread initialization. */
|
||||||
|
void DoExecute(void);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
cIsThread(const AString & a_ThreadName);
|
cIsThread(const AString & a_ThreadName);
|
||||||
virtual ~cIsThread();
|
virtual ~cIsThread();
|
||||||
|
|
||||||
/// Starts the thread; returns without waiting for the actual start
|
/** Starts the thread; returns without waiting for the actual start. */
|
||||||
bool Start(void);
|
bool Start(void);
|
||||||
|
|
||||||
/// Signals the thread to terminate and waits until it's finished
|
/** Signals the thread to terminate and waits until it's finished. */
|
||||||
void Stop(void);
|
void Stop(void);
|
||||||
|
|
||||||
/// Waits for the thread to finish. Doesn't signalize the ShouldTerminate flag
|
/** Waits for the thread to finish. Doesn't signalize the ShouldTerminate flag. */
|
||||||
bool Wait(void);
|
bool Wait(void);
|
||||||
|
|
||||||
/** Returns true if the thread calling this function is the thread contained within this object. */
|
/** Returns true if the thread calling this function is the thread contained within this object. */
|
||||||
@ -50,6 +55,10 @@ public:
|
|||||||
protected:
|
protected:
|
||||||
AString m_ThreadName;
|
AString m_ThreadName;
|
||||||
std::thread m_Thread;
|
std::thread m_Thread;
|
||||||
|
|
||||||
|
/** The event that is used to wait with the thread's execution until the thread object is fully initialized.
|
||||||
|
This prevents the IsCurrentThread() call to fail because of a race-condition. */
|
||||||
|
cEvent m_evtStart;
|
||||||
} ;
|
} ;
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user