TcpLib
Loading...
Searching...
No Matches
eut::RepeatingThread Class Referenceabstract

Base class for a thread that executes its work endlessly until aborted. More...

#include <EuRepeatingThread.h>

Inheritance diagram for eut::RepeatingThread:
Collaboration diagram for eut::RepeatingThread:

Public Types

enum  EuTHREADERROR { EuTHREAD_ERR_NO_THREAD = -10301 , EuTHREAD_ERR_THREAD_ALREADY_WORKING = -10302 , EuTHREAD_ERR_THREAD_BREAK_COUNT_LESS_THAN_ZERO = -10303 , EuTHREAD_ERR_UNKNOWN = -10400 }
 Error range = -10301 to -10400 More...
 
enum  STATUS {
  eAT_THE_START , eWORKING , ePAUSING , eENDING ,
  eCOMPLETED
}
 
enum  ORDER { eUNDEFINED , eDO_WORK , eEXIT }
 

Public Member Functions

 RepeatingThread ()
 
virtual ~RepeatingThread ()
 
virtual int start ()
 
virtual void cancel ()
 
bool testCancel ()
 
RepeatingThread::STATUS status () const
 
bool isInExclusiveAccess () const
 
void setExclusiveAccess ()
 
void unsetExclusiveAccess ()
 
int getBreakCounter ()
 
virtual void takeABreak ()
 
virtual void finishBreak ()
 
void waitForInput ()
 
void signalInput ()
 

Protected Member Functions

void threadWork ()
 
void setStatus (STATUS eStatus)
 
STATUS getStatus ()
 
void toOrder (ORDER eOrder)
 
ORDER getOrder ()
 
virtual void work ()=0
 

Private Member Functions

 RepeatingThread (const RepeatingThread &)
 
RepeatingThreadoperator= (const RepeatingThread &)
 

Private Attributes

STATUS m_eStatus
 
ORDER m_eOrder
 
std::thread * m_pThread
 
CriticalSection m_ExclusiveAccessSection
 
std::mutex m_WaitMutex
 
std::condition_variable m_InputCondVar
 
std::mutex m_BreakMutex
 
std::condition_variable m_BreakCondVar
 
int m_iBreakCounter
 
int m_iDataReady
 

Detailed Description

Base class for a thread that executes its work endlessly until aborted.

In subclasses, only the virtual method RepeatingThread::work() must be overwritten.

Attention
The thread must be terminated after the start with cancel() before calling the destructor!
Author
Helmut Jakoby

Member Enumeration Documentation

◆ EuTHREADERROR

Error range = -10301 to -10400

Enumerator
EuTHREAD_ERR_NO_THREAD 

-10301: An expected thread is not available or not started.

EuTHREAD_ERR_THREAD_ALREADY_WORKING 

-10302: The thread is already started.

EuTHREAD_ERR_THREAD_BREAK_COUNT_LESS_THAN_ZERO 

-10303: The thread has been woken from sleep too often.

EuTHREAD_ERR_UNKNOWN 

-10400: Undefined error.

◆ ORDER

A RepeatingThread can be given instructions after the start.

Enumerator
eUNDEFINED 

Undefined.

eDO_WORK 

Thread should work.

eEXIT 

Thread should end.

◆ STATUS

To be able to control the thread, it is helpful to know the work status.

Enumerator
eAT_THE_START 

The thread has not yet worked.

eWORKING 

The thread is working.

ePAUSING 

The thread is paused.

eENDING 

The thread is just finishing its work.

eCOMPLETED 

The thread is finished with its work.

Constructor & Destructor Documentation

◆ RepeatingThread() [1/2]

eut::RepeatingThread::RepeatingThread ( )

Standard constructor.

◆ ~RepeatingThread()

virtual eut::RepeatingThread::~RepeatingThread ( )
virtual

Destructor.

Attention
The method cancel() must be called before the destructor! Since cancel() is virtual, it cannot be executed in dtor.

◆ RepeatingThread() [2/2]

eut::RepeatingThread::RepeatingThread ( const RepeatingThread & )
private

The copy constructor is not available.

Member Function Documentation

◆ cancel()

virtual void eut::RepeatingThread::cancel ( )
virtual

Terminates the thread.

Attention
Must be called before the destructor if started with start()! Since cancel() is virtual, it cannot be executed in dtor.

Reimplemented in tcp::Client, tcp::ClientReceiver, tcp::Server, tcp::ServerAcceptReceiver, tcp::ServerReceiver, and tcp::Transmitter.

◆ finishBreak()

virtual void eut::RepeatingThread::finishBreak ( )
virtual

Ends the working pause. Must have been initiated by takeABreak().

Reimplemented in tcp::ReceiverTransmitter.

◆ getBreakCounter()

int eut::RepeatingThread::getBreakCounter ( )

Returns the pause counter.

See also
m_iBreakCounter

◆ getOrder()

ORDER eut::RepeatingThread::getOrder ( )
protected

Returns the last transferred instruction.

Returns
The current instructions.

◆ getStatus()

STATUS eut::RepeatingThread::getStatus ( )
protected

Returns the current status.

Returns
The seted status.

◆ isInExclusiveAccess()

bool eut::RepeatingThread::isInExclusiveAccess ( ) const

Is the thread in an exclusive area?

