34 const char * name,
unsigned int priority,
unsigned int stackSize,
45 epicsThreadRunable::~epicsThreadRunable () {}
46 void epicsThreadRunable::run () {}
47 void epicsThreadRunable::show (
unsigned int )
const {}
50 public std :: exception {
52 const char * what ()
const throw ();
58 return "unable to create thread";
61 void epicsThread :: printLastChanceExceptionMessage (
62 const char * pExceptionTypeName,
63 const char * pExceptionContext )
67 epicsTime cur = epicsTime :: getCurrent ();
68 cur.strftime ( date,
sizeof ( date ),
"%a %b %d %Y %H:%M:%S.%f");
71 strcpy ( date,
"<UKN DATE>" );
76 "epicsThread: Unexpected C++ exception \"%s\" " 77 "with type \"%s\" in thread \"%s\" at %s\n",
78 pExceptionContext, pExceptionTypeName, name, date );
90 bool threadDestroyed =
false;
92 pThread->pThreadDestroyed = & threadDestroyed;
93 if ( pThread->beginWait () ) {
94 pThread->runable.run ();
100 catch (
const epicsThread::exitException & ) {
102 catch ( std :: exception & except ) {
103 if ( ! threadDestroyed ) {
104 pThread->printLastChanceExceptionMessage (
105 typeid ( except ).name (), except.what () );
109 if ( ! threadDestroyed ) {
110 pThread->printLastChanceExceptionMessage (
111 "catch ( ... )",
"Non-standard C++ exception" );
114 if ( ! threadDestroyed ) {
116 pThread->pThreadDestroyed =
NULL;
117 pThread->terminated =
true;
118 pThread->exitEvent.signal ();
124 bool epicsThread::beginWait ()
throw ()
127 while ( ! this->
begin && ! this->cancel ) {
131 return this->
begin && ! this->cancel;
134 void epicsThread::exit ()
136 throw exitException ();
139 void epicsThread::exitWait ()
throw ()
141 bool success = this->exitWait ( DBL_MAX );
145 bool epicsThread::exitWait (
const double delay )
throw ()
151 if ( this->isCurrentThread() ) {
152 if ( this->pThreadDestroyed ) {
153 *this->pThreadDestroyed =
true;
166 epicsTime exitWaitBegin = epicsTime::getCurrent ();
167 double exitWaitElapsed = 0.0;
170 while ( ! this->terminated && exitWaitElapsed < delay ) {
172 this->
event.signal ();
173 this->exitEvent.wait ( delay - exitWaitElapsed );
174 epicsTime current = epicsTime::getCurrent ();
175 exitWaitElapsed = current - exitWaitBegin;
177 if(this->terminated && !joined) {
184 catch ( std :: exception & except ) {
186 "epicsThread::exitWait(): Unexpected exception " 193 "Non-standard unexpected exception in " 194 "epicsThread::exitWait()\n" );
198 this->
event.signal ();
199 return this->terminated;
202 epicsThread::epicsThread (
203 epicsThreadRunable & runableIn,
const char * pName,
204 unsigned stackSize,
unsigned priority ) :
205 runable ( runableIn ), id ( 0 ), pThreadDestroyed ( 0 ),
206 begin (
false ), cancel (
false ), terminated (
false ),
216 static_cast < void * > (
this ),
219 throw unableToCreateThread ();
223 epicsThread::~epicsThread ()
throw ()
225 while ( ! this->exitWait ( 10.0 ) ) {
227 this->getName ( nameBuf,
sizeof ( nameBuf ) );
229 "epicsThread::~epicsThread(): \"%s\" blocking for thread \"%s\" to exit\n",
230 getNameSelf(), nameBuf );
232 "was epicsThread object destroyed before thread exit ?\n");
236 void epicsThread::start ()
throw ()
242 this->
event.signal ();
245 bool epicsThread::isCurrentThread ()
const throw ()
250 void epicsThread::resume ()
throw ()
255 void epicsThread::getName (
char *name,
size_t size )
const throw ()
265 unsigned int epicsThread::getPriority ()
const throw ()
270 void epicsThread::setPriority (
unsigned int priority)
throw ()
275 bool epicsThread::priorityIsEqual (
const epicsThread &otherThread)
const throw ()
283 bool epicsThread::isSuspended ()
const throw ()
293 return (this->
id == rhs.id);
296 void epicsThread::suspendSelf ()
throw ()
301 void epicsThread::sleep (
double seconds)
throw ()
306 const char *epicsThread::getNameSelf ()
throw ()
311 bool epicsThread::isOkToBlock ()
throw ()
316 void epicsThread::setOkToBlock(
bool isOkToBlock)
throw ()
321 void epicsThreadPrivateBase::throwUnableToCreateThreadPrivate ()
323 throw epicsThreadPrivateBase::unableToCreateThreadPrivate ();
326 void epicsThread :: show (
unsigned level )
const throw ()
328 ::printf (
"epicsThread at %p\n", this->
id );
332 ::printf (
"pThreadDestroyed = %p\n", this->pThreadDestroyed );
333 ::printf (
"begin = %c, cancel = %c, terminated = %c\n",
334 this->
begin ?
'T' :
'F',
335 this->cancel ?
'T' :
'F',
336 this->terminated ?
'T' :
'F' );
337 this->runable.show ( level - 2u );
338 this->
mutex.show ( level - 2u );
339 ::printf (
"general purpose event\n" );
340 this->
event.show ( level - 2u );
342 this->exitEvent.show ( level - 2u );
350 static const int okToBlockNo = 0;
351 static const int okToBlockYes = 1;
353 static void epicsThreadOnceIdInit(
void *)
360 const int *pokToBlock;
363 return (pokToBlock ? *pokToBlock : 0);
368 const int *pokToBlock;
370 pokToBlock = (isOkToBlock) ? &okToBlockYes : &okToBlockNo;
375 const char *name,
unsigned int priority,
unsigned int stackSize,
379 name, priority, stackSize, funptr, parm );
void epicsStdCall epicsThreadSetOkToBlock(int isOkToBlock)
epicsThreadPrivateId okToBlockPrivate
epicsThreadId epicsStdCall epicsThreadMustCreate(const char *name, unsigned int priority, unsigned int stackSize, EPICSTHREADFUNC funptr, void *parm)
#define assert(exp)
Declare that a condition should be true.
LIBCOM_API unsigned int epicsStdCall epicsThreadGetPriority(epicsThreadId id)
An EPICS-specific replacement for ANSI C's assert.
LIBCOM_API void *epicsStdCall epicsThreadPrivateGet(epicsThreadPrivateId)
LIBCOM_API const char *epicsStdCall epicsThreadGetNameSelf(void)
LIBCOM_API void epicsStdCall epicsThreadShow(epicsThreadId id, unsigned int level)
const char * what() const
LIBCOM_API int epicsStdCall epicsThreadIsEqual(epicsThreadId id1, epicsThreadId id2)
epicsThreadId epicsStdCall epicsThreadCreate(const char *name, unsigned int priority, unsigned int stackSize, EPICSTHREADFUNC funptr, void *parm)
#define EPICS_THREAD_ONCE_INIT
LIBCOM_API void epicsStdCall epicsThreadSuspendSelf(void)
LIBCOM_API void epicsStdCall epicsThreadOnce(epicsThreadOnceId *id, EPICSTHREADFUNC, void *arg)
const T & epicsMin(const T &a, const T &b)
LIBCOM_API void epicsStdCall epicsThreadPrivateSet(epicsThreadPrivateId, void *)
LIBCOM_API void epicsStdCall epicsThreadResume(epicsThreadId id)
LIBCOM_API void epicsStdCall epicsThreadGetName(epicsThreadId id, char *name, size_t size)
int main(int argc, char **argv)
int errlogPrintf(const char *pFormat,...)
void date(const char *format)
int epicsStdCall epicsThreadIsOkToBlock(void)
LIBCOM_API void epicsStdCall epicsThreadSleep(double seconds)
Block the calling thread for at least the specified time.
#define EPICS_THREAD_OPTS_INIT
Contains a few templates out of the C++ standard header algorithm.
LIBCOM_API void epicsThreadMustJoin(epicsThreadId id)
LIBCOM_API epicsThreadId epicsThreadCreateOpt(const char *name, EPICSTHREADFUNC funptr, void *parm, const epicsThreadOpts *opts)
Allocate and start a new OS thread.
LIBCOM_API int epicsStdCall epicsThreadIsSuspended(epicsThreadId id)
EPICS time-stamps (epicsTimeStamp), epicsTime C++ class and C functions for handling wall-clock times...
void epicsThreadCallEntryPoint(void *pPvt)
C++ and C descriptions for a thread.
LIBCOM_API epicsThreadPrivateId epicsStdCall epicsThreadPrivateCreate(void)
epicsThreadId epicsThreadMainId
void(* EPICSTHREADFUNC)(void *parm)
LIBCOM_API void epicsStdCall epicsThreadSetPriority(epicsThreadId id, unsigned int priority)
bool operator==(const epics::pvData::shared_vector< A > &a, const epics::pvData::shared_vector< B > &b)
LIBCOM_API epicsThreadId epicsStdCall epicsThreadGetIdSelf(void)