Add context qualifier to db_field_log, support plugins for CA read operations
This commit is contained in:
@@ -626,13 +626,14 @@ int epicsShareAPI db_post_extra_labor (dbEventCtx ctx)
|
||||
* NOTE: This assumes that the db scan lock is already applied
|
||||
* (as it copies data from the record)
|
||||
*/
|
||||
static db_field_log* db_create_event_log (struct evSubscrip *pevent)
|
||||
db_field_log* epicsShareAPI db_create_event_log (struct evSubscrip *pevent)
|
||||
{
|
||||
db_field_log *pLog = (db_field_log *) freeListCalloc(dbevFieldLogFreeList);
|
||||
|
||||
if (pLog) {
|
||||
struct dbChannel *chan = pevent->chan;
|
||||
struct dbCommon *prec = dbChannelRecord(chan);
|
||||
pLog->ctx = dbfl_context_event;
|
||||
if (pevent->useValque) {
|
||||
pLog->type = dbfl_type_val;
|
||||
pLog->stat = prec->stat;
|
||||
@@ -655,6 +656,21 @@ static db_field_log* db_create_event_log (struct evSubscrip *pevent)
|
||||
return pLog;
|
||||
}
|
||||
|
||||
/*
|
||||
* DB_CREATE_READ_LOG()
|
||||
*
|
||||
*/
|
||||
db_field_log* epicsShareAPI db_create_read_log (struct dbChannel *chan)
|
||||
{
|
||||
db_field_log *pLog = (db_field_log *) freeListCalloc(dbevFieldLogFreeList);
|
||||
|
||||
if (pLog) {
|
||||
pLog->ctx = dbfl_context_read;
|
||||
pLog->type = dbfl_type_rec;
|
||||
}
|
||||
return pLog;
|
||||
}
|
||||
|
||||
/*
|
||||
* DB_QUEUE_EVENT_LOG()
|
||||
*
|
||||
|
||||
@@ -73,6 +73,8 @@ epicsShareFunc void epicsShareAPI db_post_single_event (dbEventSubscription es);
|
||||
epicsShareFunc void epicsShareAPI db_event_enable (dbEventSubscription es);
|
||||
epicsShareFunc void epicsShareAPI db_event_disable (dbEventSubscription es);
|
||||
|
||||
epicsShareFunc struct db_field_log* epicsShareAPI db_create_event_log (struct evSubscrip *pevent);
|
||||
epicsShareFunc struct db_field_log* epicsShareAPI db_create_read_log (struct dbChannel *chan);
|
||||
epicsShareFunc void epicsShareAPI db_delete_field_log (struct db_field_log *pfl);
|
||||
|
||||
#define DB_EVENT_OK 0
|
||||
|
||||
@@ -56,6 +56,12 @@ typedef enum dbfl_type {
|
||||
dbfl_type_ref
|
||||
} dbfl_type;
|
||||
|
||||
/* Context of db_field_log: event = subscription update, read = read reply */
|
||||
typedef enum dbfl_context {
|
||||
dbfl_context_read = 0,
|
||||
dbfl_context_event
|
||||
} dbfl_context;
|
||||
|
||||
#define dbflTypeStr(t) (t==dbfl_type_val?"val":t==dbfl_type_rec?"rec":"ref")
|
||||
|
||||
struct dbfl_val {
|
||||
@@ -69,7 +75,8 @@ struct dbfl_ref {
|
||||
};
|
||||
|
||||
typedef struct db_field_log {
|
||||
enum dbfl_type type; /* type (union) selector */
|
||||
enum dbfl_type type:2; /* type (union) selector */
|
||||
enum dbfl_context ctx:1; /* context (operation type) */
|
||||
epicsTimeStamp time; /* Time stamp */
|
||||
unsigned short stat; /* Alarm Status */
|
||||
unsigned short sevr; /* Alarm Severity */
|
||||
|
||||
@@ -508,6 +508,7 @@ static void read_reply ( void *pArg, struct dbChannel *dbch,
|
||||
int status;
|
||||
int v41;
|
||||
int autosize;
|
||||
int local_fl = 0;
|
||||
long item_count;
|
||||
ca_uint32_t payload_size;
|
||||
dbAddr *paddr=&dbch->addr;
|
||||
@@ -565,8 +566,21 @@ 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 ) {
|
||||
/*
|
||||
* I cant wait to redesign this protocol from scratch!
|
||||
@@ -647,6 +661,8 @@ static int read_action ( caHdrLargeArray *mp, void *pPayloadIn, struct client *p
|
||||
void *pPayload;
|
||||
int status;
|
||||
int v41;
|
||||
int local_fl = 0;
|
||||
db_field_log *pfl = NULL;
|
||||
|
||||
if ( ! pciu ) {
|
||||
logBadId ( pClient, mp, 0 );
|
||||
@@ -689,8 +705,21 @@ 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, 0 );
|
||||
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 );
|
||||
|
||||
Reference in New Issue
Block a user