added exit and waitRelease capabilities to epicsThread class

This commit is contained in:
Jeff Hill
2002-05-14 20:24:49 +00:00
parent 0afd9ddbb8
commit c4c7ee7803
2 changed files with 48 additions and 13 deletions

View File

@@ -17,14 +17,33 @@ void epicsThreadRunable::show(unsigned int) const {};
void epicsThreadCallEntryPoint ( void * pPvt )
{
bool waitRelease = false;
epicsThread * pThread = static_cast <epicsThread *> ( pPvt );
pThread->begin.wait ();
if ( ! pThread->cancel ) {
pThread->runable.run ();
pThread->pWaitReleaseFlag = & waitRelease;
try {
pThread->beginEvent.wait ();
if ( ! pThread->cancel ) {
pThread->runable.run ();
}
if ( ! waitRelease ) {
pThread->exitWaitRelease ();
}
return;
}
pThread->id = 0;
pThread->terminated = true;
pThread->exit.signal ();
catch ( const epicsThread::exitException & ) {
if ( ! waitRelease ) {
pThread->exitWaitRelease ();
}
return;
}
catch ( ... ) {
throw;
}
}
void epicsThread::exit ()
{
throw exitException ();
}
void epicsThread::exitWait ()
@@ -35,14 +54,25 @@ void epicsThread::exitWait ()
bool epicsThread::exitWait ( double delay )
{
if ( ! this->terminated ) {
this->exit.wait ( delay );
this->exitEvent.wait ( delay );
}
return this->terminated;
}
void epicsThread::exitWaitRelease ()
{
if ( this->isCurrentThread() ) {
this->id = 0;
this->terminated = true;
*this->pWaitReleaseFlag = true;
this->exitEvent.signal ();
}
}
epicsThread::epicsThread ( epicsThreadRunable &r, const char *name,
unsigned stackSize, unsigned priority ) :
runable(r), cancel (false), terminated ( false )
runable(r), pWaitReleaseFlag ( 0 ),
cancel (false), terminated ( false )
{
this->id = epicsThreadCreate ( name, priority, stackSize,
epicsThreadCallEntryPoint, static_cast <void *> (this) );
@@ -52,7 +82,7 @@ epicsThread::~epicsThread ()
{
if ( this->id ) {
this->cancel = true;
this->begin.signal ();
this->beginEvent.signal ();
while ( ! this->exitWait ( 10.0 ) ) {
char nameBuf [256];
this->getName ( nameBuf, sizeof ( nameBuf ) );
@@ -68,7 +98,7 @@ epicsThread::~epicsThread ()
void epicsThread::start ()
{
this->begin.signal ();
this->beginEvent.signal ();
}
bool epicsThread::isCurrentThread () const

View File

@@ -121,6 +121,8 @@ public:
void start();
void exitWait ();
bool exitWait ( double delay );
void exitWaitRelease (); // noop if not called by managed thread
static void exit ();
void resume ();
void getName (char *name, size_t size) const;
unsigned int getPriority () const;
@@ -136,16 +138,19 @@ public:
static const char * getNameSelf ();
class mustBeCalledByManagedThread {}; // exception
private:
epicsThreadRunable &runable;
epicsThreadRunable & runable;
epicsThreadId id;
epicsEvent exit;
epicsEvent begin;
epicsEvent exitEvent;
epicsEvent beginEvent;
volatile bool * pWaitReleaseFlag;
bool cancel;
bool terminated;
epicsThread ( const epicsThread & );
epicsThread & operator = ( const epicsThread & );
class exitException {};
friend void epicsThreadCallEntryPoint (void *pPvt);
};