Skip to content

Commit

Permalink
db: lock record for db_create_read_log() and dbChannelGetField()
Browse files Browse the repository at this point in the history
since 27fe3e4 db_create_read_log()
accesses record fields.

remove now redundant db_create_read_log() calls.
  • Loading branch information
mdavidsaver committed Dec 28, 2024
1 parent 1699489 commit 8118d8f
Show file tree
Hide file tree
Showing 6 changed files with 37 additions and 55 deletions.
12 changes: 12 additions & 0 deletions modules/database/src/ioc/db/dbChannel.c
Original file line number Diff line number Diff line change
Expand Up @@ -635,9 +635,21 @@ long dbChannelGetField(dbChannel *chan, short dbrType, void *pbuffer,
{
dbCommon *precord = chan->addr.precord;
long status = 0;
unsigned char local_fl = 0;

dbScanLock(precord);
if (!pfl && (ellCount(&chan->pre_chain) || ellCount(&chan->post_chain))) {
pfl = db_create_read_log(chan);
if (pfl) {
local_fl = 1;
pfl = dbChannelRunPreChain(chan, pfl);
pfl = dbChannelRunPostChain(chan, pfl);
}
}
status = dbChannelGet(chan, dbrType, pbuffer, options, nRequest, pfl);
if (local_fl) {
db_delete_field_log(pfl);
}
dbScanUnlock(precord);
return status;
}
Expand Down
4 changes: 4 additions & 0 deletions modules/database/src/ioc/db/dbChannel.h
Original file line number Diff line number Diff line change
Expand Up @@ -511,6 +511,10 @@ DBCORE_API long dbChannelGet(dbChannel *chan, short type,
* \param[in,out] nRequest Pointer to the element count.
* \param[in] pfl Pointer to a db_field_log or NULL.
* \returns 0, or an error status value.
*
* \since UNRELEASED If pfl is NULL and chan has filters, db_create_read_log() will be called
* internally to create a temporary db_field_log which is passed to dbChannelGet()
* then deallocated.
*/
DBCORE_API long dbChannelGetField(dbChannel *chan, short type,
void *pbuffer, long *options, long *nRequest, void *pfl);
Expand Down
29 changes: 2 additions & 27 deletions modules/database/src/ioc/db/dbUnitTest.c
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,6 @@ void testdbGetFieldEqual(const char* pv, int dbrType, ...)
void testdbVGetFieldEqual(const char* pv, short dbrType, va_list ap)
{
dbChannel *chan = dbChannelCreate(pv);
db_field_log *pfl = NULL;
long nReq = 1;
union anybuf pod;
long status = S_dbLib_recNotFound;
Expand All @@ -212,18 +211,7 @@ void testdbVGetFieldEqual(const char* pv, short dbrType, va_list ap)
goto done;
}

if(ellCount(&chan->filters)) {
pfl = db_create_read_log(chan);
if (!pfl) {
testFail("can't db_create_read_log w/ %s", pv);
goto done;
}

pfl = dbChannelRunPreChain(chan, pfl);
pfl = dbChannelRunPostChain(chan, pfl);
}

status = dbChannelGetField(chan, dbrType, pod.bytes, NULL, &nReq, pfl);
status = dbChannelGetField(chan, dbrType, pod.bytes, NULL, &nReq, NULL);
if (status) {
testFail("dbGetField(\"%s\", %d, ...) -> %#lx (%s)", pv, dbrType, status, errSymMsg(status));
goto done;
Expand Down Expand Up @@ -261,7 +249,6 @@ void testdbVGetFieldEqual(const char* pv, short dbrType, va_list ap)
}

done:
db_delete_field_log(pfl);
if(chan)
dbChannelDelete(chan);
}
Expand All @@ -288,7 +275,6 @@ void testdbPutArrFieldOk(const char* pv, short dbrType, unsigned long count, con
void testdbGetArrFieldEqual(const char* pv, short dbfType, long nRequest, unsigned long cnt, const void *pbufraw)
{
dbChannel *chan = dbChannelCreate(pv);
db_field_log *pfl = NULL;
const long vSize = dbValueSize(dbfType);
const long nStore = vSize * nRequest;
long status = S_dbLib_recNotFound;
Expand All @@ -300,24 +286,13 @@ void testdbGetArrFieldEqual(const char* pv, short dbfType, long nRequest, unsign
goto done;
}

if(ellCount(&chan->filters)) {
pfl = db_create_read_log(chan);
if (!pfl) {
testFail("can't db_create_read_log w/ %s", pv);
goto done;
}

pfl = dbChannelRunPreChain(chan, pfl);
pfl = dbChannelRunPostChain(chan, pfl);
}

gbuf = gstore = malloc(nStore);
if(!gbuf && nStore!=0) { /* note that malloc(0) is allowed to return NULL on success */
testFail("Allocation failed esize=%ld total=%ld", vSize, nStore);
return;
}

status = dbChannelGetField(chan, dbfType, gbuf, NULL, &nRequest, pfl);
status = dbChannelGetField(chan, dbfType, gbuf, NULL, &nRequest, NULL);
if (status) {
testFail("dbGetField(\"%s\", %d, ...) -> %#lx", pv, dbfType, status);

Expand Down
13 changes: 13 additions & 0 deletions modules/database/src/ioc/db/db_access.c
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,7 @@ int dbChannel_get_count(
long options;
long i;
long zero = 0;
unsigned char local_fl = 0;

/* The order of the DBR* elements in the "newSt" structures below is
* very important and must correspond to the order of processing
Expand All @@ -156,6 +157,16 @@ int dbChannel_get_count(

dbScanLock(dbChannelRecord(chan));

/* If filters are involved in a read, create field log and run filters */
if (!pfl && (ellCount(&chan->pre_chain) || ellCount(&chan->post_chain))) {
pfl = db_create_read_log(chan);
if (pfl) {
local_fl = 1;
pfl = dbChannelRunPreChain(chan, pfl);
pfl = dbChannelRunPostChain(chan, pfl);
}
}

switch(buffer_type) {
case(oldDBR_STRING):
status = dbChannelGet(chan, DBR_STRING, pbuffer, &zero, nRequest, pfl);
Expand Down Expand Up @@ -800,6 +811,8 @@ int dbChannel_get_count(

dbScanUnlock(dbChannelRecord(chan));

if (local_fl) db_delete_field_log(pfl);

if (status) return -1;
return 0;
}
Expand Down
26 changes: 0 additions & 26 deletions modules/database/src/ioc/rsrv/camessage.c
Original file line number Diff line number Diff line change
Expand Up @@ -493,7 +493,6 @@ static void read_reply ( void *pArg, struct dbChannel *dbch,
const int readAccess = asCheckGet ( pciu->asClientPVT );
int status;
int autosize;
int local_fl = 0;
long item_count;
ca_uint32_t payload_size;
dbAddr *paddr=&dbch->addr;
Expand Down Expand Up @@ -535,21 +534,9 @@ static void read_reply ( void *pArg, struct dbChannel *dbch,
return;
}

/* If filters are involved in a read, create field log and run filters */
if (!pfl && (ellCount(&dbch->pre_chain) || ellCount(&dbch->post_chain))) {
pfl = db_create_read_log(dbch);
if (pfl) {
local_fl = 1;
pfl = dbChannelRunPreChain(dbch, pfl);
pfl = dbChannelRunPostChain(dbch, pfl);
}
}

status = dbChannel_get_count ( dbch, pevext->msg.m_dataType,
pPayload, &item_count, pfl);

if (local_fl) db_delete_field_log(pfl);

if ( status < 0 ) {
/* Clients recv the status of the operation directly to the
* event/put/get callback. (from CA_V41())
Expand Down Expand Up @@ -616,7 +603,6 @@ static int read_action ( caHdrLargeArray *mp, void *pPayloadIn, struct client *p
ca_uint32_t payloadSize;
void *pPayload;
int status;
int local_fl = 0;
db_field_log *pfl = NULL;

if ( ! pciu ) {
Expand Down Expand Up @@ -655,21 +641,9 @@ static int read_action ( caHdrLargeArray *mp, void *pPayloadIn, struct client *p
return RSRV_OK;
}

/* If filters are involved in a read, create field log and run filters */
if (ellCount(&pciu->dbch->pre_chain) || ellCount(&pciu->dbch->post_chain)) {
pfl = db_create_read_log(pciu->dbch);
if (pfl) {
local_fl = 1;
pfl = dbChannelRunPreChain(pciu->dbch, pfl);
pfl = dbChannelRunPostChain(pciu->dbch, pfl);
}
}

status = dbChannel_get ( pciu->dbch, mp->m_dataType,
pPayload, mp->m_count, pfl );

if (local_fl) db_delete_field_log(pfl);

if ( status < 0 ) {
send_err ( mp, ECA_GETFAIL, pClient, RECORD_NAME ( pciu->dbch ) );
SEND_UNLOCK ( pClient );
Expand Down
8 changes: 6 additions & 2 deletions modules/database/test/ioc/db/dbChArrTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -130,9 +130,11 @@ static void check(short dbr_type) {
off = Offset; req = 10; \
memset(buf, 0, sizeof(buf)); \
(void) dbPutField(&offaddr, DBR_LONG, &off, 1); \
dbScanLock(dbChannelRecord(pch)); \
pfl = db_create_read_log(pch); \
testOk(pfl && pfl->type == dbfl_type_ref, "Valid pfl, type = ref"); \
testOk(!dbChannelGetField(pch, DBR_LONG, buf, NULL, &req, pfl), "Got Field value"); \
testOk(!dbChannelGet(pch, DBR_LONG, buf, NULL, &req, pfl), "Got Field value"); \
dbScanUnlock(dbChannelRecord(pch)); \
testOk(req == Size, "Got %ld elements (expected %d)", req, Size); \
if (!testOk(!memcmp(buf, Expected, sizeof(Expected)), "Data correct")) \
for (i=0; i<Size; i++) \
Expand Down Expand Up @@ -174,14 +176,16 @@ static void check(short dbr_type) {
off = Offset; req = 15; \
memset(buf, 0, sizeof(buf)); \
(void) dbPutField(&offaddr, DBR_LONG, &off, 1); \
dbScanLock(dbChannelRecord(pch)); \
pfl = db_create_read_log(pch); \
pfl->type = dbfl_type_ref; \
pfl->field_type = DBF_CHAR; \
pfl->field_size = 1; \
pfl->no_elements = 26; \
pfl->dtor = freeArray; \
pfl->u.r.field = epicsStrDup("abcdefghijklmnopqrsstuvwxyz"); \
testOk(!dbChannelGetField(pch, DBR_LONG, buf, NULL, &req, pfl), "Got Field value"); \
testOk(!dbChannelGet(pch, DBR_LONG, buf, NULL, &req, pfl), "Got Field value"); \
dbScanUnlock(dbChannelRecord(pch)); \
testOk(req == Size, "Got %ld elements (expected %d)", req, Size); \
if (!testOk(!memcmp(buf, Expected, sizeof(Expected)), "Data correct")) \
for (i=0; i<Size; i++) \
Expand Down

0 comments on commit 8118d8f

Please sign in to comment.