fix testdbCaWaitForEvent()

sync with CA context thread(s) as well as dbCa worker.
This commit is contained in:
Michael Davidsaver
2025-10-17 16:18:43 -07:00
committed by mdavidsaver
parent bbc4c6358e
commit 71e4635d34
9 changed files with 57 additions and 5 deletions

View File

@@ -207,6 +207,7 @@ private:
cacChannel::priLev );
void flush (
epicsGuard < epicsMutex > & );
void sync ();
unsigned circuitCount (
epicsGuard < epicsMutex > & ) const;
void selfTest (

View File

@@ -209,9 +209,9 @@ void testdbCaWaitForEventCB(void *raw)
{
struct waitPvt *pvt = raw;
epicsMutexMustLock(pvt->pca->lock);
epicsMutexMustLock(workListLock);
epicsEventMustTrigger(pvt->evt);
epicsMutexUnlock(pvt->pca->lock);
epicsMutexUnlock(workListLock);
}
static
@@ -239,8 +239,6 @@ void testdbCaWaitForEvent(DBLINK *plink, unsigned long cnt, enum testEvent event
dbScanUnlock(plink->precord);
epicsEventMustWait(evt);
/* ensure worker has finished executing */
dbCaSync();
dbScanLock(plink->precord);
epicsMutexMustLock(pca->lock);
@@ -250,8 +248,15 @@ void testdbCaWaitForEvent(DBLINK *plink, unsigned long cnt, enum testEvent event
pca->userPvt = NULL;
}
epicsEventDestroy(evt);
epicsMutexUnlock(pca->lock);
/* ensure worker has finished executing */
dbCaSync();
epicsMutexMustLock(workListLock); /* lock to ensure that epicsEventMustTrigger() has returned */
epicsEventDestroy(evt);
epicsMutexUnlock(workListLock);
caLinkDec(pca);
dbScanUnlock(plink->precord);
}
@@ -266,6 +271,10 @@ void testdbCaWaitForUpdateCount(DBLINK *plink, unsigned long cnt)
testdbCaWaitForEvent(plink, cnt, testEventCount);
}
// private access to access.cpp
LIBCA_API
void dbCaSyncLocal(void);
/* Block until worker thread has processed all previously queued actions.
* Does not prevent additional actions from being queued.
*/
@@ -274,6 +283,8 @@ void dbCaSync(void)
epicsEventId wake;
caLink templink;
dbCaSyncLocal();
/* we only partially initialize templink.
* It has no link field and no subscription
* so the worker must handle it early

View File

@@ -399,6 +399,23 @@ void dbContext::flush (
}
}
static
void dbContextDummyExtraLabor(void *) {}
void dbContext::sync()
{
// ctx created lazily on first subscription
{
epicsGuard<epicsMutex> G(mutex);
if(!ctx)
return;
}
// assumes dbContext makes no other use of extra labor
db_add_extra_labor_event(ctx, dbContextDummyExtraLabor, NULL);
db_post_extra_labor(ctx);
db_flush_extra_labor_event(ctx);
}
unsigned dbContext::circuitCount (
epicsGuard < epicsMutex > & guard ) const
{