Experimental Physics and
You're right that my status = (*dbFastPutConvertRoutine[DBR_STRING][field_type]) call doesn't specify DBF_NOACCESS for field_type. I missed the reassignment to field_type.
This code is called from two initHooks: initHookAfterInitDevSup (before record init) and initHookAfterInitDatabase (after record and device init). DBF_NOACCESS fields, including arrays, are skipped in the first call.
I don't have a way of distinguishing arrays of one element from scalars. At save time, I'm using ca_element_count() to determine the number of array elements, and treating PVs with one element as scalars.
At boot-time restore, I'm using the text that was written at save time to tell me how to restore the PV's value.
I also noticed that paddr->pfield was being set in different calls - get_array_info() or cvt_dbaddr() - and that this changed from 220.127.116.11 to 3.15.5. But when I pulled the 18.104.22.168 version of the waveform record into 3.15.5 and it didn't fix the problem, I assumed this was not the source of the problem. Maybe I should try again, more carefully this time.
Tim Mooney (firstname.lastname@example.org) (630)252-5417
Beamline Controls Group (www.aps.anl.gov)
Advanced Photon Source, Argonne National Lab
From: email@example.com <firstname.lastname@example.org> on behalf of Andrew Johnson <email@example.com>
Sent: Tuesday, July 11, 2017 6:58:38 PM
Subject: Re: Autosave for waveform with 1 element
On 07/11/2017 05:10 PM, Mooney, Tim M. wrote:
> I think the line in dbrestore.c that isn't doing the same thing under
> 3.15.5 that it did under 22.214.171.124 is this:
> status = (*dbFastPutConvertRoutine[DBR_STRING][field_type])
> where field_type has the value DBF_NOACCESS.
If your code really is looking up
then it isn't getting the function pointer that it's looking for,
because the second index into that array only goes up to DBF_DEVICE
which is 4 less than DBF_NOACCESS. More likely the field_type value was
replaced when dbNameToAddr() called the prset->cvt_dbaddr() routine,
which sets paddr->field_type from prec->ftvl or the equivalent field.
Hmm, is this dbrestore code being run from initHooks during iocInit()?
Which hooks do you use when dealing with array fields, and how do you
detect and distinguish between arrays and scalars?
Michael Davidsaver added some tests to Base-3.16 which check the APIs
that autosave uses so we shouldn't break them when we modify Base, but
he doesn't actually call dbPut() in the initHookAfterInitDatabase state
so we might have subtly changed the behaviour without knowing it (and of
course those tests are present in 3.16, not 3.15).
> But I don't understand how
> the aSubRecord's .A field behaves differently than the waveform record's
> .VAL field, because they are both one element array fields.
Arrays with one element look to some parts of the IOC code like they are
regular fields, but to other parts like they are arrays. That
distinction has changed slightly in more recent versions.
One subtle difference that I know about is when the field's buffer
pointer gets copied into paddr->pfield. Both the waveform and aao record
types do this in their get_array_info() method:
paddr->pfield = prec->bptr;
In the aSub record though paddr->pfield is set in the cvt_dbaddr()
paddr->pfield = (&prec->a )[offset];
Thus the behaviour difference you see might be explained by something
not calling the get_array_info() method properly in 3.15.5 at the time
when you're accessing the array field.
Arguing for surveillance because you have nothing to hide is no
different than making the claim, "I don't care about freedom of
speech because I have nothing to say." -- Edward Snowdon
|ANJ, 21 Dec 2017||
· Search · EPICS V4 · IRMIS · Talk · Bugs · Documents · Links · Licensing ·