Merge remote-tracking branch 'origin/3.15' into 7.0

* origin/3.15: (40 commits)
  Revert "More msi.plt retries for Jenkins builds on Windows"
  Revert "Testing msi: Add retries if necessary"
  msi: Flush stdout on program exit
  Now fix the non-windows systems
  Don't use / in Windows program paths
  Redirect msi's STDERR to /dev/null (NUL on Windows) during tests
  VxWorks: Mark undetected underflow parse test as ToDo
  Fix VxWorks osiSockOptMcastLoop_t => char
  Fix sync filter example in dbd.pod
  doc/ca: clarify variable size array subscription
  Remove cacExitHandler
  Don't clear caClientCallbackThreadId in CA's exit handler
  appveyor-ci: ANL Make install 4.1 -> 4.2.1
  appveyor-ci: use pre-installed AppVeyor MinGW
  appveyor-ci: use choco MinGW 5.3.0 to work around build problem (fixes lp:1827225)
  appveyor-ci: exclude some cygwin builds (broken compiler) appveyor-ci: remove slack, add email and GitHub notifications (cherry-picked from branch 7.0)
  epicsTime: rely on implicit copy constructor
  iocLogServer: check return values
  Fix potential buffer overflow in iocLogServer
  Fix weird use of strncpy
  ...

