dbLock: restore initialization of PV_LINK

PV_LINK -> DB_LINK must happen in doResolveLinks after add_record
This commit is contained in:
Michael Davidsaver
2015-08-20 15:52:30 -04:00
parent 536c6e91ff
commit d890c80961
4 changed files with 13 additions and 52 deletions
+5 -3
View File
@@ -127,7 +127,7 @@ static long dbConstGetLink(struct link *plink, short dbrType, void *pbuffer,
/***************************** Database Links *****************************/
static long dbDbInitLink(struct link *plink, short dbfType)
static long dbDbInitLink(struct dbCommon *precord, struct link *plink, short dbfType)
{
DBADDR dbaddr;
long status;
@@ -145,6 +145,8 @@ static long dbDbInitLink(struct link *plink, short dbfType)
/* merging into the same lockset is deferred to the caller.
* cf. initPVLinks()
*/
dbLockSetMerge(NULL, precord, dbaddr.precord);
assert(precord->lset->plockSet==dbaddr.precord->lset->plockSet);
return 0;
}
@@ -386,7 +388,7 @@ static void dbDbScanFwdLink(struct link *plink)
dbScanPassive(precord, paddr->precord);
}
lset dbDb_lset = { dbDbRemoveLink,
lset dbDb_lset = { NULL,
dbDbIsLinkConnected, dbDbGetDBFtype, dbDbGetElements, dbDbGetValue,
dbDbGetControlLimits, dbDbGetGraphicLimits, dbDbGetAlarmLimits,
dbDbGetPrecision, dbDbGetUnits, dbDbGetAlarm, dbDbGetTimeStamp,
@@ -403,7 +405,7 @@ void dbInitLink(struct dbCommon *precord, struct link *plink, short dbfType)
if (!(plink->value.pv_link.pvlMask & (pvlOptCA | pvlOptCP | pvlOptCPP))) {
/* Make it a DB link if possible */
if (!dbDbInitLink(plink, dbfType))
if (!dbDbInitLink(precord, plink, dbfType))
return;
}
+3 -49
View File
@@ -516,53 +516,9 @@ static int createLockRecord(void* junk, DBENTRY* pdbentry)
lrec->precord = prec;
prec->lset = lrec;
return 0;
}
static int initPVLinks(void* junk, DBENTRY* pdbentry)
{
size_t i;
dbRecordType *rtype=pdbentry->precordType;
dbCommon *prec = pdbentry->precnode->precord;
lockSet *A=prec->lset->plockSet;
if(!A) {
A = prec->lset->plockSet = makeSet();
ellAdd(&A->lockRecordList, &prec->lset->node);
}
/* for each link originating from this record */
for(i=0; i<rtype->no_links; i++) {
DBADDR *paddr;
dbFldDes *pdesc = rtype->papFldDes[rtype->link_ind[i]];
DBLINK *plink = (DBLINK*)((char*)prec + pdesc->offset);
lockSet *B;
if(plink->type!=PV_LINK)
continue;
dbInitLink(prec, plink, pdesc->field_type);
if(plink->type!=DB_LINK)
continue;
paddr = (DBADDR*)plink->value.pv_link.pvt;
B = paddr->precord->lset->plockSet;
if(A==B) {
/* these records are already in the same lockset */
} else if(B) {
assert(A!=B);
dbLockSetMerge(NULL, prec, paddr->precord);
assert(prec->lset->plockSet==paddr->precord->lset->plockSet);
} else {
/* fast merge paddr->precord into A */
paddr->precord->lset->plockSet = A;
dbLockIncRef(A);
ellAdd(&A->lockRecordList, &paddr->precord->lset->node);
}
}
prec->lset->plockSet = makeSet();
ellAdd(&prec->lset->plockSet->lockRecordList, &prec->lset->node);
return 0;
}
@@ -570,10 +526,8 @@ void dbLockInitRecords(dbBase *pdbbase)
{
epicsThreadOnce(&dbLockOnceInit, &dbLockOnce, NULL);
/* create all lockRecords */
/* create all lockRecords and lockSets */
forEachRecord(NULL, pdbbase, &createLockRecord);
/* create lockSets */
forEachRecord(NULL, pdbbase, &initPVLinks);
}
static int freeLockRecord(void* junk, DBENTRY* pdbentry)
+1
View File
@@ -10,6 +10,7 @@
#define DBLOCKPVT_H
#include "dbLock.h"
#include "epicsSpin.h"
/* enable additional error checking */
#define LOCKSET_DEBUG
+4
View File
@@ -495,6 +495,7 @@ static void doResolveLinks(dbRecordType *pdbRecordType, dbCommon *precord,
/* For all the links in the record type... */
for (j = 0; j < pdbRecordType->no_links; j++) {
dbFldDes *pdbFldDes = papFldDes[link_ind[j]];
DBLINK *plink = (DBLINK*)((char*)precord + pdbFldDes->offset);
if (ellCount(&precord->rdes->devList) > 0 && pdbFldDes->isDevLink) {
devSup *pdevSup = dbDTYPtoDevSup(pdbRecordType, precord->dtyp);
@@ -506,6 +507,9 @@ static void doResolveLinks(dbRecordType *pdbRecordType, dbCommon *precord,
}
}
}
if (plink->type == PV_LINK)
dbInitLink(precord, plink, pdbFldDes->field_type);
}
}