dbLock: restore initialization of PV_LINK
PV_LINK -> DB_LINK must happen in doResolveLinks after add_record
This commit is contained in:
+5
-3
@@ -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
@@ -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)
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#define DBLOCKPVT_H
|
||||
|
||||
#include "dbLock.h"
|
||||
#include "epicsSpin.h"
|
||||
|
||||
/* enable additional error checking */
|
||||
#define LOCKSET_DEBUG
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user