Subject: |
Re: Lock/Mutex to prevent "caget" from cutting in between updating multiple fields |
From: |
Andrew Johnson <[email protected]> |
To: |
<[email protected]> |
Date: |
Tue, 3 May 2016 14:15:09 -0500 |
Hi Dehong,
On 05/03/2016 12:31 PM, Zhang, Dehong wrote:
> From the name, dbScanLock() seems to be for updating (writing) requests from outside
> the record. Of course the record support itself can also call it, when the record wants to
> update itself, to block updating requests from outside. Is it easy to let the CA server
> also call it when the CA server wants to reply to "caget" or broadcast to the "camonitor"
> list.
You are mistaken there, dbScanLock() is always called before *anything*
accesses a record field, for either reading or writing data. For CA
requests the path from the RSRV server is always via
db_get_field() => dbGetField() => dbScanLock()
no matter whether the request is directly from a CA Get request or from
the thread at the low-priority end of an event queue that is sending out
a monitor update. A similar path applies to CA Put requests, and for
record scanning dbScanLock() is called before entering the record's
process() routine.
The reason why for arrays and string values the alarm+timestamp data may
come from a different update than the value data is that the
alarm+timestamp are saved into the event queues by the call to
db_post_events() inside the record's process() routine, but the objects
we put onto those queues are too small to hold more than 8 bytes of
value data. Every CA client gets an event queue with storage for at
least 128 of these objects, so we don't want to make them too large.
For the larger data types the queue instead stores a pointer to the
original data, and when the objects are read out of the queues by the
low-priority threads that forward them to each client they call
db_get_field() a second time (the first time was on entry to the queue)
which again locks the record before extracting just the value data from
the stored pointer. The alarm+timestamp from the event queue are
provided in the db_field_log object pflin that is also passed to
db_get_field(). However while the update was waiting on the event queue
the record was unlocked, so it is possible for another thread to lock
the record and cause it to process first, thus changing the data in the
array/string being monitored.
Note also that if you have 2 different CA clients monitoring the same
PV, it is possible for a single db_post_events() call to result in the 2
clients seeing different data for the same alarm+timestamp, since each
client has its own queue and and its own low-priority thread that reads
out the event queue and forwards the data to the appropriate TCP socket.
The low priority threads are not synchronized, they each have to call
db_get_field() independently and at different times (in order to get
access to the record data they must take the lock, which is a mutex so
only one of them can "own" the record at once even if they're only
reading from it).
It is actually relatively easy to increase the size of the db_field_log
object so it can store a 40 character DBF_STRING value, but making it
larger than that would have no effect other than wasting memory. IOC
memory sizes have grown since the event queue code was written, and we
should now be able to afford the extra RAM needed by the IOC (32 bytes
extra * 128 items = 4KB minimum per CA client).
HTH,
- 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
- Replies:
- Re: Lock/Mutex to prevent "caget" from cutting in between updating multiple fields Till Straumann
- References:
- Lock/Mutex to prevent "caget" from cutting in between updating multiple fields Zhang, Dehong
- RE: Lock/Mutex to prevent "caget" from cutting in between updating multiple fields Mooney, Tim M.
- Re: Lock/Mutex to prevent "caget" from cutting in between updating multiple fields Till Straumann
- Re: Lock/Mutex to prevent "caget" from cutting in between updating multiple fields Zhang, Dehong
- Re: Lock/Mutex to prevent "caget" from cutting in between updating multiple fields Till Straumann
- RE: Lock/Mutex to prevent "caget" from cutting in between updating multiple fields Kim, Kukhee
- Re: Lock/Mutex to prevent "caget" from cutting in between updating multiple fields Zhang, Dehong
- Navigate by Date:
- Prev:
RE: Lock/Mutex to prevent "caget" from cutting in between updating multiple fields Kim, Kukhee
- Next:
EPICS and CANbus? Grelle, Austin L.
- Index:
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
<2016>
2017
2018
2019
2020
2021
2022
2023
2024
- Navigate by Thread:
- Prev:
RE: Lock/Mutex to prevent "caget" from cutting in between updating multiple fields Kim, Kukhee
- Next:
Re: Lock/Mutex to prevent "caget" from cutting in between updating multiple fields Till Straumann
- Index:
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
<2016>
2017
2018
2019
2020
2021
2022
2023
2024
|