Fix VxWorks epicsThreadMustJoin() problems
taskWait() actually returns OK on timeout, so drop the timeout warning (the other implementations don't have one). The taskWait() may return ERROR with S_objLib_OBJ_ID_ERROR if the target thread has higher priority; this indicates a successful join, because we already did a rendezvous using joinSem. Delete joinSem *after* calling taskSpareFieldSet(), in case it matters.
This commit is contained in:
@@ -211,16 +211,20 @@ void epicsThreadAwaitingJoin(int tid)
|
||||
if (status)
|
||||
perror("epicsThreadAwaitingJoin");
|
||||
|
||||
semDelete(joinSem);
|
||||
taskSpareFieldSet(tid, joinField, 0);
|
||||
semDelete(joinSem);
|
||||
}
|
||||
#define PREPARE_JOIN(tid, joinable) \
|
||||
taskSpareFieldSet(tid, joinField, \
|
||||
joinable ? (int) semBCreate(SEM_Q_FIFO, SEM_EMPTY) : 0)
|
||||
#define AWAIT_JOIN(tid) epicsThreadAwaitingJoin(tid)
|
||||
#define AWAIT_JOIN(tid) \
|
||||
epicsThreadAwaitingJoin(tid)
|
||||
|
||||
#else
|
||||
|
||||
#define PREPARE_JOIN(tid, joinable)
|
||||
#define AWAIT_JOIN(tid)
|
||||
|
||||
#endif
|
||||
|
||||
static void createFunction(EPICSTHREADFUNC func, void *parm)
|
||||
@@ -297,48 +301,34 @@ void epicsThreadMustJoin(epicsThreadId id)
|
||||
|
||||
joinSem = (SEM_ID) taskSpareFieldGet(tid, joinField);
|
||||
if ((int) joinSem == ERROR) {
|
||||
errlogPrintf("%s: Thread '%s' no longer exists.\n",
|
||||
fn, taskName(tid));
|
||||
errlogPrintf("%s: Thread %#x no longer exists.\n", fn, tid);
|
||||
return;
|
||||
}
|
||||
|
||||
if (tid == taskIdSelf()) {
|
||||
if (joinSem) {
|
||||
semDelete(joinSem);
|
||||
taskSpareFieldSet(tid, joinField, 0);
|
||||
semDelete(joinSem);
|
||||
}
|
||||
else {
|
||||
errlogPrintf("%s: Self-join of unjoinable thread '%s'\n",
|
||||
fn, taskName(tid));
|
||||
errlogPrintf("%s: Thread '%s' (%#x) can't self-join.\n",
|
||||
fn, epicsThreadGetNameSelf(), tid);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (!joinSem) {
|
||||
cantProceed("%s: Thread '%s' is not joinable.\n",
|
||||
fn, taskName(tid));
|
||||
cantProceed("%s: Thread '%s' (%#x) is not joinable.\n",
|
||||
fn, taskName(tid), tid);
|
||||
return;
|
||||
}
|
||||
|
||||
semGive(joinSem); /* Rendezvous with thread */
|
||||
|
||||
status = taskWait(tid, JOIN_WARNING_TIMEOUT);
|
||||
if (status && errno == S_objLib_OBJ_TIMEOUT) {
|
||||
errlogPrintf("Warning: %s still waiting for thread '%s'\n",
|
||||
fn, taskName(tid));
|
||||
status = taskWait(tid, WAIT_FOREVER);
|
||||
}
|
||||
if (status) {
|
||||
if (errno == S_taskLib_ILLEGAL_OPERATION) {
|
||||
errlogPrintf("%s: This shouldn't happen!\n", fn);
|
||||
}
|
||||
else if (errno == S_objLib_OBJ_ID_ERROR) {
|
||||
errlogPrintf("%s: %x is not a known thread\n", fn, tid);
|
||||
}
|
||||
else {
|
||||
perror(fn);
|
||||
}
|
||||
cantProceed(fn);
|
||||
status = taskWait(tid, WAIT_FOREVER);
|
||||
if (status && errno != S_objLib_OBJ_ID_ERROR) {
|
||||
perror(fn);
|
||||
cantProceed("%s: ", fn);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user