ioc/db: avoid possible race in db_close_events()

lp:1730982
This commit is contained in:
Michael Davidsaver
2017-11-08 13:51:08 -06:00
parent e38252eecc
commit e794639e31
+19
View File
@@ -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;
} }