diff --git a/src/ioc/db/dbEvent.c b/src/ioc/db/dbEvent.c index e6de60606..9304f99b2 100644 --- a/src/ioc/db/dbEvent.c +++ b/src/ioc/db/dbEvent.c @@ -117,6 +117,8 @@ static char *EVENT_PEND_NAME = "eventTask"; static struct evSubscrip canceledEvent; +static epicsMutexId stopSync; + static unsigned short ringSpace ( const struct event_que *pevq ) { if ( pevq->evque[pevq->putix] == EVENTQEMPTY ) { @@ -258,6 +260,10 @@ dbEventCtx db_init_events (void) { struct event_user * evUser; + if (!stopSync) { + stopSync = epicsMutexMustCreate(); + } + if (!dbevEventUserFreeList) { freeListInitPvt(&dbevEventUserFreeList, sizeof(struct event_user),8); @@ -337,6 +343,7 @@ epicsShareFunc void db_cleanup_events(void) dbevFieldLogFreeList = NULL; } + /* intentionally leak stopSync to avoid possible shutdown races */ /* * DB_CLOSE_EVENTS() * @@ -372,11 +379,15 @@ void db_close_events (dbEventCtx ctx) epicsMutexUnlock ( evUser->lock ); + epicsMutexMustLock (stopSync); + epicsEventDestroy(evUser->pexitsem); epicsEventDestroy(evUser->ppendsem); epicsEventDestroy(evUser->pflush_sem); epicsMutexDestroy(evUser->lock); + epicsMutexUnlock (stopSync); + freeListFree(dbevEventUserFreeList, evUser); } @@ -1059,8 +1070,15 @@ static void event_task (void *pParm) taskwdRemove(epicsThreadGetIdSelf()); + /* use stopSync to ensure pexitsem is not destroy'd + * until epicsEventSignal() has returned. + */ + epicsMutexMustLock (stopSync); + epicsEventSignal(evUser->pexitsem); + epicsMutexUnlock(stopSync); + return; } diff --git a/src/std/rec/aSubRecord.c b/src/std/rec/aSubRecord.c index b513df17a..b7d2286b6 100644 --- a/src/std/rec/aSubRecord.c +++ b/src/std/rec/aSubRecord.c @@ -159,6 +159,14 @@ static long init_record(struct dbCommon *pcommon, int pass) } strcpy(prec->onam, prec->snam); prec->oval = prec->val; + for (i = 0; i < NUM_ARGS; i++) { + epicsUInt32 nev = (&prec->neva)[i]; + + (&prec->onva)[i] = nev; + if (nev) + memcpy((&prec->ovla)[i], (&prec->vala)[i], + dbValueSize((&prec->ftva)[i]) * nev); + } return 0; }