From d897c9b68616c11e3f431df1b9589059d61bb86c Mon Sep 17 00:00:00 2001 From: Michael Davidsaver Date: Mon, 5 Jan 2015 16:26:47 -0500 Subject: [PATCH] dbCa: use scanOnce3() to prevent once queue overflow Prevent CP links to high rate records from overflowing the once queue. --- src/ioc/db/dbCa.c | 31 ++++++++++++++++++++++++++++--- src/ioc/db/dbCaPvt.h | 1 + 2 files changed, 29 insertions(+), 3 deletions(-) diff --git a/src/ioc/db/dbCa.c b/src/ioc/db/dbCa.c index e3ce5efac..2e1bf2ebf 100644 --- a/src/ioc/db/dbCa.c +++ b/src/ioc/db/dbCa.c @@ -629,6 +629,31 @@ long dbCaGetUnits(const struct link *plink, return gotAttributes ? 0 : -1; } +static void scanComplete(void *raw, dbCommon *prec) +{ + caLink *pca = raw; + epicsMutexMustLock(pca->lock); + if(pca->scanningOnce==0) + errlogPrintf("dbCa.c complete callback w/ scanningOnce==0\n"); + else if(--pca->scanningOnce){ + /* another scan is queued */ + if(scanOnce3(prec, scanComplete, raw)) { + errlogPrintf("dbCa.c failed to re-queue scanOnce\n"); + } + } + epicsMutexUnlock(pca->lock); +} + +/* must be called with pca->lock held */ +static void scanLinkOnce(dbCommon *prec, caLink *pca) { + if(pca->scanningOnce==0 && scanOnce3(prec, scanComplete, pca)) { + errlogPrintf("dbCa.c failed to queue scanOnce\n"); + } + if(pca->scanningOnce<5) + pca->scanningOnce++; + /* else too many scans queued */ +} + static void connectionCallback(struct connection_handler_args arg) { caLink *pca; @@ -649,7 +674,7 @@ static void connectionCallback(struct connection_handler_args arg) if (precord && ((ppv_link->pvlMask & pvlOptCP) || ((ppv_link->pvlMask & pvlOptCPP) && precord->scan == 0))) - scanOnce(precord); + scanLinkOnce(precord, pca); goto done; } pca->hasReadAccess = ca_read_access(arg.chid); @@ -762,7 +787,7 @@ static void eventCallback(struct event_handler_args arg) if ((ppv_link->pvlMask & pvlOptCP) || ((ppv_link->pvlMask & pvlOptCPP) && precord->scan == 0)) - scanOnce(precord); + scanLinkOnce(precord, pca); } done: epicsMutexUnlock(pca->lock); @@ -835,7 +860,7 @@ static void accessRightsCallback(struct access_rights_handler_args arg) if (precord && ((ppv_link->pvlMask & pvlOptCP) || ((ppv_link->pvlMask & pvlOptCPP) && precord->scan == 0))) - scanOnce(precord); + scanLinkOnce(precord, pca); done: epicsMutexUnlock(pca->lock); } diff --git a/src/ioc/db/dbCaPvt.h b/src/ioc/db/dbCaPvt.h index 584c53da3..219da5a51 100644 --- a/src/ioc/db/dbCaPvt.h +++ b/src/ioc/db/dbCaPvt.h @@ -85,6 +85,7 @@ typedef struct caLink char gotOutString; char newOutNative; char newOutString; + unsigned char scanningOnce; /* The following are for dbcar*/ unsigned long nDisconnect; unsigned long nNoWrite; /*only modified by dbCaPutLink*/