From f57acd2c106940533ec665ba26e06fa118f08808 Mon Sep 17 00:00:00 2001 From: Michael Davidsaver Date: Fri, 5 Nov 2021 11:01:55 -0700 Subject: [PATCH] add testdbCaWaitForConnect() --- modules/database/src/ioc/db/dbCa.c | 41 +++++++++++++++++++++++++----- modules/database/src/ioc/db/dbCa.h | 2 ++ 2 files changed, 36 insertions(+), 7 deletions(-) diff --git a/modules/database/src/ioc/db/dbCa.c b/modules/database/src/ioc/db/dbCa.c index c812b06a7..57cca404f 100644 --- a/modules/database/src/ioc/db/dbCa.c +++ b/modules/database/src/ioc/db/dbCa.c @@ -200,9 +200,13 @@ struct waitPvt { caLink *pca; epicsEventId evt; }; +enum testEvent { + testEventConnect, + testEventCount, +}; static -void testdbCaWaitForUpdateCountCB(void *raw) +void testdbCaWaitForEventCB(void *raw) { struct waitPvt *pvt = raw; @@ -211,29 +215,35 @@ void testdbCaWaitForUpdateCountCB(void *raw) epicsMutexUnlock(pvt->pca->lock); } -void testdbCaWaitForUpdateCount(DBLINK *plink, unsigned long cnt) +static +void testdbCaWaitForEvent(DBLINK *plink, unsigned long cnt, enum testEvent event) { - caLink *pca; epicsEventId evt = epicsEventMustCreate(epicsEventEmpty); dbScanLock(plink->precord); + assert(plink->type==CA_LINK); pca = (caLink *)plink->value.pv_link.pvt; - assert(plink->type==CA_LINK); epicsMutexMustLock(pca->lock); - assert(!pca->monitor && !pca->userPvt); + assert(!pca->monitor && !pca->connect && !pca->userPvt); - while(pca->nUpdate < cnt) { + while(!pca->isConnected || (event==testEventCount && pca->nUpdate < cnt)) { struct waitPvt pvt = {pca, evt}; - pca->monitor = &testdbCaWaitForUpdateCountCB; + pca->connect = &testdbCaWaitForEventCB; + pca->monitor = &testdbCaWaitForEventCB; pca->userPvt = &pvt; + epicsMutexUnlock(pca->lock); dbScanUnlock(plink->precord); + epicsEventMustWait(evt); + dbScanLock(plink->precord); epicsMutexMustLock(pca->lock); + + pca->connect = NULL; pca->monitor = NULL; pca->userPvt = NULL; } @@ -243,6 +253,16 @@ void testdbCaWaitForUpdateCount(DBLINK *plink, unsigned long cnt) dbScanUnlock(plink->precord); } +void testdbCaWaitForConnect(DBLINK *plink) +{ + testdbCaWaitForEvent(plink, 0, testEventConnect); +} + +void testdbCaWaitForUpdateCount(DBLINK *plink, unsigned long cnt) +{ + testdbCaWaitForEvent(plink, cnt, testEventCount); +} + /* Block until worker thread has processed all previously queued actions. * Does not prevent additional actions from being queued. */ @@ -816,6 +836,8 @@ static void connectionCallback(struct connection_handler_args arg) caLink *pca; short link_action = 0; struct link *plink; + dbCaCallback connect = 0; + void *userPvt = 0; pca = ca_puser(arg.chid); assert(pca); @@ -882,11 +904,16 @@ static void connectionCallback(struct connection_handler_args arg) } pca->gotAttributes = 0; if (pca->dbrType != DBR_STRING) { + /* will run connect() callback later */ link_action |= CA_GET_ATTRIBUTES; + } else { + connect = pca->connect; + userPvt = pca->userPvt; } done: if (link_action) addAction(pca, link_action); epicsMutexUnlock(pca->lock); + if (connect) connect(userPvt); } static void eventCallback(struct event_handler_args arg) diff --git a/modules/database/src/ioc/db/dbCa.h b/modules/database/src/ioc/db/dbCa.h index b3d1c3738..7b6f9c090 100644 --- a/modules/database/src/ioc/db/dbCa.h +++ b/modules/database/src/ioc/db/dbCa.h @@ -52,6 +52,8 @@ extern struct ca_client_context * dbCaClientContext; DBCORE_API void dbCaSync(void); /* Wait for the data update counter to reach the specified value. */ DBCORE_API void testdbCaWaitForUpdateCount(DBLINK *plink, unsigned long cnt); +/* Wait for CA link to become connected */ +DBCORE_API void testdbCaWaitForConnect(DBLINK *plink); #endif /* These macros are for backwards compatibility */