Add context qualifier to db_field_log, support plugins for CA read operations

This commit is contained in:
Michael Davidsaver
2012-04-27 13:21:56 -04:00
parent ec7dfb1890
commit f806551fe3
4 changed files with 57 additions and 3 deletions

View File

@@ -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()
*

View File

@@ -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

View File

@@ -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 */

View File

@@ -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 );