use dbChannel in link instead of DBADDR

This commit is contained in:
2020-02-11 17:29:16 +01:00
committed by Andrew Johnson
parent 297f04bddc
commit b1f445925d
6 changed files with 79 additions and 70 deletions

View File

@@ -1042,7 +1042,7 @@ static long dbPutFieldLink(DBADDR *paddr,
short dbrType, const void *pbuffer, long nRequest)
{
dbLinkInfo link_info;
DBADDR *pdbaddr = NULL;
dbChannel *chan = NULL;
dbCommon *precord = paddr->precord;
dbCommon *lockrecs[2];
dbLocker locker;
@@ -1080,16 +1080,11 @@ static long dbPutFieldLink(DBADDR *paddr,
if (link_info.ltype == PV_LINK &&
(link_info.modifiers & (pvlOptCA | pvlOptCP | pvlOptCPP)) == 0) {
DBADDR tempaddr;
if (dbNameToAddr(link_info.target, &tempaddr)==0) {
/* This will become a DB link. */
pdbaddr = malloc(sizeof(*pdbaddr));
if (!pdbaddr) {
status = S_db_noMemory;
goto cleanup;
}
*pdbaddr = tempaddr; /* struct copy */
chan = dbChannelCreate(link_info.target);
if (chan && dbChannelOpen(chan) != 0) {
errlogPrintf("ERROR: dbPutFieldLink %s.%s=%s: dbChannelOpen() failed\n",
precord->name, pfldDes->name, link_info.target);
goto cleanup;
}
}
@@ -1098,7 +1093,7 @@ static long dbPutFieldLink(DBADDR *paddr,
memset(&locker, 0, sizeof(locker));
lockrecs[0] = precord;
lockrecs[1] = pdbaddr ? pdbaddr->precord : NULL;
lockrecs[1] = chan ? dbChannelRecord(chan) : NULL;
dbLockerPrepare(&locker, lockrecs, 2);
dbScanLockMany(&locker);
@@ -1186,7 +1181,8 @@ static long dbPutFieldLink(DBADDR *paddr,
case PV_LINK:
case CONSTANT:
case JSON_LINK:
dbAddLink(&locker, plink, pfldDes->field_type, pdbaddr);
dbAddLink(&locker, plink, pfldDes->field_type, chan);
chan = NULL; /* don't clean it up */
break;
case DB_LINK:
@@ -1216,6 +1212,8 @@ unlock:
dbScanUnlockMany(&locker);
dbLockerFinalize(&locker);
cleanup:
if (chan)
dbChannelDelete(chan);
free(link_info.target);
return status;
}

View File

@@ -74,7 +74,7 @@
#include "recSup.h"
#include "special.h"
#include "dbDbLink.h"
#include "dbChannel.h"
/***************************** Database Links *****************************/
@@ -83,45 +83,50 @@ static lset dbDb_lset;
static long processTarget(dbCommon *psrc, dbCommon *pdst);
#define linkChannel(plink) ((dbChannel *) (plink)->value.pv_link.pvt)
long dbDbInitLink(struct link *plink, short dbfType)
{
DBADDR dbaddr;
long status;
DBADDR *pdbAddr;
dbChannel *chan;
dbCommon *precord;
status = dbNameToAddr(plink->value.pv_link.pvname, &dbaddr);
chan = dbChannelCreate(plink->value.pv_link.pvname);
if (!chan)
return S_db_notFound;
status = dbChannelOpen(chan);
if (status)
return status;
precord = dbChannelRecord(chan);
plink->lset = &dbDb_lset;
plink->type = DB_LINK;
pdbAddr = dbCalloc(1, sizeof(struct dbAddr));
*pdbAddr = dbaddr; /* structure copy */
plink->value.pv_link.pvt = pdbAddr;
ellAdd(&dbaddr.precord->bklnk, &plink->value.pv_link.backlinknode);
plink->value.pv_link.pvt = chan;
ellAdd(&precord->bklnk, &plink->value.pv_link.backlinknode);
/* merging into the same lockset is deferred to the caller.
* cf. initPVLinks()
*/
dbLockSetMerge(NULL, plink->precord, dbaddr.precord);
assert(plink->precord->lset->plockSet == dbaddr.precord->lset->plockSet);
dbLockSetMerge(NULL, plink->precord, precord);
assert(plink->precord->lset->plockSet == precord->lset->plockSet);
return 0;
}
void dbDbAddLink(struct dbLocker *locker, struct link *plink, short dbfType,
DBADDR *ptarget)
dbChannel *ptarget)
{
plink->lset = &dbDb_lset;
plink->type = DB_LINK;
plink->value.pv_link.pvt = ptarget;
ellAdd(&ptarget->precord->bklnk, &plink->value.pv_link.backlinknode);
ellAdd(&dbChannelRecord(ptarget)->bklnk, &plink->value.pv_link.backlinknode);
/* target record is already locked in dbPutFieldLink() */
dbLockSetMerge(locker, plink->precord, ptarget->precord);
dbLockSetMerge(locker, plink->precord, dbChannelRecord(ptarget));
}
static void dbDbRemoveLink(struct dbLocker *locker, struct link *plink)
{
DBADDR *pdbAddr = (DBADDR *) plink->value.pv_link.pvt;
dbChannel *chan = linkChannel(plink);
dbCommon *precord = dbChannelRecord(chan);
plink->type = PV_LINK;
@@ -131,10 +136,10 @@ static void dbDbRemoveLink(struct dbLocker *locker, struct link *plink)
plink->value.pv_link.getCvt = 0;
plink->value.pv_link.pvlMask = 0;
plink->value.pv_link.lastGetdbrType = 0;
ellDelete(&pdbAddr->precord->bklnk, &plink->value.pv_link.backlinknode);
dbLockSetSplit(locker, plink->precord, pdbAddr->precord);
ellDelete(&precord->bklnk, &plink->value.pv_link.backlinknode);
dbLockSetSplit(locker, plink->precord, precord);
}
free(pdbAddr);
dbChannelDelete(chan);
}
static int dbDbIsConnected(const struct link *plink)
@@ -144,16 +149,14 @@ static int dbDbIsConnected(const struct link *plink)
static int dbDbGetDBFtype(const struct link *plink)
{
DBADDR *paddr = (DBADDR *) plink->value.pv_link.pvt;
return paddr->field_type;
dbChannel *chan = linkChannel(plink);
return dbChannelFinalFieldType(chan);
}
static long dbDbGetElements(const struct link *plink, long *nelements)
{
DBADDR *paddr = (DBADDR *) plink->value.pv_link.pvt;
*nelements = paddr->no_elements;
dbChannel *chan = linkChannel(plink);
*nelements = dbChannelFinalElements(chan);
return 0;
}
@@ -161,30 +164,31 @@ static long dbDbGetValue(struct link *plink, short dbrType, void *pbuffer,
long *pnRequest)
{
struct pv_link *ppv_link = &plink->value.pv_link;
DBADDR *paddr = ppv_link->pvt;
dbChannel *chan = linkChannel(plink);
DBADDR *paddr = &chan->addr;
dbCommon *precord = plink->precord;
long status;
/* scan passive records if link is process passive */
if (ppv_link->pvlMask & pvlOptPP) {
status = dbScanPassive(precord, paddr->precord);
status = dbScanPassive(precord, dbChannelRecord(chan));
if (status)
return status;
}
if (ppv_link->getCvt && ppv_link->lastGetdbrType == dbrType) {
status = ppv_link->getCvt(paddr->pfield, pbuffer, paddr);
status = ppv_link->getCvt(dbChannelField(chan), pbuffer, paddr);
} else {
unsigned short dbfType = paddr->field_type;
unsigned short dbfType = dbChannelFinalFieldType(chan);
if (dbrType < 0 || dbrType > DBR_ENUM || dbfType > DBF_DEVICE)
return S_db_badDbrtype;
if (paddr->no_elements == 1 && (!pnRequest || *pnRequest == 1)
&& paddr->special != SPC_DBADDR
&& paddr->special != SPC_ATTRIBUTE) {
if (dbChannelFinalElements(chan) == 1 && (!pnRequest || *pnRequest == 1)
&& dbChannelSpecial(chan) != SPC_DBADDR
&& dbChannelSpecial(chan) != SPC_ATTRIBUTE) {
ppv_link->getCvt = dbFastGetConvertRoutine[dbfType][dbrType];
status = ppv_link->getCvt(paddr->pfield, pbuffer, paddr);
status = ppv_link->getCvt(dbChannelField(chan), pbuffer, paddr);
} else {
ppv_link->getCvt = NULL;
status = dbGet(paddr, dbrType, pbuffer, NULL, pnRequest, NULL);
@@ -192,16 +196,18 @@ static long dbDbGetValue(struct link *plink, short dbrType, void *pbuffer,
ppv_link->lastGetdbrType = dbrType;
}
if (!status && precord != paddr->precord)
if (!status && precord != dbChannelRecord(chan))
recGblInheritSevr(plink->value.pv_link.pvlMask & pvlOptMsMode,
plink->precord, paddr->precord->stat, paddr->precord->sevr);
plink->precord,
dbChannelRecord(chan)->stat, dbChannelRecord(chan)->sevr);
return status;
}
static long dbDbGetControlLimits(const struct link *plink, double *low,
double *high)
{
DBADDR *paddr = (DBADDR *) plink->value.pv_link.pvt;
dbChannel *chan = linkChannel(plink);
DBADDR *paddr = &chan->addr;
struct buffer {
DBRctrlDouble
double value;
@@ -222,7 +228,8 @@ static long dbDbGetControlLimits(const struct link *plink, double *low,
static long dbDbGetGraphicLimits(const struct link *plink, double *low,
double *high)
{
DBADDR *paddr = (DBADDR *) plink->value.pv_link.pvt;
dbChannel *chan = linkChannel(plink);
DBADDR *paddr = &chan->addr;
struct buffer {
DBRgrDouble
double value;
@@ -243,7 +250,8 @@ static long dbDbGetGraphicLimits(const struct link *plink, double *low,
static long dbDbGetAlarmLimits(const struct link *plink, double *lolo,
double *low, double *high, double *hihi)
{
DBADDR *paddr = (DBADDR *) plink->value.pv_link.pvt;
dbChannel *chan = linkChannel(plink);
DBADDR *paddr = &chan->addr;
struct buffer {
DBRalDouble
double value;
@@ -265,7 +273,8 @@ static long dbDbGetAlarmLimits(const struct link *plink, double *lolo,
static long dbDbGetPrecision(const struct link *plink, short *precision)
{
DBADDR *paddr = (DBADDR *) plink->value.pv_link.pvt;
dbChannel *chan = linkChannel(plink);
DBADDR *paddr = &chan->addr;
struct buffer {
DBRprecision
double value;
@@ -284,7 +293,8 @@ static long dbDbGetPrecision(const struct link *plink, short *precision)
static long dbDbGetUnits(const struct link *plink, char *units, int unitsSize)
{
DBADDR *paddr = (DBADDR *) plink->value.pv_link.pvt;
dbChannel *chan = linkChannel(plink);
DBADDR *paddr = &chan->addr;
struct buffer {
DBRunits
double value;
@@ -304,20 +314,20 @@ static long dbDbGetUnits(const struct link *plink, char *units, int unitsSize)
static long dbDbGetAlarm(const struct link *plink, epicsEnum16 *status,
epicsEnum16 *severity)
{
DBADDR *paddr = (DBADDR *) plink->value.pv_link.pvt;
dbChannel *chan = linkChannel(plink);
dbCommon *precord = dbChannelRecord(chan);
if (status)
*status = paddr->precord->stat;
*status = precord->stat;
if (severity)
*severity = paddr->precord->sevr;
*severity = precord->sevr;
return 0;
}
static long dbDbGetTimeStamp(const struct link *plink, epicsTimeStamp *pstamp)
{
DBADDR *paddr = (DBADDR *) plink->value.pv_link.pvt;
*pstamp = paddr->precord->time;
dbChannel *chan = linkChannel(plink);
dbCommon *precord = dbChannelRecord(chan);
*pstamp = precord->time;
return 0;
}
@@ -325,9 +335,10 @@ static long dbDbPutValue(struct link *plink, short dbrType,
const void *pbuffer, long nRequest)
{
struct pv_link *ppv_link = &plink->value.pv_link;
dbChannel *chan = linkChannel(plink);
struct dbCommon *psrce = plink->precord;
DBADDR *paddr = (DBADDR *) ppv_link->pvt;
dbCommon *pdest = paddr->precord;
DBADDR *paddr = &chan->addr;
dbCommon *pdest = dbChannelRecord(chan);
long status = dbPut(paddr, dbrType, pbuffer, nRequest);
recGblInheritSevr(ppv_link->pvlMask & pvlOptMsMode, pdest, psrce->nsta,
@@ -335,7 +346,7 @@ static long dbDbPutValue(struct link *plink, short dbrType,
if (status)
return status;
if (paddr->pfield == (void *) &pdest->proc ||
if (dbChannelField(chan) == (void *) &pdest->proc ||
(ppv_link->pvlMask & pvlOptPP && pdest->scan == 0)) {
status = processTarget(psrce, pdest);
}
@@ -346,9 +357,8 @@ static long dbDbPutValue(struct link *plink, short dbrType,
static void dbDbScanFwdLink(struct link *plink)
{
dbCommon *precord = plink->precord;
dbAddr *paddr = (dbAddr *) plink->value.pv_link.pvt;
dbScanPassive(precord, paddr->precord);
dbChannel *chan = linkChannel(plink);
dbScanPassive(precord, dbChannelRecord(chan));
}
static long doLocked(struct link *plink, dbLinkUserCallback rtn, void *priv)

View File

@@ -27,7 +27,7 @@ struct dbLocker;
epicsShareFunc long dbDbInitLink(struct link *plink, short dbfType);
epicsShareFunc void dbDbAddLink(struct dbLocker *locker, struct link *plink,
short dbfType, DBADDR *ptarget);
short dbfType, dbChannel *ptarget);
#ifdef __cplusplus
}

View File

@@ -144,7 +144,7 @@ void dbInitLink(struct link *plink, short dbfType)
}
void dbAddLink(struct dbLocker *locker, struct link *plink, short dbfType,
DBADDR *ptarget)
dbChannel *ptarget)
{
struct dbCommon *precord = plink->precord;

View File

@@ -21,6 +21,7 @@
#include "epicsTypes.h"
#include "epicsTime.h"
#include "dbAddr.h"
#include "dbChannel.h"
#ifdef __cplusplus
extern "C" {
@@ -369,7 +370,7 @@ epicsShareFunc const char * dbLinkFieldName(const struct link *plink);
epicsShareFunc void dbInitLink(struct link *plink, short dbfType);
epicsShareFunc void dbAddLink(struct dbLocker *locker, struct link *plink,
short dbfType, DBADDR *ptarget);
short dbfType, dbChannel *ptarget);
epicsShareFunc void dbLinkOpen(struct link *plink);
epicsShareFunc void dbRemoveLink(struct dbLocker *locker, struct link *plink);

View File

@@ -743,14 +743,14 @@ void dbLockSetSplit(dbLocker *locker, dbCommon *pfirst, dbCommon *psecond)
for(i=0; i<rtype->no_links; i++) {
dbFldDes *pdesc = rtype->papFldDes[rtype->link_ind[i]];
DBLINK *plink = (DBLINK*)((char*)prec + pdesc->offset);
DBADDR *ptarget;
dbChannel *chan;
lockRecord *lr;
if(plink->type!=DB_LINK)
continue;
ptarget = plink->value.pv_link.pvt;
lr = ptarget->precord->lset;
chan = plink->value.pv_link.pvt;
lr = dbChannelRecord(chan)->lset;
assert(lr);
if(lr->precord==pfirst) {