Hi Bob,
On Friday 24 April 2009 14:55:25 Bob Dalesio wrote:
> Do you know what the PUTF record processed by dbPutfield, and RPRO
> reprocess fields are used to accomplish?
I'm cross-posting this message to core-talk because while replying to Bob's
question I think I've found a couple of bugs associated with those fields,
and I'd like some more eyes on the issue.
I believe PUTF was provided as a way of telling a record that it's being
processed because someone changed one of its fields, so it can distinguish
between that and processing resulting from a forward link or other scan
mechanism. I don't know of any record types that actually look at PUTF, but
there could be some. However there are occasions where PUTF lies, which
makes it less useful (see below).
RPRO is needed to ensure that a pending asynchronous operation doesn't cause
the processing resulting from a put operation to be missed. It is less
relevent to the record type, being mostly for internal use but is related to
the PUTF field.
Here's what I get from reading the source, which uses these two fields in four
places:
1. If something [usually CA but it could be a dbpf command] calls dbPutField()
to set a field which is marked as PP, the routine will try to process the
record immediately. If PACT is true however it can't, so it sets RPRO to
request reprocessing later; if PACT is false it sets PUTF and calls
dbProcess() to do the actual processing.
2. Inside dbProcess(), if a record is found to be disabled because DISA==DISV,
both PUTF and RPRO are cleared immediately.
3. When a record finishes processing, usually the last thing its process()
routine does is to call recGblFwdLink(). This checks and clears the RPRO
field and if set it sticks this record on the scanOnce() queue to be run
again as soon as possible. recGblFwdLink() always clears PUTF.
4. In dbPutLinkValue() when a DB link from another record has the PP flag set
or points to the PROC field, if the destination record has its PUTF field set
it just sets RPRO. If PUTF is not set, it calls dbScanLink() to process the
destination record. This code really doesn't make any sense to me.
I think there are two bugs in the above code, which make the PUTF field less
useful than it could/should be.
A) I suspect that in item 4 above, the dbPutLinkValue() code really should be
testing PACT not PUTF, and it should actually set PUTF before the call to
dbScanLink(). I have some vestigial memories that before PACT was introduced
the PUTF field was involved in asynchronous processing, but I wasn't involved
at the time so I may be confused about that.
B) I also think that recGblFwdLink() should not clear PUTF if RPRO was set,
because the *next* time the record processes is the one that is due to a call
to dbPutField() or dbPutLink(). Instead it should be setting PUTF if RPRO
was set, and clearing it otherwise.
I propose to apply the attached change in src/db and would appreciate comments
from other core developers in case I've missed or misunderstood something
about how this is supposed to work.
Without this patch, PUTF is actually an almost useless field; the only place
where its value gets looked at is in the dbPutLinkValue() routine as
described above, unless there are some non-core record types that use it.
- Andrew
--
The best FOSS code is written to be read by other humans -- Harold Welte
? Notify.txt
Index: dbAccess.c
===================================================================
RCS file: /net/phoebus/epicsmgr/cvsroot/epics/base/src/db/dbAccess.c,v
retrieving revision 1.116.2.31
diff -d -u -b -B -p -r1.116.2.31 dbAccess.c
--- dbAccess.c 23 Apr 2009 18:49:38 -0000 1.116.2.31
+++ dbAccess.c 24 Apr 2009 22:30:39 -0000
@@ -919,9 +919,10 @@ long epicsShareAPI dbPutLinkValue(struct
(ppv_link->pvlMask & pvlOptPP && pdest->scan == 0)) {
/*if dbPutField caused asyn record to process */
/* ask for reprocessing*/
- if (pdest->putf) {
+ if (pdest->pact) {
pdest->rpro = TRUE;
} else { /* otherwise ask for the record to be processed*/
+ pdest->putf = TRUE;
status = dbScanLink(psource, pdest);
}
}
Index: recGbl.c
===================================================================
RCS file: /net/phoebus/epicsmgr/cvsroot/epics/base/src/db/recGbl.c,v
retrieving revision 1.60.2.8
diff -d -u -b -B -p -r1.60.2.8 recGbl.c
--- recGbl.c 24 Feb 2009 22:30:26 -0000 1.60.2.8
+++ recGbl.c 24 Apr 2009 22:30:39 -0000
@@ -265,13 +265,12 @@ void epicsShareAPI recGblFwdLink(void *p
dbScanFwdLink(&pdbc->flnk);
/*Handle dbPutFieldNotify record completions*/
if(pdbc->ppn) dbNotifyCompletion(pdbc);
+ pdbc->putf = pdbc->rpro;
if(pdbc->rpro) {
/*If anyone requested reprocessing do it*/
pdbc->rpro = FALSE;
scanOnce(pdbc);
}
- /*In case putField caused put we are all done */
- pdbc->putf = FALSE;
}
void epicsShareAPI recGblGetTimeStamp(void *pvoid)
- Replies:
- Re: some field definitions Tim Mooney
- Re: some field definitions Marty Kraimer
- Navigate by Date:
- Prev:
Re: Failing EPICS Test Harness on RTEMS-mvme5500 Kate Feng
- Next:
Re: some field definitions Tim Mooney
- Index:
2002
2003
2004
2005
2006
2007
2008
<2009>
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
- Navigate by Thread:
- Prev:
Re: 3.14.10 on native win32: make problem Ralph Lange
- Next:
Re: some field definitions Tim Mooney
- Index:
2002
2003
2004
2005
2006
2007
2008
<2009>
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
|