diff --git a/src/libCom/osi/os/posix/osdEvent.c b/src/libCom/osi/os/posix/osdEvent.c index 764e39b2a..16e0ba665 100644 --- a/src/libCom/osi/os/posix/osdEvent.c +++ b/src/libCom/osi/os/posix/osdEvent.c @@ -45,6 +45,27 @@ if(status) { \ errlogPrintf("%s failed: error %s\n",(message),strerror((status))); \ cantProceed((method)); \ } + +/* pthread_mutex_lock is NOT supposed to return EINTR but bad implementations*/ +static int mutexLock(pthread_mutex_t *id) +{ + int status; + + while(1) { + status = pthread_mutex_lock(id); + if(status!=EINTR) return status; + } +} + +int condTimedwait(pthread_cond_t *condId, pthread_mutex_t *mutexId, + struct timespec *time) +{ + int status; + while(1) { + status = pthread_cond_timedwait(condId,mutexId,time); + if(status!=EINTR) return status; + } +} epicsEventId epicsEventCreate(epicsEventInitialState initialState) { @@ -82,7 +103,7 @@ void epicsEventSignal(epicsEventId pevent) { int status; - status = pthread_mutex_lock(&pevent->mutex); + status = mutexLock(&pevent->mutex); checkStatusQuit(status,"pthread_mutex_lock","epicsEventSignal"); if(!pevent->isFull) { pevent->isFull = 1; @@ -98,7 +119,7 @@ epicsEventWaitStatus epicsEventWait(epicsEventId pevent) int status; if(!pevent) return(epicsEventWaitError); - status = pthread_mutex_lock(&pevent->mutex); + status = mutexLock(&pevent->mutex); checkStatusQuit(status,"pthread_mutex_lock","epicsEventWait"); /*no need for while since caller must be prepared for no work*/ if(!pevent->isFull) { @@ -117,11 +138,11 @@ epicsEventWaitStatus epicsEventWaitWithTimeout(epicsEventId pevent, double timeo int status = 0; int unlockStatus; - status = pthread_mutex_lock(&pevent->mutex); + status = mutexLock(&pevent->mutex); checkStatusQuit(status,"pthread_mutex_lock","epicsEventWaitWithTimeout"); if(!pevent->isFull) { convertDoubleToWakeTime(timeout,&wakeTime); - status = pthread_cond_timedwait( + status = condTimedwait( &pevent->cond,&pevent->mutex,&wakeTime); } if(status==0) pevent->isFull = 0; diff --git a/src/libCom/osi/os/posix/osdMutex.c b/src/libCom/osi/os/posix/osdMutex.c index ea90d9156..4cad8a2cf 100644 --- a/src/libCom/osi/os/posix/osdMutex.c +++ b/src/libCom/osi/os/posix/osdMutex.c @@ -36,6 +36,17 @@ if(status) { \ cantProceed((method)); \ } +/* pthread_mutex_lock is NOT supposed to return EINTR but bad implementations*/ +static int mutexLock(pthread_mutex_t *id) +{ + int status; + + while(1) { + status = pthread_mutex_lock(id); + if(status!=EINTR) return status; + } +} + /* Until these can be demonstrated to work leave them undefined*/ /* On solaris 8 _POSIX_THREAD_PRIO_INHERIT fails*/ #undef _POSIX_THREAD_PROCESS_SHARED @@ -98,7 +109,7 @@ epicsMutexLockStatus epicsMutexOsdLock(struct epicsMutexOSD * pmutex) int status; if(!pmutex) return(epicsMutexLockError); - status = pthread_mutex_lock(&pmutex->lock); + status = mutexLock(&pmutex->lock); checkStatusQuit(status,"pthread_mutex_lock","epicsMutexOsdLock"); return(epicsMutexLockOK); } @@ -182,7 +193,7 @@ void epicsMutexOsdUnlock(struct epicsMutexOSD * pmutex) { int status; - status = pthread_mutex_lock(&pmutex->lock); + status = mutexLock(&pmutex->lock); checkStatusQuit(status,"pthread_mutex_lock","epicsMutexOsdUnlock"); if((pmutex->count<=0) || (pmutex->ownerTid != pthread_self())) { errlogPrintf("epicsMutexOsdUnlock but caller is not owner\n"); @@ -206,7 +217,7 @@ epicsMutexLockStatus epicsMutexOsdLock(struct epicsMutexOSD * pmutex) int status; if(!pmutex || !tid) return(epicsMutexLockError); - status = pthread_mutex_lock(&pmutex->lock); + status = mutexLock(&pmutex->lock); checkStatusQuit(status,"pthread_mutex_lock","epicsMutexOsdLock"); while(pmutex->owned && !pthread_equal(pmutex->ownerTid,tid)) pthread_cond_wait(&pmutex->waitToBeOwner,&pmutex->lock); @@ -224,7 +235,7 @@ epicsMutexLockStatus epicsMutexOsdTryLock(struct epicsMutexOSD * pmutex) epicsMutexLockStatus status; int pthreadStatus; - pthreadStatus = pthread_mutex_lock(&pmutex->lock); + pthreadStatus = mutexLock(&pmutex->lock); checkStatusQuit(pthreadStatus,"pthread_mutex_lock","epicsMutexOsdTryLock"); if(!pmutex->owned || pthread_equal(pmutex->ownerTid,tid)) { pmutex->ownerTid = tid; diff --git a/src/libCom/osi/os/posix/osdThread.c b/src/libCom/osi/os/posix/osdThread.c index 370a62698..9b9fdd9d6 100644 --- a/src/libCom/osi/os/posix/osdThread.c +++ b/src/libCom/osi/os/posix/osdThread.c @@ -35,6 +35,17 @@ #include "epicsAssert.h" #include "epicsExit.h" +/* pthread_mutex_lock is NOT supposed to return EINTR but bad implementations*/ +static int mutexLock(pthread_mutex_t *id) +{ + int status; + + while(1) { + status = pthread_mutex_lock(id); + if(status!=EINTR) return status; + } +} + /* Until this can be demonstrated to work leave it undefined*/ #undef _POSIX_THREAD_PRIORITY_SCHEDULING @@ -109,7 +120,7 @@ static void myAtExit(void) return; } epicsExitCallAtExits(); - status = pthread_mutex_lock(&listLock); + status = mutexLock(&listLock); checkStatusQuit(status,"pthread_mutex_lock","myAtExit"); pthreadSelf = (epicsThreadOSD *)pthread_getspecific(getpthreadInfo); if(pthreadSelf==NULL) @@ -201,7 +212,7 @@ static void free_threadInfo(epicsThreadOSD *pthreadInfo) { int status; - status = pthread_mutex_lock(&listLock); + status = mutexLock(&listLock); checkStatusQuit(status,"pthread_mutex_lock","free_threadInfo"); ellDelete(&pthreadList,&pthreadInfo->node); status = pthread_mutex_unlock(&listLock); @@ -258,7 +269,7 @@ static void once(void) pthreadInfo = init_threadInfo("_main_",0,epicsThreadGetStackSize(epicsThreadStackSmall),0,0); status = pthread_setspecific(getpthreadInfo,(void *)pthreadInfo); checkStatusOnceQuit(status,"pthread_setspecific","epicsThreadInit"); - status = pthread_mutex_lock(&listLock); + status = mutexLock(&listLock); checkStatusQuit(status,"pthread_mutex_lock","epicsThreadInit"); ellAdd(&pthreadList,&pthreadInfo->node); status = pthread_mutex_unlock(&listLock); @@ -281,7 +292,7 @@ static void * start_routine(void *arg) checkStatusQuit(status,"pthread_setspecific","start_routine"); status = pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS,&oldtype); checkStatusQuit(status,"pthread_setcanceltype","start_routine"); - status = pthread_mutex_lock(&listLock); + status = mutexLock(&listLock); checkStatusQuit(status,"pthread_mutex_lock","start_routine"); ellAdd(&pthreadList,&pthreadInfo->node); status = pthread_mutex_unlock(&listLock); @@ -332,7 +343,7 @@ void epicsThreadOnceOsd(epicsThreadOnceId *id, void (*func)(void *), void *arg) { int status; epicsThreadInit(); - status = pthread_mutex_lock(&onceLock); + status = mutexLock(&onceLock); if(status) { fprintf(stderr,"epicsThreadOnceOsd epicsMutexLock failed.\n"); exit(-1); @@ -567,7 +578,7 @@ epicsThreadId epicsThreadGetId(const char *name) { int status; assert(epicsThreadOnceCalled); - status = pthread_mutex_lock(&listLock); + status = mutexLock(&listLock); checkStatusQuit(status,"pthread_mutex_lock","epicsThreadGetId"); pthreadInfo=(epicsThreadOSD *)ellFirst(&pthreadList); while(pthreadInfo) { @@ -627,7 +638,7 @@ void epicsThreadShowAll(unsigned int level) epicsThreadInit(); epicsThreadShow(0,level); - status = pthread_mutex_lock(&listLock); + status = mutexLock(&listLock); checkStatusQuit(status,"pthread_mutex_lock","epicsThreadShowAll"); pthreadInfo=(epicsThreadOSD *)ellFirst(&pthreadList); while(pthreadInfo) { @@ -649,7 +660,7 @@ void epicsThreadShow(epicsThreadId showThread, unsigned int level) showThreadInfo(0,level); return; } - status = pthread_mutex_lock(&listLock); + status = mutexLock(&listLock); checkStatusQuit(status,"pthread_mutex_lock","epicsThreadShowAll"); pthreadInfo=(epicsThreadOSD *)ellFirst(&pthreadList); while(pthreadInfo) {