# Conflicts:
#	modules/database/src/ioc/dbtemplate/msi.c
#	modules/database/src/std/rec/stringinRecord.c
#	modules/database/src/std/rec/stringoutRecord.c
#	modules/database/test/ioc/dbtemplate/msi.plt
#	modules/libcom/src/osi/os/vxWorks/osdSock.h
#	src/ioc/dbtemplate/msi.c
#	src/ioc/dbtemplate/msi.cpp
This commit is contained in:
Michael Davidsaver
2019-08-31 15:05:37 -07:00
18 changed files with 914 additions and 210 deletions
+13 -8
View File
@@ -229,20 +229,23 @@ static void asCaTask(void)
void asCaStart(void)
{
epicsThreadOpts opts = EPICS_THREAD_OPTS_INIT;
opts.stackSize = epicsThreadGetStackSize(epicsThreadStackBig);
opts.priority = epicsThreadPriorityScanLow - 3;
opts.joinable = 1;
if(asCaDebug) printf("asCaStart called\n");
if(firstTime) {
firstTime = FALSE;
firstTime = FALSE;
asCaTaskLock=epicsMutexMustCreate();
asCaTaskWait=epicsEventMustCreate(epicsEventEmpty);
asCaTaskAddChannels=epicsEventMustCreate(epicsEventEmpty);
asCaTaskClearChannels=epicsEventMustCreate(epicsEventEmpty);
threadid = epicsThreadCreate("asCaTask",
(epicsThreadPriorityScanLow - 3),
epicsThreadGetStackSize(epicsThreadStackBig),
(EPICSTHREADFUNC)asCaTask,0);
if(threadid==0) {
errMessage(0,"asCaStart: taskSpawn Failure\n");
}
threadid = epicsThreadCreateOpt("asCaTask", (EPICSTHREADFUNC)asCaTask, 0, &opts);
if(threadid==0) {
errMessage(0,"asCaStart: taskSpawn Failure\n");
}
}
epicsMutexMustLock(asCaTaskLock);
epicsEventSignal(asCaTaskAddChannels);
@@ -260,6 +263,8 @@ void asCaStop(void)
epicsEventMustWait(asCaTaskWait);
if(asCaDebug) printf("asCaStop done\n");
epicsMutexUnlock(asCaTaskLock);
epicsThreadMustJoin(threadid);
threadid = 0;
}
int ascar(int level) { return ascarFP(stdout,level);}
+11 -3
View File
@@ -68,6 +68,7 @@ static volatile enum dbCaCtl_t {
ctlInit, ctlRun, ctlPause, ctlExit
} dbCaCtl;
static epicsEventId startStopEvent;
static epicsThreadId dbCaWorker;
struct ca_client_context * dbCaClientContext;
@@ -258,10 +259,18 @@ void dbCaShutdown(void)
dbCaCtl = ctlExit;
epicsEventSignal(workListEvent);
epicsEventMustWait(startStopEvent);
if(dbCaWorker)
epicsThreadMustJoin(dbCaWorker);
}
static void dbCaLinkInitImpl(int isolate)
{
epicsThreadOpts opts = EPICS_THREAD_OPTS_INIT;
opts.stackSize = epicsThreadGetStackSize(epicsThreadStackBig);
opts.priority = epicsThreadPriorityMedium;
opts.joinable = 1;
dbServiceIsolate = isolate;
dbServiceIOInit();
@@ -274,9 +283,8 @@ static void dbCaLinkInitImpl(int isolate)
startStopEvent = epicsEventMustCreate(epicsEventEmpty);
dbCaCtl = ctlPause;
epicsThreadCreate("dbCaLink", epicsThreadPriorityMedium,
epicsThreadGetStackSize(epicsThreadStackBig),
dbCaTask, NULL);
dbCaWorker = epicsThreadCreateOpt("dbCaLink", dbCaTask, NULL, &opts);
/* wait for worker to startup and initialize dbCaClientContext */
epicsEventMustWait(startStopEvent);
}
+19 -51
View File
@@ -84,7 +84,6 @@ 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 */
@@ -123,8 +122,6 @@ 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 ) {
@@ -266,10 +263,6 @@ dbEventCtx db_init_events (void)
{
struct event_user * evUser;
if (!stopSync) {
stopSync = epicsMutexMustCreate();
}
if (!dbevEventUserFreeList) {
freeListInitPvt(&dbevEventUserFreeList,
sizeof(struct event_user),8);
@@ -293,9 +286,6 @@ 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)
@@ -310,9 +300,6 @@ 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,8 +314,6 @@ fail:
epicsEventDestroy (evUser->ppendsem);
if(evUser->pflush_sem)
epicsEventDestroy (evUser->pflush_sem);
if(evUser->pexitsem)
epicsEventDestroy (evUser->pexitsem);
freeListFree(dbevEventUserFreeList,evUser);
return NULL;
}
@@ -349,7 +334,6 @@ epicsShareFunc void db_cleanup_events(void)
dbevFieldLogFreeList = NULL;
}
/* intentionally leak stopSync to avoid possible shutdown races */
/*
* DB_CLOSE_EVENTS()
*
@@ -371,30 +355,15 @@ void db_close_events (dbEventCtx ctx)
* hazardous to the system's health.
*/
epicsMutexMustLock ( evUser->lock );
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 );
}
evUser->pendexit = TRUE;
epicsMutexUnlock ( evUser->lock );
epicsMutexMustLock (stopSync);
/* notify the waiting task */
epicsEventSignal(evUser->ppendsem);
epicsEventDestroy(evUser->pexitsem);
epicsEventDestroy(evUser->ppendsem);
epicsEventDestroy(evUser->pflush_sem);
epicsMutexDestroy(evUser->lock);
epicsMutexUnlock (stopSync);
freeListFree(dbevEventUserFreeList, evUser);
if(evUser->taskid)
epicsThreadMustJoin(evUser->taskid);
/* evUser has been deleted by the worker */
}
/*
@@ -1074,17 +1043,14 @@ static void event_task (void *pParm)
}
}
epicsEventDestroy(evUser->ppendsem);
epicsEventDestroy(evUser->pflush_sem);
epicsMutexDestroy(evUser->lock);
freeListFree(dbevEventUserFreeList, evUser);
taskwdRemove(epicsThreadGetIdSelf());
/* use stopSync to ensure pexitsem is not destroy'd
* until epicsEventSignal() has returned.
*/
epicsMutexMustLock (stopSync);
epicsEventSignal(evUser->pexitsem);
epicsMutexUnlock(stopSync);
return;
}
@@ -1096,6 +1062,11 @@ 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 );
@@ -1113,15 +1084,12 @@ int db_start_events (
if (!taskname) {
taskname = EVENT_PEND_NAME;
}
evUser->taskid = epicsThreadCreate (
taskname, osiPriority,
epicsThreadGetStackSize(epicsThreadStackMedium),
event_task, (void *)evUser);
evUser->taskid = epicsThreadCreateOpt (
taskname, event_task, (void *)evUser, &opts);
if (!evUser->taskid) {
epicsMutexUnlock ( evUser->lock );
return DB_EVENT_ERROR;
}
evUser->pendexit = FALSE;
epicsMutexUnlock ( evUser->lock );
return DB_EVENT_OK;
}