@@ -88,13 +88,16 @@ extern "C" void epicsThreadCallEntryPoint ( void * pPvt )
88
88
epicsThread * pThread =
89
89
static_cast <epicsThread *> ( pPvt );
90
90
bool threadDestroyed = false ;
91
- try {
91
+ {
92
+ epicsGuard < epicsMutex > guard ( pThread->mutex );
92
93
pThread->pThreadDestroyed = & threadDestroyed;
94
+ }
95
+ try {
93
96
if ( pThread->beginWait () ) {
94
97
pThread->runable .run ();
95
98
// The run() routine may have destroyed the epicsThread
96
99
// object by now; pThread can only be used below here
97
- // when the threadDestroyed flag is false.
100
+ // if the threadDestroyed flag is false.
98
101
}
99
102
}
100
103
catch ( const epicsThread::exitException & ) {
@@ -145,22 +148,11 @@ void epicsThread::exitWait () throw ()
145
148
bool epicsThread::exitWait ( const double delay ) throw ()
146
149
{
147
150
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.
151
153
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 ;
164
156
return true ;
165
157
}
166
158
epicsTime exitWaitBegin = epicsTime::getCurrent ();
@@ -174,12 +166,6 @@ bool epicsThread::exitWait ( const double delay ) throw ()
174
166
epicsTime current = epicsTime::getCurrent ();
175
167
exitWaitElapsed = current - exitWaitBegin;
176
168
}
177
- if (this ->terminated && !joined) {
178
- joined = true ;
179
-
180
- epicsGuardRelease < epicsMutex > unguard ( guard );
181
- epicsThreadMustJoin (this ->id );
182
- }
183
169
}
184
170
catch ( std :: exception & except ) {
185
171
errlogPrintf (
@@ -203,13 +189,12 @@ epicsThread::epicsThread (
203
189
epicsThreadRunable & runableIn, const char * pName,
204
190
unsigned stackSize, unsigned priority ) :
205
191
runable ( runableIn ), id ( 0 ), pThreadDestroyed ( 0 ),
206
- begin ( false ), cancel ( false ), terminated ( false ),
207
- joined ( false )
192
+ begin ( false ), cancel ( false ), terminated ( false )
208
193
{
209
194
epicsThreadOpts opts = EPICS_THREAD_OPTS_INIT;
210
195
opts.stackSize = stackSize;
211
196
opts.priority = priority;
212
- opts. joinable = 1 ;
197
+ /* Don't set joinable, we have our own mechanism for that */
213
198
214
199
this ->id = epicsThreadCreateOpt (
215
200
pName, epicsThreadCallEntryPoint,
@@ -231,6 +216,10 @@ epicsThread::~epicsThread () throw ()
231
216
fprintf ( stderr,
232
217
" was epicsThread object destroyed before thread exit ?\n " );
233
218
}
219
+ epicsGuard < epicsMutex > guard ( this ->mutex );
220
+ if ( this ->pThreadDestroyed ) {
221
+ *this ->pThreadDestroyed = true ;
222
+ }
234
223
}
235
224
236
225
void epicsThread::start () throw ()
0 commit comments