pthread_mutex_lock and pthread_cond_timedwait ignore EINTR
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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) {
|
||||
|
||||
Reference in New Issue
Block a user