fix RPRO/PUTF regression

This commit is contained in:
Michael Davidsaver
2019-01-27 19:10:00 -08:00
parent e918994704
commit e860617389
3 changed files with 34 additions and 7 deletions
@@ -5,11 +5,16 @@
#include <dbDefs.h>
#include "dbCommon.h"
struct epicsThreadOSD;
/** Base internal additional information for every record
*/
typedef struct dbCommonPvt {
struct dbRecordNode *recnode;
/* Thread which is currently processing this record */
struct epicsThreadOSD* procThread;
struct dbCommon common;
} dbCommonPvt;
+29 -5
View File
@@ -56,7 +56,7 @@
#include "dbAddr.h"
#include "dbBase.h"
#include "dbBkpt.h"
#include "dbCommon.h"
#include "dbCommonPvt.h"
#include "dbConvertFast.h"
#include "dbConvert.h"
#include "db_field_log.h"
@@ -386,8 +386,11 @@ static long processTarget(dbCommon *psrc, dbCommon *pdst)
{
char context[40] = "";
int trace = dbAccessDebugPUTF && *dbLockSetAddrTrace(psrc);
int srcset = dbRec2Pvt(psrc)->procThread==NULL;
int dstset = dbRec2Pvt(pdst)->procThread==NULL;
long status;
epicsUInt8 pact = psrc->pact;
epicsThreadId self = epicsThreadGetIdSelf();
psrc->pact = TRUE;
@@ -408,8 +411,9 @@ static long processTarget(dbCommon *psrc, dbCommon *pdst)
pdst->putf = psrc->putf;
}
else if (psrc->putf) {
/* The dst record is busy (awaiting async reprocessing) and
else if (psrc->putf && dbRec2Pvt(pdst)->procThread!=self) {
/* The dst record is busy (awaiting async reprocessing),
* not being processed recursively by us, and
* we were originally triggered by a call to dbPutField(),
* so we mark the dst record for reprocessing once the async
* completion is over.
@@ -422,17 +426,37 @@ static long processTarget(dbCommon *psrc, dbCommon *pdst)
pdst->rpro = TRUE;
}
else {
/* The dst record is busy, but we weren't triggered by a call
* to dbPutField(). Do nothing.
/* The dst record is busy, but either is being processed recursively,
* or wasn't triggered by a call to dbPutField(). Do nothing.
*/
if (trace)
printf("%s: '%s' -> Active '%s', done\n",
context, psrc->name, pdst->name);
}
if(srcset) {
dbRec2Pvt(psrc)->procThread = self;
} else {
assert(dbRec2Pvt(psrc)->procThread==self);
}
if(dstset) {
dbRec2Pvt(pdst)->procThread = self;
} else {
assert(dbRec2Pvt(psrc)->procThread==self);
}
status = dbProcess(pdst);
psrc->pact = pact;
assert(dbRec2Pvt(psrc)->procThread==self);
assert(dbRec2Pvt(pdst)->procThread==self);
if(srcset) {
dbRec2Pvt(psrc)->procThread = NULL;
}
if(dstset) {
dbRec2Pvt(pdst)->procThread = NULL;
}
return status;
}