Hi Tim,
On 07/11/2017 08:29 PM, Mooney, Tim M. wrote:
> 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 checked out the latest version of autosave to look at what you're
doing. As I said yesterday and contrary to the comment in dbrestore.c
it's not actually record initialization that changes the field type, the
value of pflddes->field_type never changes (it holds the metadata for
the record type as a whole, not for individual record instances), but
the call to prset->cvt_dbaddr() inside dbNameToAddr() that modifies your
paddr->field_type value. It also sets any other members of paddr that
need updating at runtime.
The other relevant RSET routine is prset->get_array_info() which in
newer versions of Base can also adjust paddr->pfield to permit
double-buffering of the array data, and I now think this is where the
autosave code needs to change slightly. More below...
> 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.
Your code in SR_put_array_values() is calling prset->get_array_info(),
but in scalar_restore() you don't call it, so in the new versions of the
aao and waveform record code where paddr->pfield is now being set in the
get_array_info() routine the scalar_restore() method is not writing
single-element array data to the right place. For a field whose
pflddes->field_type is DBF_NOACCESS you *must* now use the record type's
prset->get_array_info() method to update your paddr->pfield pointer, and
you should probably also call prset->put_array_info() afterwards too.
These should be safe to call in older versions of Base, so I don't think
you'll need version-specific code.
However I don't know whether you really need to reimplement the
functionality in dbAccess.c:dbPut() inside autosave, why aren't you just
using that to write the field values in pass 1? I can understand that it
won't work in pass 0 (especially for fields that are marked special),
but after the records have been initialized the dbPut() routine should
work properly. If it doesn't I would like to know why and try fixing it
in Base.
> 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.
That should be OK.
> I also noticed that paddr->pfield was being set in different calls
> - get_array_info() or cvt_dbaddr() - and that this changed from
> 3.14.12.5 to 3.15.5. But when I pulled the 3.14.12.5 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.
It's not just the record type changes that matter, what you're trying
there probably isn't going to solve the problem.
- Andrew
--
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