Revert "dbEvent simplify db_close_events() with join"
This reverts commit 37a76b433a.
# Conflicts:
# modules/database/src/ioc/db/dbEvent.c
This commit is contained in:
@@ -84,6 +84,7 @@ struct event_user {
|
||||
epicsMutexId lock;
|
||||
epicsEventId ppendsem; /* Wait while empty */
|
||||
epicsEventId pflush_sem; /* wait for flush */
|
||||
epicsEventId pexitsem; /* wait for event task to join */
|
||||
|
||||
EXTRALABORFUNC *extralabor_sub;/* off load to event task */
|
||||
void *extralabor_arg;/* parameter to above */
|
||||
@@ -122,6 +123,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 ) {
|
||||
@@ -260,6 +263,10 @@ int dbel ( const char *pname, unsigned level )
|
||||
*/
|
||||
void db_init_event_freelists (void)
|
||||
{
|
||||
if (!stopSync) {
|
||||
stopSync = epicsMutexMustCreate();
|
||||
}
|
||||
|
||||
if (!dbevEventUserFreeList) {
|
||||
freeListInitPvt(&dbevEventUserFreeList,
|
||||
sizeof(struct event_user),8);
|
||||
@@ -299,6 +306,9 @@ dbEventCtx db_init_events (void)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Flag will be cleared when event task starts */
|
||||
evUser->pendexit = TRUE;
|
||||
|
||||
evUser->firstque.evUser = evUser;
|
||||
evUser->firstque.writelock = epicsMutexCreate();
|
||||
if (!evUser->firstque.writelock)
|
||||
@@ -313,6 +323,9 @@ dbEventCtx db_init_events (void)
|
||||
evUser->lock = epicsMutexCreate();
|
||||
if (!evUser->lock)
|
||||
goto fail;
|
||||
evUser->pexitsem = epicsEventCreate(epicsEventEmpty);
|
||||
if (!evUser->pexitsem)
|
||||
goto fail;
|
||||
|
||||
evUser->flowCtrlMode = FALSE;
|
||||
evUser->extraLaborBusy = FALSE;
|
||||
@@ -327,6 +340,8 @@ fail:
|
||||
epicsEventDestroy (evUser->ppendsem);
|
||||
if(evUser->pflush_sem)
|
||||
epicsEventDestroy (evUser->pflush_sem);
|
||||
if(evUser->pexitsem)
|
||||
epicsEventDestroy (evUser->pexitsem);
|
||||
freeListFree(dbevEventUserFreeList,evUser);
|
||||
return NULL;
|
||||
}
|
||||
@@ -347,6 +362,7 @@ DBCORE_API void db_cleanup_events(void)
|
||||
dbevFieldLogFreeList = NULL;
|
||||
}
|
||||
|
||||
/* intentionally leak stopSync to avoid possible shutdown races */
|
||||
/*
|
||||
* DB_CLOSE_EVENTS()
|
||||
*
|
||||
@@ -368,15 +384,30 @@ void db_close_events (dbEventCtx ctx)
|
||||
* hazardous to the system's health.
|
||||
*/
|
||||
epicsMutexMustLock ( evUser->lock );
|
||||
evUser->pendexit = TRUE;
|
||||
if(!evUser->pendexit) { /* event task running */
|
||||
evUser->pendexit = TRUE;
|
||||
epicsMutexUnlock ( evUser->lock );
|
||||
|
||||
/* notify the waiting task */
|
||||
epicsEventSignal(evUser->ppendsem);
|
||||
/* wait for task to exit */
|
||||
epicsEventMustWait(evUser->pexitsem);
|
||||
|
||||
epicsMutexMustLock ( evUser->lock );
|
||||
}
|
||||
|
||||
epicsMutexUnlock ( evUser->lock );
|
||||
|
||||
/* notify the waiting task */
|
||||
epicsEventSignal(evUser->ppendsem);
|
||||
epicsMutexMustLock (stopSync);
|
||||
|
||||
if(evUser->taskid)
|
||||
epicsThreadMustJoin(evUser->taskid);
|
||||
/* evUser has been deleted by the worker */
|
||||
epicsEventDestroy(evUser->pexitsem);
|
||||
epicsEventDestroy(evUser->ppendsem);
|
||||
epicsEventDestroy(evUser->pflush_sem);
|
||||
epicsMutexDestroy(evUser->lock);
|
||||
|
||||
epicsMutexUnlock (stopSync);
|
||||
|
||||
freeListFree(dbevEventUserFreeList, evUser);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1063,18 +1094,17 @@ static void event_task (void *pParm)
|
||||
}
|
||||
}
|
||||
|
||||
epicsEventDestroy(evUser->ppendsem);
|
||||
epicsEventDestroy(evUser->pflush_sem);
|
||||
epicsMutexDestroy(evUser->lock);
|
||||
|
||||
if (dbevEventUserFreeList)
|
||||
freeListFree(dbevEventUserFreeList, evUser);
|
||||
else
|
||||
fprintf(stderr, "%s exiting but dbevEventUserFreeList already NULL\n",
|
||||
__FUNCTION__);
|
||||
|
||||
taskwdRemove(epicsThreadGetIdSelf());
|
||||
|
||||
/* use stopSync to ensure pexitsem is not destroy'd
|
||||
* until epicsEventSignal() has returned.
|
||||
*/
|
||||
epicsMutexMustLock (stopSync);
|
||||
|
||||
epicsEventSignal(evUser->pexitsem);
|
||||
|
||||
epicsMutexUnlock(stopSync);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1086,11 +1116,6 @@ int db_start_events (
|
||||
void *init_func_arg, unsigned osiPriority )
|
||||
{
|
||||
struct event_user * const evUser = (struct event_user *) ctx;
|
||||
epicsThreadOpts opts = EPICS_THREAD_OPTS_INIT;
|
||||
|
||||
opts.stackSize = epicsThreadGetStackSize(epicsThreadStackMedium);
|
||||
opts.priority = osiPriority;
|
||||
opts.joinable = 1;
|
||||
|
||||
epicsMutexMustLock ( evUser->lock );
|
||||
|
||||
@@ -1108,12 +1133,15 @@ int db_start_events (
|
||||
if (!taskname) {
|
||||
taskname = EVENT_PEND_NAME;
|
||||
}
|
||||
evUser->taskid = epicsThreadCreateOpt (
|
||||
taskname, event_task, (void *)evUser, &opts);
|
||||
evUser->taskid = epicsThreadCreate (
|
||||
taskname, osiPriority,
|
||||
epicsThreadGetStackSize(epicsThreadStackMedium),
|
||||
event_task, (void *)evUser);
|
||||
if (!evUser->taskid) {
|
||||
epicsMutexUnlock ( evUser->lock );
|
||||
return DB_EVENT_ERROR;
|
||||
}
|
||||
evUser->pendexit = FALSE;
|
||||
epicsMutexUnlock ( evUser->lock );
|
||||
return DB_EVENT_OK;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user