It seems like the message is emitted by
epicsThreadAwaitingJoin() [1] which seems to be a VxWorks-specific
function that gets called at the end of epicsThreadEntry() [2] (in other
words after callbackThread::run() has completed) and only if
EPICS_THREAD_CAN_JOIN is defined. It seems like the message is only
emitted if epicsThreadAwaitingJoin() hasn't been able to acquire joinSem
within a reasonable time. I'm wondering if some other code forgot to
release the semaphore.
In the VxWorks implementation that message is printed once by any joinable epicsThread that has finished its work and returns from its entry routine if no other thread calls epicsThreadJoin() on the thread within 60 seconds of it having returned. I assumed
that code would only set the join flag if its parent actually uses epicsThreadJoin() to clean up, and that would normally happen under controlled conditions when a parent is waiting for the thread to exit.