diff --git a/documentation/RELEASE_NOTES.html b/documentation/RELEASE_NOTES.html index d6e89cc60..efec011ba 100644 --- a/documentation/RELEASE_NOTES.html +++ b/documentation/RELEASE_NOTES.html @@ -13,6 +13,20 @@ +
When a CA client gets data from an IOC record using a compound data type such +as DBR_TIME_DOUBLE the value field is fetched from the database in a +separate call than the other metadata, without keeping the record locked. This +allows some other thread such as a periodic scan thread a chance to interrupt +the get operation and process the record in between. CA monitors have always +been atomic as long as the value data isn't a string or an array, but this race +condition in the CA get path has now been fixed so the record will stay locked +between the two fetch operations.
+ +This fixes +Launchpad bug #1581212, thanks to Till Strauman and Dehong Zhang.
+The 'make runtests' and 'make tapfiles' build targets normally only run the diff --git a/src/db/db_access.c b/src/db/db_access.c index d9d0bc83f..07cce3fec 100644 --- a/src/db/db_access.c +++ b/src/db/db_access.c @@ -32,6 +32,7 @@ #include "dbCommon.h" #include "errMdef.h" #include "recSup.h" +#include "dbLock.h" #include "alarm.h" #define db_accessHFORdb_accessC #include "db_access.h" @@ -182,6 +183,8 @@ int epicsShareAPI db_get_field_and_count( * in the dbAccess.c dbGet() and getOptions() routines. */ + dbScanLock(paddr->precord); + switch(buffer_type) { case(oldDBR_STRING): status = dbGetField(paddr, DBR_STRING, pbuffer, &zero, nRequest, pfl); @@ -820,8 +823,12 @@ int epicsShareAPI db_get_field_and_count( } break; default: - return -1; + status = -1; + break; } + + dbScanUnlock(paddr->precord); + if (status) return -1; return 0; }