Skip to content

Commit cf42f09

Browse files
committed
Merge epicsThreadSelfJoin fixes from 3.15
1 parent 19146a5 commit cf42f09

File tree

3 files changed

+22
-35
lines changed

3 files changed

+22
-35
lines changed

modules/libcom/src/osi/epicsThread.cpp

Lines changed: 15 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -88,13 +88,16 @@ extern "C" void epicsThreadCallEntryPoint ( void * pPvt )
8888
epicsThread * pThread =
8989
static_cast <epicsThread *> ( pPvt );
9090
bool threadDestroyed = false;
91-
try {
91+
{
92+
epicsGuard < epicsMutex > guard ( pThread->mutex );
9293
pThread->pThreadDestroyed = & threadDestroyed;
94+
}
95+
try {
9396
if ( pThread->beginWait () ) {
9497
pThread->runable.run ();
9598
// The run() routine may have destroyed the epicsThread
9699
// object by now; pThread can only be used below here
97-
// when the threadDestroyed flag is false.
100+
// if the threadDestroyed flag is false.
98101
}
99102
}
100103
catch ( const epicsThread::exitException & ) {
@@ -145,22 +148,11 @@ void epicsThread::exitWait () throw ()
145148
bool epicsThread::exitWait ( const double delay ) throw ()
146149
{
147150
try {
148-
// When called (usually by a destructor) in the context of
149-
// the managed thread we can't wait for the thread to exit.
150-
// Set the threadDestroyed flag and return success.
151+
// When called in the context of the managed thread we can't
152+
// wait for the thread to exit. Set cancel and return true.
151153
if ( this->isCurrentThread() ) {
152-
if ( this->pThreadDestroyed ) {
153-
*this->pThreadDestroyed = true;
154-
}
155-
bool j;
156-
{
157-
epicsGuard < epicsMutex > guard ( this->mutex );
158-
j = joined;
159-
joined = true;
160-
}
161-
if(!j) {
162-
epicsThreadMustJoin(this->id);
163-
}
154+
epicsGuard < epicsMutex > guard ( this->mutex );
155+
this->cancel = true;
164156
return true;
165157
}
166158
epicsTime exitWaitBegin = epicsTime::getCurrent ();
@@ -174,12 +166,6 @@ bool epicsThread::exitWait ( const double delay ) throw ()
174166
epicsTime current = epicsTime::getCurrent ();
175167
exitWaitElapsed = current - exitWaitBegin;
176168
}
177-
if(this->terminated && !joined) {
178-
joined = true;
179-
180-
epicsGuardRelease < epicsMutex > unguard ( guard );
181-
epicsThreadMustJoin(this->id);
182-
}
183169
}
184170
catch ( std :: exception & except ) {
185171
errlogPrintf (
@@ -203,13 +189,12 @@ epicsThread::epicsThread (
203189
epicsThreadRunable & runableIn, const char * pName,
204190
unsigned stackSize, unsigned priority ) :
205191
runable ( runableIn ), id ( 0 ), pThreadDestroyed ( 0 ),
206-
begin ( false ), cancel ( false ), terminated ( false ),
207-
joined ( false )
192+
begin ( false ), cancel ( false ), terminated ( false )
208193
{
209194
epicsThreadOpts opts = EPICS_THREAD_OPTS_INIT;
210195
opts.stackSize = stackSize;
211196
opts.priority = priority;
212-
opts.joinable = 1;
197+
/* Don't set joinable, we have our own mechanism for that */
213198

214199
this->id = epicsThreadCreateOpt(
215200
pName, epicsThreadCallEntryPoint,
@@ -231,6 +216,10 @@ epicsThread::~epicsThread () throw ()
231216
fprintf ( stderr,
232217
"was epicsThread object destroyed before thread exit ?\n");
233218
}
219+
epicsGuard < epicsMutex > guard ( this->mutex );
220+
if ( this->pThreadDestroyed ) {
221+
*this->pThreadDestroyed = true;
222+
}
234223
}
235224

236225
void epicsThread::start () throw ()

modules/libcom/src/osi/epicsThread.h

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -372,21 +372,21 @@ class LIBCOM_API epicsThread {
372372
*
373373
* cf. epicsThreadOpts
374374
* \note Threads must be start() ed.
375-
* @throws epicsThread::unableToCreateThread on error.
375+
* \throws epicsThread::unableToCreateThread on error.
376376
*/
377377
epicsThread ( epicsThreadRunable &,const char *name, unsigned int stackSize,
378378
unsigned int priority=epicsThreadPriorityLow );
379379
~epicsThread () throw ();
380380
//! Actually start the thread.
381381
void start () throw ();
382-
//! Wait for the thread epicsRunnable::run() to return.
382+
//! Wait for the thread epicsThreadRunable::run() to return.
383383
void exitWait () throw ();
384-
//! Wait for the thread epicsRunnable::run() to return.
384+
//! Wait for the thread epicsThreadRunable::run() to return.
385385
//! \param delay Wait up to this many seconds.
386386
//! \return true if run() returned. false on timeout.
387387
bool exitWait ( const double delay ) throw ();
388-
//! @throws A special exitException which will be caught and ignored.
389-
//! \note This exitException doesn't not derive from std::exception
388+
//! \throws An epicsThread::exitException which will be caught and ignored.
389+
//! \note epicsThread::exitException does not derive from std::exception
390390
static void exit ();
391391
//! cf. epicsThreadResume()
392392
void resume () throw ();
@@ -425,7 +425,6 @@ class LIBCOM_API epicsThread {
425425
bool begin;
426426
bool cancel;
427427
bool terminated;
428-
bool joined;
429428

430429
bool beginWait () throw ();
431430
epicsThread ( const epicsThread & );

modules/libcom/test/epicsThreadClassTest.cpp

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -55,9 +55,8 @@ const char * const cases[] = {
5555
"BsErD", // Parent does exitWait(); child returns; parent deletes thread
5656
"BsXDr", // Parent does exitWait(0); parent deletes thread; child returns
5757
"BwXTDsr", // Parent does exitWait(0); parent deletes thread; child returns
58-
// These are currently broken
59-
// "BetWSrD", // Child does exitWait(); sync; child returns; parent deletes thread
60-
// "BetWsDr", // Child does exitWait(); sync; parent deletes thread; child returns
58+
"BetrWSD", // Child does exitWait(); sync; child returns; parent deletes thread
59+
"BetsWDr", // Child does exitWait(); sync; parent deletes thread; child returns
6160

6261
// In these cases the child deletes the thread
6362
"BdrS", // Child deletes thread, returns

0 commit comments

Comments
 (0)