ioc/db: avoid possible race in db_close_events()
lp:1730982
This commit is contained in:
@@ -117,6 +117,8 @@ static char *EVENT_PEND_NAME = "eventTask";
|
|||||||
|
|
||||||
static struct evSubscrip canceledEvent;
|
static struct evSubscrip canceledEvent;
|
||||||
|
|
||||||
|
static epicsMutexId stopSync;
|
||||||
|
|
||||||
static unsigned short ringSpace ( const struct event_que *pevq )
|
static unsigned short ringSpace ( const struct event_que *pevq )
|
||||||
{
|
{
|
||||||
if ( pevq->evque[pevq->putix] == EVENTQEMPTY ) {
|
if ( pevq->evque[pevq->putix] == EVENTQEMPTY ) {
|
||||||
@@ -258,6 +260,10 @@ dbEventCtx db_init_events (void)
|
|||||||
{
|
{
|
||||||
struct event_user * evUser;
|
struct event_user * evUser;
|
||||||
|
|
||||||
|
if (!stopSync) {
|
||||||
|
stopSync = epicsMutexMustCreate();
|
||||||
|
}
|
||||||
|
|
||||||
if (!dbevEventUserFreeList) {
|
if (!dbevEventUserFreeList) {
|
||||||
freeListInitPvt(&dbevEventUserFreeList,
|
freeListInitPvt(&dbevEventUserFreeList,
|
||||||
sizeof(struct event_user),8);
|
sizeof(struct event_user),8);
|
||||||
@@ -321,6 +327,8 @@ fail:
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* intentionally leak stopSync to avoid possible shutdown races */
|
||||||
/*
|
/*
|
||||||
* DB_CLOSE_EVENTS()
|
* DB_CLOSE_EVENTS()
|
||||||
*
|
*
|
||||||
@@ -356,11 +364,15 @@ void db_close_events (dbEventCtx ctx)
|
|||||||
|
|
||||||
epicsMutexUnlock ( evUser->lock );
|
epicsMutexUnlock ( evUser->lock );
|
||||||
|
|
||||||
|
epicsMutexMustLock (stopSync);
|
||||||
|
|
||||||
epicsEventDestroy(evUser->pexitsem);
|
epicsEventDestroy(evUser->pexitsem);
|
||||||
epicsEventDestroy(evUser->ppendsem);
|
epicsEventDestroy(evUser->ppendsem);
|
||||||
epicsEventDestroy(evUser->pflush_sem);
|
epicsEventDestroy(evUser->pflush_sem);
|
||||||
epicsMutexDestroy(evUser->lock);
|
epicsMutexDestroy(evUser->lock);
|
||||||
|
|
||||||
|
epicsMutexUnlock (stopSync);
|
||||||
|
|
||||||
freeListFree(dbevEventUserFreeList, evUser);
|
freeListFree(dbevEventUserFreeList, evUser);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1043,8 +1055,15 @@ static void event_task (void *pParm)
|
|||||||
|
|
||||||
taskwdRemove(epicsThreadGetIdSelf());
|
taskwdRemove(epicsThreadGetIdSelf());
|
||||||
|
|
||||||
|
/* use stopSync to ensure pexitsem is not destroy'd
|
||||||
|
* until epicsEventSignal() has returned.
|
||||||
|
*/
|
||||||
|
epicsMutexMustLock (stopSync);
|
||||||
|
|
||||||
epicsEventSignal(evUser->pexitsem);
|
epicsEventSignal(evUser->pexitsem);
|
||||||
|
|
||||||
|
epicsMutexUnlock(stopSync);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user