Comment 2 for bug 1786320

Revision history for this message
Andrew Johnson (anj) wrote :

I can explain what's happening, and guess why it was implemented this way.

Internally dbCa has 2 ways of subscribing for monitor updates, which can coexist: As the native type, and as a string. All dbCa input links subscribe for the value in the channel's native type when they first connect. This ensures that a CP/CPP link will process the record when the channel connects.

A string subscription gets added when the native type of the channel is DBF_ENUM and the record or device support calls dbCaGetLink(plink, DBR_STRING, ...). I guess this was added to get around the fact that for a long time there was no way to ask for updates whenever an ENUM's choice strings changed. If you did the conversion from the native ENUM value to a string locally on the client like we do for all of the other data types, you would get it wrong as soon as someone modifies the choice strings.

So a stringin record monitoring an ENUM channel has two subscriptions, which is exactly what you're seeing. What we *want* to happen in this case is for only the string subscription to trigger the record to process. Making that happen isn't actually very difficult, the attached patch against the 3.14 branch implements this.

However at the initial connection (or re-connection for remote links) the stringin record will still process twice. That's because it isn't until the record actually processes for the first time that the stringin device support calls dbCaGetLink(plink, DBR_STRING, ...) which is what causes the second monitor to be set up. The dbCaGetLink() code cannot block waiting for that to happen, but it should put the record into an INVALID/LINK alarm state the first time. The second scan gives the right value.

I might be able to fix the latter in EPICS 7, but it isn't really possible in earlier series.

I have not tested this patch heavily, other than to confirm that it appears to fix this issue.

- Andrew