Experimental Physics and
| |||||||||||||||||
|
Dirk Zimoch wrote: Hi Chen,
Executive summary: You can manipulate buffer pointers in some cases, but there are limitations on what you can accomplish by doing it. The limitations for gets are different from the limitations for monitors. In the following, the array field has the attribute SPC_DBADDR, and record support implements the routines cvt_dbaddr() and get_array_info(). Here's what happens when a client does a get (either ca or db) on the array field: 1) cvt_dbaddr() is called (twice; I don't know why) and is supplied with a struct dbAddr argument which names the field the client wants. cvt_dbddr() fills in the dbAddr structure to describe the field data, and to specify the buffer pointer. It doesn't matter what the buffer pointer actually points to yet, though it must be of the correct type. 2) get_array_info() is called, with the struct dbAddr arg that cvt_dbaddr() modified. Thus, get_array_info() sees both the field name and the buffer pointer written by cvt_dbaddr(). get_array_info() can change the buffer pointer in the dbAddr structure, and this is the buffer pointer that will actually be used to transfer data. So, if we restrict attention to gets, a record can do whatever it wants with buffer pointers, as long as its get_array_info() routine supplies the correct buffer pointer, and the record maintains the data and the pointer until they are read by the client. The record cannot know when a client will want to read the data, however, so steps must be taken to defend clients from stale or partially written data. Monitors are a little more indirect, and the record is significantly more constrained in the pointer manipulation it can get way with. Here's what happens when a client monitors an array field: 1) cvt_dbaddr() is called as for a get. 2) get_array_info() is called twice, and CA evidently caches the dbAddr structure, or at least the buffer pointer (the dbAddr's pfield) that get_array_info() wrote to that structure. 3) when the record wants to post the array field, it must post the buffer pointer (pfield) from (2) to get the array data sent to the client whose monitor request resulted in that call to get_array_info(). (Ned Arnold discovered and coded around this in his initial development of double buffered arrays for the scan record.) The posting is merely an advertisement that array data are available; it doesn't directly transfer array data. 4) get_array_info() is called when channel access gets an opportunity to send data to the client, and it is supplied with the field name and the buffer pointer that it wrote earlier. get_array_info() is free to write any buffer pointer it wants to the dbAddr's pfield at this time, so it can choose which data will be sent to the client. Thus, the association between an array field name and the data sent to a client monitoring that field is made by the buffer pointer written by get_array_info(), and get_array_info() has two opportunities to write that pointer: The first write (when the monitor is connected) determines what pointer the record must post to notify the client that data are available for the field. The second write (at data-transfer time) determines what data will actually be sent to the client. However, get_array_info() doesn't know whether it's doing the first write or the second write, because clients can cause get_array_info() to be called at any time. So some of the potential flexibility in this mechanism may not actually be available to the record. I think it might be ok for the record to write an artificial buffer pointer in the call to cvt_dbaddr(), and thereby to tell itself that the ensuing call to get_array_info() is for the purpose of connecting, and not the result of a monitor posting. I haven't tried this yet, but it would allow the sscan record more effectively to distinguish display clients from storage clients. (Currently, when the record posts old data to storage clients it is also posting new data to display clients, and vice-versa.) I don't, by the way, expect all this array stuff to remain backward compatible forever, just because it's being exploited by the sscan record. I haven't seen any other record that relies on these details, and I do not want be the one to quash new development in this area. If a better mechanism should be developed, I'll be happy to code to it. -- Tim Mooney ([email protected]) (630)252-5417 Beamline Controls & Data Acquisition Group Advanced Photon Source, Argonne National Lab.
| ||||||||||||||||
ANJ, 02 Sep 2010 |
·
Home
·
News
·
About
·
Base
·
Modules
·
Extensions
·
Distributions
·
Download
·
· Search · EPICS V4 · IRMIS · Talk · Bugs · Documents · Links · Licensing · |