Returns
If true, it's in an exclusive area.
See also
setExclusiveAccess() and unsetExclusiveAccess()

◆ operator=()

RepeatingThread & eut::RepeatingThread::operator= ( const RepeatingThread & )
private

Assignment operator is not available.

◆ setExclusiveAccess()

void eut::RepeatingThread::setExclusiveAccess ( )

Initiates a CriticalSection. Must be canceled using unsetExclusiveAccess ().

See also
m_ExclusiveAccessSection

◆ setStatus()

void eut::RepeatingThread::setStatus ( STATUS eStatus)
protected

Set the status.

Parameters
[in]eStatusThe status to be set.

◆ signalInput()

void eut::RepeatingThread::signalInput ( )

Ends the wait without activity initiated by waitForInput().

◆ start()

virtual int eut::RepeatingThread::start ( )
virtual

Starts the thread.

Returns
A return value < 0 indicates an error. E.g. if thread is already running.
Attention
The thread must be terminated after start() before the destructor with cancel().

◆ status()

RepeatingThread::STATUS eut::RepeatingThread::status ( ) const

Returns the status of the thread.

Returns
The status.

◆ takeABreak()

virtual void eut::RepeatingThread::takeABreak ( )
virtual

Initiates a pause of the thread to interrupt the processing. Must be ended again with finishBreak().

Note
Since the thread only skips the processing (i.e. is still running) a real suspension of the thread can be achieved by using the method waitForInput() in the method work() of the derived class.

Reimplemented in tcp::ReceiverTransmitter.

◆ testCancel()

bool eut::RepeatingThread::testCancel ( )

Returns true when thread has ended.

Returns
see above.

◆ threadWork()

void eut::RepeatingThread::threadWork ( )
protected

This method, executed by the thread, calls the method work() in a loop.

◆ toOrder()

void eut::RepeatingThread::toOrder ( ORDER eOrder)
protected

Accepts the transferred instruction.

Parameters
[in]eOrderThe statement to be set.

◆ unsetExclusiveAccess()

void eut::RepeatingThread::unsetExclusiveAccess ( )

Cancels an initiated CriticalSection if set by setExclusiveAccess()

See also
m_ExclusiveAccessSection

◆ waitForInput()

void eut::RepeatingThread::waitForInput ( )

Lets the thread wait at a defined position without activity. Must be terminated again by signalInput().

Note
This method can be used in the method work() of a derived class to suspend the thread. The thread wakes up again with signalInput(), which must also be initiated in the derived class.

◆ work()

virtual void eut::RepeatingThread::work ( )
protectedpure virtual

This method is executed by the thread and must be overwritten in subclasses.

See also
threadWork()

Implemented in tcp::Client, tcp::ClientReceiver, tcp::Server, tcp::ServerAcceptReceiver, tcp::ServerReceiver, and tcp::Transmitter.

Member Data Documentation

◆ m_BreakCondVar

std::condition_variable eut::RepeatingThread::m_BreakCondVar
private

Condition_variable to pause

See also
threadWork(), finishBreak() and m_BreakMutex

◆ m_BreakMutex

std::mutex eut::RepeatingThread::m_BreakMutex
private

Mutex to pause.

See also
threadWork() und m_BreakCondVar

◆ m_eOrder

ORDER eut::RepeatingThread::m_eOrder
private

A thread can be given a command which is set here.

◆ m_eStatus

STATUS eut::RepeatingThread::m_eStatus
private

The working status.

◆ m_ExclusiveAccessSection

CriticalSection eut::RepeatingThread::m_ExclusiveAccessSection
private

Is required to define access protected areas by RepeatingThread::setExclusiveAccess() or RepeatingThread::unsetExclusiveAccess().

◆ m_iBreakCounter

int eut::RepeatingThread::m_iBreakCounter
private

If a RepeatingThread is to pause, this counter is incremented. If the thread should wake up again, this counter is decremented. At 0 the thread is woken up again.

This enables a nested sleep and wake up.

◆ m_iDataReady

int eut::RepeatingThread::m_iDataReady
private

To avoid "lost wakeup" and "spurious wakeups" this variable is necessary.

  • Lost wakeup: The phenomenon of the lost wakeup is that the sender sends its notification before the receiver gets to its wait state. The consequence is that the notification is lost. The C++ standard describes condition variables as a simultaneous synchronisation mechanism: "The condition_variable class is a synchronisation primitive that can be used to block a thread, or multiple threads at the same time, ...". So the notification gets lost, and the receiver is waiting and waiting and ... .
  • Spurious wakeup: It may happen that the receiver wakes up, although no notification happened. At a minimum POSIX Threads and the Windows API can be victims of these phenomena.

Found in: https://www.modernescpp.com/index.php/c-core-guidelines-be-aware-of-the-traps-of-condition-variables

◆ m_InputCondVar

std::condition_variable eut::RepeatingThread::m_InputCondVar
private

Condition_variable to wait for input.

See also
waitForInput(), signalInput() and m_WaitMutex

◆ m_pThread

std::thread* eut::RepeatingThread::m_pThread
private

The 'real' thread.

◆ m_WaitMutex

std::mutex eut::RepeatingThread::m_WaitMutex
private

Mutex to wait for input.

See also
waitForInput() and m_InputCondVar

The documentation for this class was generated from the following file: