Return epicsMutexLockError rather than calling cantProceed() if the

pthread_mutex_ functions return EINVAL.
This commit is contained in:
Andrew Johnson
2009-03-03 18:00:49 +00:00
parent 33b4942ae2
commit aadbf07647

View File

@@ -41,11 +41,10 @@ static int mutexLock(pthread_mutex_t *id)
{
int status;
while(1) {
status = pthread_mutex_lock(id);
if(status!=EINTR) return status;
while ((status = pthread_mutex_lock(id)) == EINTR) {
errlogPrintf("pthread_mutex_lock returned EINTR. Violates SUSv3\n");
}
return status;
}
/* Until these can be demonstrated to work leave them undefined*/
@@ -64,36 +63,40 @@ static int mutexLock(pthread_mutex_t *id)
#if defined(_XOPEN_SOURCE) && (_XOPEN_SOURCE)>=500
typedef struct epicsMutexOSD {
pthread_mutexattr_t mutexAttr;
pthread_mutex_t lock;
}epicsMutexOSD;
pthread_mutex_t lock;
} epicsMutexOSD;
epicsMutexOSD * epicsMutexOsdCreate(void) {
epicsMutexOSD *pmutex;
int status;
int status;
pmutex = callocMustSucceed(1,sizeof(*pmutex),"epicsMutexOsdCreate");
pmutex = callocMustSucceed(1, sizeof(*pmutex), "epicsMutexOsdCreate");
status = pthread_mutexattr_init(&pmutex->mutexAttr);
checkStatusQuit(status,"pthread_mutexattr_init","epicsMutexOsdCreate");
checkStatusQuit(status,"pthread_mutexattr_init", "epicsMutexOsdCreate");
#if defined _POSIX_THREAD_PRIO_INHERIT
status = pthread_mutexattr_setprotocol(
&pmutex->mutexAttr,PTHREAD_PRIO_INHERIT);
if(errVerbose) checkStatus(status,"pthread_mutexattr_setprotocal");
status = pthread_mutexattr_setprotocol(&pmutex->mutexAttr,
PTHREAD_PRIO_INHERIT);
if (errVerbose) checkStatus(status, "pthread_mutexattr_setprotocal");
#endif /*_POSIX_THREAD_PRIO_INHERIT*/
status = pthread_mutexattr_settype(&pmutex->mutexAttr,PTHREAD_MUTEX_RECURSIVE);
if(errVerbose) checkStatus(status,"pthread_mutexattr_settype");
status = pthread_mutex_init(&pmutex->lock,&pmutex->mutexAttr);
checkStatusQuit(status,"pthread_mutex_init","epicsMutexOsdCreate");
return(pmutex);
status = pthread_mutexattr_settype(&pmutex->mutexAttr,
PTHREAD_MUTEX_RECURSIVE);
if (errVerbose) checkStatus(status, "pthread_mutexattr_settype");
status = pthread_mutex_init(&pmutex->lock, &pmutex->mutexAttr);
checkStatusQuit(status, "pthread_mutex_init", "epicsMutexOsdCreate");
return pmutex;
}
void epicsMutexOsdDestroy(struct epicsMutexOSD * pmutex)
{
int status;
int status;
status = pthread_mutex_destroy(&pmutex->lock);
checkStatus(status,"pthread_mutex_destroy");
checkStatus(status, "pthread_mutex_destroy");
status = pthread_mutexattr_destroy(&pmutex->mutexAttr);
checkStatus(status,"pthread_mutexattr_destroy");
checkStatus(status, "pthread_mutexattr_destroy");
free(pmutex);
}
@@ -102,33 +105,33 @@ void epicsMutexOsdUnlock(struct epicsMutexOSD * pmutex)
int status;
status = pthread_mutex_unlock(&pmutex->lock);
checkStatusQuit(status,"pthread_mutex_unlock","epicsMutexOsdUnlock");
checkStatusQuit(status, "pthread_mutex_unlock", "epicsMutexOsdUnlock");
}
epicsMutexLockStatus epicsMutexOsdLock(struct epicsMutexOSD * pmutex)
{
int status;
if(!pmutex) return(epicsMutexLockError);
if (!pmutex) return epicsMutexLockError;
status = mutexLock(&pmutex->lock);
checkStatusQuit(status,"pthread_mutex_lock","epicsMutexOsdLock");
return(epicsMutexLockOK);
if (status == EINVAL) return epicsMutexLockError;
checkStatusQuit(status, "pthread_mutex_lock", "epicsMutexOsdLock");
return epicsMutexLockOK;
}
epicsMutexLockStatus epicsMutexOsdTryLock(struct epicsMutexOSD * pmutex)
{
int pthreadStatus;
int status;
if(!pmutex) return(epicsMutexLockError);
pthreadStatus = pthread_mutex_trylock(&pmutex->lock);
if(pthreadStatus!=0) {
if(pthreadStatus==EBUSY) return(epicsMutexLockTimeout);
checkStatusQuit(pthreadStatus,"pthread_mutex_lock","epicsMutexOsdTryLock");
}
return(epicsMutexLockOK);
if (!pmutex) return epicsMutexLockError;
status = pthread_mutex_trylock(&pmutex->lock);
if (status == EINVAL) return epicsMutexLockError;
if (status == EBUSY) return epicsMutexLockTimeout;
checkStatusQuit(status, "pthread_mutex_lock", "epicsMutexOsdTryLock");
return epicsMutexLockOK;
}
void epicsMutexOsdShow(struct epicsMutexOSD * pmutex,unsigned int level)
void epicsMutexOsdShow(struct epicsMutexOSD * pmutex, unsigned int level)
{
}
@@ -144,34 +147,37 @@ typedef struct epicsMutexOSD {
int count;
int owned; /* TRUE | FALSE */
pthread_t ownerTid;
}epicsMutexOSD;
} epicsMutexOSD;
epicsMutexOSD * epicsMutexOsdCreate(void) {
epicsMutexOSD *pmutex;
int status;
pmutex = callocMustSucceed(1,sizeof(*pmutex),"epicsMutexOsdCreate");
pmutex = callocMustSucceed(1, sizeof(*pmutex), "epicsMutexOsdCreate");
status = pthread_mutexattr_init(&pmutex->mutexAttr);
checkStatusQuit(status,"pthread_mutexattr_init","epicsMutexOsdCreate");
checkStatusQuit(status, "pthread_mutexattr_init", "epicsMutexOsdCreate");
#if defined _POSIX_THREAD_PRIO_INHERIT
status = pthread_mutexattr_setprotocol(
&pmutex->mutexAttr,PTHREAD_PRIO_INHERIT);
if(errVerbose) checkStatus(status,"pthread_mutexattr_setprotocal");
if (errVerbose) checkStatus(status, "pthread_mutexattr_setprotocal");
#endif /*_POSIX_THREAD_PRIO_INHERIT*/
status = pthread_mutex_init(&pmutex->lock,&pmutex->mutexAttr);
checkStatusQuit(status,"pthread_mutex_init","epicsMutexOsdCreate");
status = pthread_mutex_init(&pmutex->lock, &pmutex->mutexAttr);
checkStatusQuit(status, "pthread_mutex_init", "epicsMutexOsdCreate");
#if defined _POSIX_THREAD_PROCESS_SHARED
status = pthread_condattr_init(&pmutex->condAttr);
checkStatus(status,"pthread_condattr_init");
checkStatus(status, "pthread_condattr_init");
status = pthread_condattr_setpshared(&pmutex->condAttr,
PTHREAD_PROCESS_PRIVATE);
checkStatus(status,"pthread_condattr_setpshared");
status = pthread_cond_init(&pmutex->waitToBeOwner,&pmutex->condAttr);
checkStatus(status, "pthread_condattr_setpshared");
status = pthread_cond_init(&pmutex->waitToBeOwner, &pmutex->condAttr);
#else
status = pthread_cond_init(&pmutex->waitToBeOwner,0);
status = pthread_cond_init(&pmutex->waitToBeOwner, 0);
#endif /*_POSIX_THREAD_PROCESS_SHARED*/
checkStatusQuit(status,"pthread_cond_init","epicsMutexOsdCreate");
return(pmutex);
checkStatusQuit(status, "pthread_cond_init", "epicsMutexOsdCreate");
return pmutex;
}
void epicsMutexOsdDestroy(struct epicsMutexOSD * pmutex)
@@ -179,14 +185,14 @@ void epicsMutexOsdDestroy(struct epicsMutexOSD * pmutex)
int status;
status = pthread_cond_destroy(&pmutex->waitToBeOwner);
checkStatus(status,"pthread_cond_destroy");
checkStatus(status, "pthread_cond_destroy");
#if defined _POSIX_THREAD_PROCESS_SHARED
status = pthread_condattr_destroy(&pmutex->condAttr);
#endif /*_POSIX_THREAD_PROCESS_SHARED*/
status = pthread_mutex_destroy(&pmutex->lock);
checkStatus(status,"pthread_mutex_destroy");
checkStatus(status, "pthread_mutex_destroy");
status = pthread_mutexattr_destroy(&pmutex->mutexAttr);
checkStatus(status,"pthread_mutexattr_destroy");
checkStatus(status, "pthread_mutexattr_destroy");
free(pmutex);
}
@@ -195,31 +201,34 @@ void epicsMutexOsdUnlock(struct epicsMutexOSD * pmutex)
int status;
status = mutexLock(&pmutex->lock);
checkStatusQuit(status,"pthread_mutex_lock","epicsMutexOsdUnlock");
if((pmutex->count<=0) || (pmutex->ownerTid != pthread_self())) {
checkStatusQuit(status, "pthread_mutex_lock", "epicsMutexOsdUnlock");
if ((pmutex->count <= 0) || (pmutex->ownerTid != pthread_self())) {
errlogPrintf("epicsMutexOsdUnlock but caller is not owner\n");
status = pthread_mutex_unlock(&pmutex->lock);
checkStatusQuit(status,"pthread_mutex_unlock","epicsMutexOsdUnlock");
checkStatusQuit(status, "pthread_mutex_unlock", "epicsMutexOsdUnlock");
return;
}
pmutex->count--;
if(pmutex->count == 0) {
if (pmutex->count == 0) {
pmutex->owned = 0;
pmutex->ownerTid = 0;
pthread_cond_signal(&pmutex->waitToBeOwner);
}
status = pthread_mutex_unlock(&pmutex->lock);
checkStatusQuit(status,"pthread_mutex_unlock","epicsMutexOsdUnlock");
checkStatusQuit(status, "pthread_mutex_unlock", "epicsMutexOsdUnlock");
}
static int condWait(pthread_cond_t *condId, pthread_mutex_t *mutexId)
{
int status;
while(1) {
status = pthread_cond_wait(condId,mutexId);
if(status!=EINTR) return status;
while ((status = pthread_cond_wait(condId, mutexId)) == EINTR) {
errlogPrintf("pthread_cond_wait returned EINTR. Violates SUSv3\n");
}
return status;
}
epicsMutexLockStatus epicsMutexOsdLock(struct epicsMutexOSD * pmutex)
@@ -227,44 +236,49 @@ epicsMutexLockStatus epicsMutexOsdLock(struct epicsMutexOSD * pmutex)
pthread_t tid = pthread_self();
int status;
if(!pmutex || !tid) return(epicsMutexLockError);
if (!pmutex || !tid) return epicsMutexLockError;
status = mutexLock(&pmutex->lock);
checkStatusQuit(status,"pthread_mutex_lock","epicsMutexOsdLock");
while(pmutex->owned && !pthread_equal(pmutex->ownerTid,tid))
condWait(&pmutex->waitToBeOwner,&pmutex->lock);
if (status == EINVAL) return epicsMutexLockError;
checkStatusQuit(status, "pthread_mutex_lock", "epicsMutexOsdLock");
while (pmutex->owned && !pthread_equal(pmutex->ownerTid, tid))
condWait(&pmutex->waitToBeOwner, &pmutex->lock);
pmutex->ownerTid = tid;
pmutex->owned = 1;
pmutex->count++;
status = pthread_mutex_unlock(&pmutex->lock);
checkStatusQuit(status,"pthread_mutex_unlock","epicsMutexOsdLock");
return(epicsMutexLockOK);
checkStatusQuit(status, "pthread_mutex_unlock", "epicsMutexOsdLock");
return epicsMutexLockOK;
}
epicsMutexLockStatus epicsMutexOsdTryLock(struct epicsMutexOSD * pmutex)
{
pthread_t tid = pthread_self();
epicsMutexLockStatus status;
int pthreadStatus;
epicsMutexLockStatus result;
int status;
pthreadStatus = mutexLock(&pmutex->lock);
checkStatusQuit(pthreadStatus,"pthread_mutex_lock","epicsMutexOsdTryLock");
if(!pmutex->owned || pthread_equal(pmutex->ownerTid,tid)) {
status = mutexLock(&pmutex->lock);
if (status == EINVAL) return epicsMutexLockError;
checkStatusQuit(status, "pthread_mutex_lock", "epicsMutexOsdTryLock");
if (!pmutex->owned || pthread_equal(pmutex->ownerTid, tid)) {
pmutex->ownerTid = tid;
pmutex->owned = 1;
pmutex->count++;
status = epicsMutexLockOK;
result = epicsMutexLockOK;
} else {
result = epicsMutexLockTimeout;
}
else {
status = epicsMutexLockTimeout;
}
pthreadStatus = pthread_mutex_unlock(&pmutex->lock);
checkStatusQuit(pthreadStatus,"pthread_mutex_unlock","epicsMutexOsdTryLock");
return(status);
status = pthread_mutex_unlock(&pmutex->lock);
checkStatusQuit(status, "pthread_mutex_unlock", "epicsMutexOsdTryLock");
return result;
}
void epicsMutexOsdShow(struct epicsMutexOSD *pmutex,unsigned int level)
{
printf("ownerTid %p count %d owned %d\n",
(void *)pmutex->ownerTid,pmutex->count,pmutex->owned);
(void *)pmutex->ownerTid, pmutex->count, pmutex->owned);
}
#endif /*defined(_XOPEN_SOURCE) && (_XOPEN_SOURCE)>=500 */