From 05e0381b191aeea29cfe7286c0797c6faf99f53c Mon Sep 17 00:00:00 2001 From: Andrew Johnson Date: Thu, 2 Jan 2020 16:39:10 -0600 Subject: [PATCH] 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. --- modules/libcom/src/osi/os/vxWorks/osdThread.c | 42 +++++++------------ 1 file changed, 16 insertions(+), 26 deletions(-) diff --git a/modules/libcom/src/osi/os/vxWorks/osdThread.c b/modules/libcom/src/osi/os/vxWorks/osdThread.c index 0ed31389f..1eaea3a3c 100644 --- a/modules/libcom/src/osi/os/vxWorks/osdThread.c +++ b/modules/libcom/src/osi/os/vxWorks/osdThread.c @@ -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 }