dbAccess: multi-locking in dbPutFieldLink
Use new locking API in dbPutFieldLink() Adjust dbAddLink() and dbRemoveLink() to pass a dbLocker* through to lockSet merge/split
This commit is contained in:
@@ -32,6 +32,7 @@
|
||||
#include "epicsThread.h"
|
||||
#include "epicsTime.h"
|
||||
#include "errlog.h"
|
||||
#include "epicsSpin.h"
|
||||
#include "errMdef.h"
|
||||
|
||||
#define epicsExportSharedSymbols
|
||||
@@ -50,7 +51,7 @@
|
||||
#include "dbFldTypes.h"
|
||||
#include "dbFldTypes.h"
|
||||
#include "dbLink.h"
|
||||
#include "dbLock.h"
|
||||
#include "dbLockPvt.h"
|
||||
#include "dbNotify.h"
|
||||
#include "dbScan.h"
|
||||
#include "dbServer.h"
|
||||
@@ -944,6 +945,8 @@ static long dbPutFieldLink(DBADDR *paddr,
|
||||
dbLinkInfo link_info;
|
||||
DBADDR *pdbaddr = NULL;
|
||||
dbCommon *precord = paddr->precord;
|
||||
dbCommon *lockrecs[3];
|
||||
dbLocker locker;
|
||||
dbFldDes *pfldDes = paddr->pfldDes;
|
||||
long special = paddr->special;
|
||||
struct link *plink = (struct link *)paddr->pfield;
|
||||
@@ -956,6 +959,8 @@ static long dbPutFieldLink(DBADDR *paddr,
|
||||
int isDevLink;
|
||||
short scan;
|
||||
|
||||
STATIC_ASSERT(DBLOCKER_NALLOC>=3);
|
||||
|
||||
switch (dbrType) {
|
||||
case DBR_CHAR:
|
||||
case DBR_UCHAR:
|
||||
@@ -992,10 +997,13 @@ static long dbPutFieldLink(DBADDR *paddr,
|
||||
isDevLink = ellCount(&precord->rdes->devList) > 0 &&
|
||||
pfldDes->isDevLink;
|
||||
|
||||
dbLockSetGblLock();
|
||||
dbLockSetRecordLock(precord);
|
||||
if (pdbaddr)
|
||||
dbLockSetRecordLock(pdbaddr->precord);
|
||||
memset(&locker, 0, sizeof(locker));
|
||||
lockrecs[0] = precord;
|
||||
lockrecs[1] = pdbaddr ? pdbaddr->precord : NULL;
|
||||
lockrecs[2] = NULL;
|
||||
dbLockerPrepare(&locker, lockrecs, 3);
|
||||
|
||||
dbScanLockMany(&locker);
|
||||
|
||||
scan = precord->scan;
|
||||
|
||||
@@ -1044,7 +1052,7 @@ static long dbPutFieldLink(DBADDR *paddr,
|
||||
switch (plink->type) { /* Old link type */
|
||||
case DB_LINK:
|
||||
case CA_LINK:
|
||||
dbRemoveLink(plink);
|
||||
dbRemoveLink(&locker, precord, plink);
|
||||
break;
|
||||
|
||||
case PV_LINK:
|
||||
@@ -1091,7 +1099,7 @@ static long dbPutFieldLink(DBADDR *paddr,
|
||||
|
||||
switch (plink->type) { /* New link type */
|
||||
case PV_LINK:
|
||||
dbAddLink(precord, plink, pfldDes->field_type, pdbaddr);
|
||||
dbAddLink(&locker, precord, plink, pfldDes->field_type, pdbaddr);
|
||||
break;
|
||||
|
||||
case CONSTANT:
|
||||
@@ -1121,7 +1129,8 @@ postScanEvent:
|
||||
if (scan != precord->scan)
|
||||
db_post_events(precord, &precord->scan, DBE_VALUE | DBE_LOG);
|
||||
unlock:
|
||||
dbLockSetGblUnlock();
|
||||
dbScanUnlockMany(&locker);
|
||||
dbLockerFinalize(&locker);
|
||||
cleanup:
|
||||
free(link_info.target);
|
||||
return status;
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
#include "cantProceed.h"
|
||||
#include "cvtFast.h"
|
||||
#include "dbDefs.h"
|
||||
#include "epicsSpin.h"
|
||||
#include "ellLib.h"
|
||||
#include "epicsThread.h"
|
||||
#include "epicsTime.h"
|
||||
@@ -45,7 +46,7 @@
|
||||
#include "dbFldTypes.h"
|
||||
#include "dbFldTypes.h"
|
||||
#include "dbLink.h"
|
||||
#include "dbLock.h"
|
||||
#include "dbLockPvt.h"
|
||||
#include "dbNotify.h"
|
||||
#include "dbScan.h"
|
||||
#include "dbStaticLib.h"
|
||||
@@ -140,18 +141,21 @@ static long dbDbInitLink(struct link *plink, short dbfType)
|
||||
pdbAddr = dbCalloc(1, sizeof(struct dbAddr));
|
||||
*pdbAddr = dbaddr; /* structure copy */
|
||||
plink->value.pv_link.pvt = pdbAddr;
|
||||
dbLockSetMerge(plink->value.pv_link.precord, pdbAddr->precord);
|
||||
/* merging into the same lockset is deferred to the caller.
|
||||
* cf. initPVLinks()
|
||||
*/
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void dbDbRemoveLink(struct link *plink)
|
||||
static void dbDbRemoveLink(dbLocker *locker, struct dbCommon *prec, struct link *plink)
|
||||
{
|
||||
free(plink->value.pv_link.pvt);
|
||||
DBADDR *pdbAddr = (DBADDR *) plink->value.pv_link.pvt;
|
||||
plink->value.pv_link.pvt = 0;
|
||||
plink->value.pv_link.getCvt = 0;
|
||||
plink->value.pv_link.lastGetdbrType = 0;
|
||||
plink->type = PV_LINK;
|
||||
dbLockSetSplit(plink->value.pv_link.precord);
|
||||
dbLockSetSplit(locker, prec, pdbAddr->precord);
|
||||
free(pdbAddr);
|
||||
}
|
||||
|
||||
static int dbDbIsLinkConnected(const struct link *plink)
|
||||
@@ -422,7 +426,7 @@ void dbInitLink(struct dbCommon *precord, struct link *plink, short dbfType)
|
||||
}
|
||||
}
|
||||
|
||||
void dbAddLink(struct dbCommon *precord, struct link *plink, short dbfType, DBADDR *ptargetaddr)
|
||||
void dbAddLink(dbLocker *locker, struct dbCommon *precord, struct link *plink, short dbfType, DBADDR *ptargetaddr)
|
||||
{
|
||||
plink->value.pv_link.precord = precord;
|
||||
|
||||
@@ -436,7 +440,7 @@ void dbAddLink(struct dbCommon *precord, struct link *plink, short dbfType, DBAD
|
||||
plink->value.pv_link.pvt = ptargetaddr;
|
||||
|
||||
/* target record is already locked in dbPutFieldLink() */
|
||||
dbLockSetMerge(plink->value.pv_link.precord, ptargetaddr->precord);
|
||||
dbLockSetMerge(locker, plink->value.pv_link.precord, ptargetaddr->precord);
|
||||
|
||||
return;
|
||||
}
|
||||
@@ -463,11 +467,11 @@ long dbLoadLink(struct link *plink, short dbrType, void *pbuffer)
|
||||
return S_db_notFound;
|
||||
}
|
||||
|
||||
void dbRemoveLink(struct link *plink)
|
||||
void dbRemoveLink(dbLocker *locker, dbCommon *prec, struct link *plink)
|
||||
{
|
||||
switch (plink->type) {
|
||||
case DB_LINK:
|
||||
dbDbRemoveLink(plink);
|
||||
dbDbRemoveLink(locker, prec, plink);
|
||||
break;
|
||||
case CA_LINK:
|
||||
dbCaRemoveLink(plink);
|
||||
|
||||
@@ -50,13 +50,15 @@ typedef struct lset {
|
||||
#define dbGetSevr(PLINK, PSEVERITY) \
|
||||
dbGetAlarm((PLINK), NULL, (PSEVERITY))
|
||||
|
||||
struct dbLocker;
|
||||
|
||||
epicsShareFunc void dbInitLink(struct dbCommon *precord, struct link *plink,
|
||||
short dbfType);
|
||||
epicsShareFunc void dbAddLink(struct dbCommon *precord, struct link *plink,
|
||||
epicsShareFunc void dbAddLink(struct dbLocker *locker, struct dbCommon *precord, struct link *plink,
|
||||
short dbfType, DBADDR *ptargetaddr);
|
||||
epicsShareFunc long dbLoadLink(struct link *plink, short dbrType,
|
||||
void *pbuffer);
|
||||
epicsShareFunc void dbRemoveLink(struct link *plink);
|
||||
epicsShareFunc void dbRemoveLink(struct dbLocker *locker, struct dbCommon *prec, struct link *plink);
|
||||
epicsShareFunc long dbGetNelements(const struct link *plink, long *nelements);
|
||||
epicsShareFunc int dbIsLinkConnected(const struct link *plink);
|
||||
epicsShareFunc int dbGetLinkDBFtype(const struct link *plink);
|
||||
|
||||
Reference in New Issue
Block a user