Restructured pre- and post-event queue chains, type/size change detection
* Add new db_field_log type "probe" for type change detection * Move linked lists for pre- and post-event-queue chains into dbChannel, function pointers and arguments into chFilter * Remove set-type-chain completely * Simplify register functions in filter and plugin interfaces * Add functions to run the pre and post chains to dbChannel * Refactor in db_field_log: field_size -> element_size * Refactor in dbEvent: db_post_single_event_first -> db_create_event_log db_post_single_event_final -> db_queue_event_log (removed from public interface) * Change tests to compile
This commit is contained in:
committed by
Michael Davidsaver
parent
b99975cf71
commit
c41fcef260
@@ -480,38 +480,24 @@ static long channel_open(chFilter *filter)
|
||||
else return 0;
|
||||
}
|
||||
|
||||
static void channel_register_pre_eventq(chFilter *filter,
|
||||
chPostEventFunc *pe_in, void *pe_arg_in,
|
||||
chSetTypeFunc *st_in, void *st_arg_in,
|
||||
chPostEventFunc **pe_out, void **pe_arg_out,
|
||||
chSetTypeFunc **st_out, void **st_arg_out)
|
||||
static void channel_register_pre(chFilter *filter,
|
||||
chPostEventFunc **cb_out, void **arg_out)
|
||||
{
|
||||
chfPlugin *p = (chfPlugin*) filter->plug->puser;
|
||||
chfFilter *f = (chfFilter*) filter->puser;
|
||||
|
||||
if (p->pif->channelRegisterPreEventQue)
|
||||
p->pif->channelRegisterPreEventQue(filter->chan, f->puser,
|
||||
pe_in, pe_arg_in,
|
||||
st_in, st_arg_in,
|
||||
pe_out, pe_arg_out,
|
||||
st_out, st_arg_out);
|
||||
if (p->pif->channelRegisterPre)
|
||||
p->pif->channelRegisterPre(filter->chan, f->puser, cb_out, arg_out);
|
||||
}
|
||||
|
||||
static void channel_register_post_eventq(chFilter *filter,
|
||||
chPostEventFunc *pe_in, void *pe_arg_in,
|
||||
chSetTypeFunc *st_in, void *st_arg_in,
|
||||
chPostEventFunc **pe_out, void **pe_arg_out,
|
||||
chSetTypeFunc **st_out, void **st_arg_out)
|
||||
static void channel_register_post(chFilter *filter,
|
||||
chPostEventFunc **cb_out, void **arg_out)
|
||||
{
|
||||
chfPlugin *p = (chfPlugin*) filter->plug->puser;
|
||||
chfFilter *f = (chfFilter*) filter->puser;
|
||||
|
||||
if (p->pif->channelRegisterPostEventQue)
|
||||
p->pif->channelRegisterPostEventQue(filter->chan, f->puser,
|
||||
pe_in, pe_arg_in,
|
||||
st_in, st_arg_in,
|
||||
pe_out, pe_arg_out,
|
||||
st_out, st_arg_out);
|
||||
if (p->pif->channelRegisterPost)
|
||||
p->pif->channelRegisterPost(filter->chan, f->puser, cb_out, arg_out);
|
||||
}
|
||||
|
||||
static void channel_report(chFilter *filter, const char *intro, int level)
|
||||
@@ -519,7 +505,8 @@ static void channel_report(chFilter *filter, const char *intro, int level)
|
||||
chfPlugin *p = (chfPlugin*) filter->plug->puser;
|
||||
chfFilter *f = (chfFilter*) filter->puser;
|
||||
|
||||
if (p->pif->channel_report) p->pif->channel_report(filter->chan, f->puser, intro, level);
|
||||
if (p->pif->channel_report)
|
||||
p->pif->channel_report(filter->chan, f->puser, intro, level);
|
||||
}
|
||||
|
||||
static void channel_close(chFilter *filter)
|
||||
@@ -556,8 +543,8 @@ static chFilterIf wrapper_fif = {
|
||||
NULL, /* parse_end_array, */
|
||||
|
||||
channel_open,
|
||||
channel_register_pre_eventq,
|
||||
channel_register_post_eventq,
|
||||
channel_register_pre,
|
||||
channel_register_post,
|
||||
channel_report,
|
||||
channel_close
|
||||
};
|
||||
|
||||
@@ -137,38 +137,19 @@ typedef struct chfPluginIf {
|
||||
* This function is called to establish the stack of plugins that an event
|
||||
* is passed through between the database and the event queue.
|
||||
*
|
||||
* The plugin must call the supplied 'pe_in' function (usually within
|
||||
* its own post-event callback) with 'pe_arg_in' as first argument to forward
|
||||
* the data to the next plugin towards the event queue.
|
||||
* It must set pe_out to point to its own post-event callback in order to be
|
||||
* called when a data update is sent from the database towards the event queue.
|
||||
*
|
||||
* The plugin must call the supplied 'st_in' function (from within
|
||||
* its own set-type callback) with 'st_arg_in' as first argument after changing
|
||||
* the data type and/or array size of 'chan'.
|
||||
* The plugin must set pe_out to point to its own post-event callback in order
|
||||
* to be called when a data update is sent from the database towards the
|
||||
* event queue.
|
||||
*
|
||||
* @param chan dbChannel for which the connection is being made.
|
||||
* @param pvt Pointer to private structure.
|
||||
* @param pe_in Pointer to the next plugin's post-event callback
|
||||
* @param pe_arg_in Argument that must be supplied when this plugin calls
|
||||
* the next plugin's post-event callback
|
||||
* @param st_in Pointer to the next plugin's set-type callback
|
||||
* @param st_arg_in Argument that must be supplied when this plugin calls
|
||||
* the next plugin's set-type callback
|
||||
* @param pe_out Pointer to this plugin's post-event callback (set to NULL to bypass
|
||||
* this plugin)
|
||||
* @param pe_arg_out Argument that must be supplied when calling
|
||||
* this plugin's post-event callback
|
||||
* @param st_out Pointer to this plugin's set-type callback (set to NULL if plugin
|
||||
* does not change the data type or size)
|
||||
* @param st_arg_out Argument that must be supplied when calling
|
||||
* this plugin's set-type callback
|
||||
* @param cb_out Pointer to this plugin's post-event callback (NULL to bypass
|
||||
* this plugin).
|
||||
* @param arg_out Argument that must be supplied when calling
|
||||
* this plugin's post-event callback.
|
||||
*/
|
||||
void (* channelRegisterPreEventQue) (dbChannel *chan, void *pvt,
|
||||
chPostEventFunc *pe_in, void *pe_arg_in,
|
||||
chSetTypeFunc *st_in, void *st_arg_in,
|
||||
chPostEventFunc **pe_out, void **pe_arg_out,
|
||||
chSetTypeFunc **st_out, void **st_arg_out);
|
||||
void (* channelRegisterPre) (dbChannel *chan, void *pvt,
|
||||
chPostEventFunc **cb_out, void **arg_out);
|
||||
|
||||
/** @brief Register callbacks for post-event-queue operation.
|
||||
*
|
||||
@@ -178,12 +159,9 @@ typedef struct chfPluginIf {
|
||||
* is passed through between the event queue and the final user (CA server or
|
||||
* database access).
|
||||
*
|
||||
* The plugin must call the supplied 'pe_in' function (usually within
|
||||
* its own post-event callback) with 'arg_in' as first argument to forward
|
||||
* the data to the next plugin towards the final user.
|
||||
* It must set pe_out to point to its own post-event callback in order to be
|
||||
* called when a data update is sent from the event queue towards the final
|
||||
* user.
|
||||
* The plugin must set pe_out to point to its own post-event callback in order
|
||||
* to be called when a data update is sent from the event queue towards the
|
||||
* final user.
|
||||
*
|
||||
* The plugin must call the supplied 'st_in' function (from within
|
||||
* its own set-type callback) with 'arg_in' as first argument after changing
|
||||
@@ -191,26 +169,13 @@ typedef struct chfPluginIf {
|
||||
*
|
||||
* @param chan dbChannel for which the connection is being made.
|
||||
* @param pvt Pointer to private structure.
|
||||
* @param pe_in Pointer to the next plugin's post-event callback
|
||||
* @param pe_arg_in Argument that must be supplied when this plugin calls
|
||||
* the next plugin's post-event callback
|
||||
* @param st_in Pointer to the next plugin's set-type callback
|
||||
* @param st_arg_in Argument that must be supplied when this plugin calls
|
||||
* the next plugin's set-type callback
|
||||
* @param pe_out Pointer to this plugin's post-event callback (set to NULL to bypass
|
||||
* this plugin)
|
||||
* @param pe_arg_out Argument that must be supplied when calling
|
||||
* this plugin's post-event callback
|
||||
* @param st_out Pointer to this plugin's set-type callback (set to NULL if plugin
|
||||
* does not change the data type or size)
|
||||
* @param st_arg_out Argument that must be supplied when calling
|
||||
* this plugin's set-type callback
|
||||
* @param cb_out Pointer to this plugin's post-event callback (NULL to bypass
|
||||
* this plugin).
|
||||
* @param arg_out Argument that must be supplied when calling
|
||||
* this plugin's post-event callback.
|
||||
*/
|
||||
void (* channelRegisterPostEventQue) (dbChannel *chan, void *pvt,
|
||||
chPostEventFunc *pe_in, void *pe_arg_in,
|
||||
chSetTypeFunc *st_in, void *st_arg_in,
|
||||
chPostEventFunc **pe_out, void **pe_arg_out,
|
||||
chSetTypeFunc **st_out, void **st_arg_out);
|
||||
void (* channelRegisterPost) (dbChannel *chan, void *pvt,
|
||||
chPostEventFunc **cb_out, void **arg_out);
|
||||
|
||||
/** @brief Channel report request.
|
||||
*
|
||||
|
||||
@@ -838,9 +838,9 @@ long epicsShareAPI dbGet(DBADDR *paddr, short dbrType,
|
||||
} else {
|
||||
DBADDR localAddr = *paddr; /* Structure copy */
|
||||
localAddr.field_type = pfl->field_type;
|
||||
localAddr.field_size = pfl->field_size;
|
||||
localAddr.field_size = pfl->element_size;
|
||||
localAddr.no_elements = pfl->no_elements;
|
||||
if (pfl->type == dbfl_type_val)
|
||||
if (pfl->type == dbfl_type_value)
|
||||
localAddr.pfield = (char *) &pfl->u.v.field;
|
||||
else
|
||||
localAddr.pfield = (char *) pfl->u.r.field;
|
||||
@@ -874,9 +874,9 @@ long epicsShareAPI dbGet(DBADDR *paddr, short dbrType,
|
||||
} else {
|
||||
DBADDR localAddr = *paddr; /* Structure copy */
|
||||
localAddr.field_type = pfl->field_type;
|
||||
localAddr.field_size = pfl->field_size;
|
||||
localAddr.field_size = pfl->element_size;
|
||||
localAddr.no_elements = pfl->no_elements;
|
||||
if (pfl->type == dbfl_type_val)
|
||||
if (pfl->type == dbfl_type_value)
|
||||
localAddr.pfield = (char *) &pfl->u.v.field;
|
||||
else
|
||||
localAddr.pfield = (char *) pfl->u.r.field;
|
||||
|
||||
@@ -346,6 +346,8 @@ dbChannel * dbChannelCreate(const char *name)
|
||||
chan = (dbChannel *) callocMustSucceed(1, sizeof(*chan), "dbChannelCreate");
|
||||
chan->name = strdup(name); /* FIXME: free-list */
|
||||
ellInit(&chan->filters);
|
||||
ellInit(&chan->pre_chain);
|
||||
ellInit(&chan->post_chain);
|
||||
|
||||
paddr = &chan->addr;
|
||||
pflddes = dbEntry.pflddes;
|
||||
@@ -413,89 +415,95 @@ finish:
|
||||
return chan;
|
||||
}
|
||||
|
||||
static void setFinalType(void *pvt, long no_elements, short field_type, short element_size) {
|
||||
dbChannel *chan = (dbChannel*) pvt;
|
||||
db_field_log* dbChannelRunPreChain(dbChannel *chan, db_field_log *pLogIn) {
|
||||
chFilter *filter;
|
||||
ELLNODE *node;
|
||||
db_field_log *pLog = pLogIn;
|
||||
|
||||
chan->final_no_elements = no_elements;
|
||||
chan->final_element_size = element_size;
|
||||
chan->final_type = field_type;
|
||||
chan->dbr_final_type = dbDBRnewToDBRold[mapDBFToDBR[field_type]];
|
||||
for (node = ellFirst(&chan->pre_chain); node; node = ellNext(node)) {
|
||||
filter = CONTAINER(node, chFilter, pre_node);
|
||||
pLog = filter->pre_func(filter->pre_arg, chan, pLog);
|
||||
}
|
||||
return pLog;
|
||||
}
|
||||
|
||||
db_field_log* dbChannelRunPostChain(dbChannel *chan, db_field_log *pLogIn) {
|
||||
chFilter *filter;
|
||||
ELLNODE *node;
|
||||
db_field_log *pLog = pLogIn;
|
||||
|
||||
for (node = ellFirst(&chan->post_chain); node; node = ellNext(node)) {
|
||||
filter = CONTAINER(node, chFilter, post_node);
|
||||
pLog = filter->post_func(filter->post_arg, chan, pLog);
|
||||
}
|
||||
return pLog;
|
||||
}
|
||||
|
||||
long dbChannelOpen(dbChannel *chan)
|
||||
{
|
||||
chFilter *filter;
|
||||
long status = 0;
|
||||
chPostEventFunc *pre_pe_next = db_post_single_event_final;
|
||||
void *pre_nextarg = NULL;
|
||||
chPostEventFunc *pre_pe_this = NULL;
|
||||
void *pre_thisarg = NULL;
|
||||
chPostEventFunc *post_pe_next = NULL;
|
||||
void *post_nextarg = NULL;
|
||||
chPostEventFunc *post_pe_this = NULL;
|
||||
void *post_thisarg = NULL;
|
||||
chSetTypeFunc *st_next = setFinalType;
|
||||
void *st_nextarg = chan;
|
||||
chSetTypeFunc *st_this = NULL;
|
||||
void *st_thisarg = NULL;
|
||||
chPostEventFunc *func;
|
||||
void *arg;
|
||||
long status;
|
||||
|
||||
filter = (chFilter *) ellFirst(&chan->filters);
|
||||
while (filter) {
|
||||
status = filter->plug->fif->channel_open(filter);
|
||||
if (status) goto finish;
|
||||
/*
|
||||
* Call channel_open for all filters
|
||||
*/
|
||||
status = 0;
|
||||
if (filter->plug->fif->channel_open)
|
||||
status = filter->plug->fif->channel_open(filter);
|
||||
if (status) return status;
|
||||
|
||||
/*
|
||||
* Build up the pre- and post-event-queue filter chains
|
||||
*/
|
||||
func = NULL;
|
||||
arg = NULL;
|
||||
if (filter->plug->fif->channel_register_post) {
|
||||
filter->plug->fif->channel_register_post(filter, &func, &arg);
|
||||
if (func) {
|
||||
ellAdd(&chan->post_chain, &filter->post_node);
|
||||
filter->post_func = func;
|
||||
filter->post_arg = arg;
|
||||
}
|
||||
}
|
||||
func = NULL;
|
||||
arg = NULL;
|
||||
if (filter->plug->fif->channel_register_pre) {
|
||||
filter->plug->fif->channel_register_pre(filter, &func, &arg);
|
||||
if (func) {
|
||||
ellAdd(&chan->pre_chain, &filter->pre_node);
|
||||
filter->pre_func = func;
|
||||
filter->pre_arg = arg;
|
||||
}
|
||||
}
|
||||
|
||||
filter = (chFilter *) ellNext(&filter->node);
|
||||
}
|
||||
|
||||
/*
|
||||
* Build up the post-event-queue and pre-event-queue filter chains.
|
||||
* Must be done top-down and separate, since there is only one callback chain
|
||||
* for type/size changes.
|
||||
*/
|
||||
filter = (chFilter *) ellLast(&chan->filters);
|
||||
while (filter && filter->plug->fif->channel_register_post_eventq) {
|
||||
filter->plug->fif->channel_register_post_eventq(filter,
|
||||
post_pe_next, post_nextarg,
|
||||
st_next, st_nextarg,
|
||||
&post_pe_this, &post_thisarg,
|
||||
&st_this, &st_thisarg);
|
||||
if (post_pe_this) {
|
||||
post_pe_next = post_pe_this;
|
||||
post_nextarg = post_thisarg;
|
||||
}
|
||||
if (st_this) {
|
||||
st_next = st_this;
|
||||
st_nextarg = st_thisarg;
|
||||
}
|
||||
filter = (chFilter *) ellPrevious(&filter->node);
|
||||
}
|
||||
chan->post_event_cb = post_pe_next;
|
||||
chan->post_event_arg = post_nextarg;
|
||||
/* Set up type probe */
|
||||
db_field_log probe;
|
||||
db_field_log *pfl;
|
||||
probe.type = dbfl_type_probe;
|
||||
probe.field_type = dbChannelFieldType(chan);
|
||||
probe.no_elements = dbChannelElements(chan);
|
||||
probe.element_size = dbChannelElementSize(chan);
|
||||
|
||||
filter = (chFilter *) ellLast(&chan->filters);
|
||||
while (filter && filter->plug->fif->channel_register_pre_eventq) {
|
||||
filter->plug->fif->channel_register_pre_eventq(filter,
|
||||
pre_pe_next, pre_nextarg,
|
||||
st_next, st_nextarg,
|
||||
&pre_pe_this, &pre_thisarg,
|
||||
&st_this, &st_thisarg);
|
||||
if (pre_pe_this) {
|
||||
pre_pe_next = pre_pe_this;
|
||||
pre_nextarg = pre_thisarg;
|
||||
}
|
||||
if (st_this) {
|
||||
st_next = st_this;
|
||||
st_nextarg = st_thisarg;
|
||||
}
|
||||
filter = (chFilter *) ellPrevious(&filter->node);
|
||||
}
|
||||
chan->pre_event_cb = pre_pe_next;
|
||||
chan->pre_event_arg = pre_nextarg;
|
||||
/* Call filter chains to determine data type/size changes */
|
||||
pfl = dbChannelRunPreChain(chan, &probe);
|
||||
if (pfl != &probe) return -1;
|
||||
pfl = dbChannelRunPostChain(chan, &probe);
|
||||
if (pfl != &probe) return -1;
|
||||
|
||||
/* Call filter chain to determine data type/size changes */
|
||||
if (st_next) st_next(st_nextarg, chan->addr.no_elements, chan->addr.field_type, chan->addr.field_size);
|
||||
/* Save probe results */
|
||||
chan->final_no_elements = probe.no_elements;
|
||||
chan->final_element_size = probe.element_size;
|
||||
chan->final_type = probe.field_type;
|
||||
chan->dbr_final_type = dbDBRnewToDBRold[mapDBFToDBR[probe.field_type]];
|
||||
|
||||
finish:
|
||||
return status;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* FIXME: For performance we should make these one-liners into macros,
|
||||
|
||||
@@ -41,26 +41,21 @@ typedef struct evSubscrip {
|
||||
|
||||
typedef struct chFilter chFilter;
|
||||
|
||||
/* Prototype for the post event function that is called recursively in filter stacks */
|
||||
typedef void (chPostEventFunc)(void *pvt, struct evSubscrip *event, db_field_log *pLog);
|
||||
|
||||
/* A dbChannel points to a record field, and can have multiple filters */
|
||||
typedef struct dbChannel {
|
||||
const char *name;
|
||||
dbAddr addr;
|
||||
dbAddr addr; /* address structure for record/field */
|
||||
long final_no_elements; /* final number of elements (arrays) */
|
||||
short final_element_size; /* final size of element */
|
||||
short final_type; /* final type of database field */
|
||||
short dbr_final_type; /* final field type as seen by database request */
|
||||
chPostEventFunc *pre_event_cb;
|
||||
void *pre_event_arg;
|
||||
chPostEventFunc *post_event_cb;
|
||||
void *post_event_arg;
|
||||
ELLLIST filters;
|
||||
ELLLIST filters; /* list of filters as created from JSON */
|
||||
ELLLIST pre_chain; /* list of filters to be called pre-event-queue */
|
||||
ELLLIST post_chain; /* list of filters to be called post-event-queue */
|
||||
} dbChannel;
|
||||
|
||||
/* Prototype for the set type function that is called recursively in filter stacks */
|
||||
typedef void (chSetTypeFunc)(void *pvt, long no_elements, short field_type, short element_size);
|
||||
/* Prototype for the post event function that is called in filter stacks */
|
||||
typedef db_field_log* (chPostEventFunc)(void *pvt, dbChannel *chan, db_field_log *pLog);
|
||||
|
||||
/* Return values from chFilterIf->parse_* routines: */
|
||||
typedef enum {
|
||||
@@ -102,16 +97,8 @@ typedef struct chFilterIf {
|
||||
|
||||
/* Channel operations: */
|
||||
long (* channel_open)(chFilter *filter);
|
||||
void (* channel_register_pre_eventq) (chFilter *filter,
|
||||
chPostEventFunc *pe_in, void *arg_pe_in,
|
||||
chSetTypeFunc *st_in, void *arg_st_in,
|
||||
chPostEventFunc **pe_out, void **arg_pe_out,
|
||||
chSetTypeFunc **st_out, void **arg_st_out);
|
||||
void (* channel_register_post_eventq)(chFilter *filter,
|
||||
chPostEventFunc *pe_in, void *arg_pe_in,
|
||||
chSetTypeFunc *st_in, void *arg_st_in,
|
||||
chPostEventFunc **pe_out, void **arg_pe_out,
|
||||
chSetTypeFunc **st_out, void **arg_st_out);
|
||||
void (* channel_register_pre) (chFilter *filter, chPostEventFunc **cb_out, void **arg_out);
|
||||
void (* channel_register_post)(chFilter *filter, chPostEventFunc **cb_out, void **arg_out);
|
||||
void (* channel_report)(chFilter *filter, const char *intro, int level);
|
||||
/* FIXME: More filter routines here ... */
|
||||
void (* channel_close)(chFilter *filter);
|
||||
@@ -128,8 +115,14 @@ typedef struct chFilterPlugin {
|
||||
/* A chFilter holds data for a single filter instance */
|
||||
struct chFilter {
|
||||
ELLNODE node;
|
||||
ELLNODE pre_node;
|
||||
ELLNODE post_node;
|
||||
dbChannel *chan;
|
||||
const chFilterPlugin *plug;
|
||||
chPostEventFunc *pre_func;
|
||||
void *pre_arg;
|
||||
chPostEventFunc *post_func;
|
||||
void *post_arg;
|
||||
void *puser;
|
||||
};
|
||||
|
||||
@@ -167,6 +160,8 @@ epicsShareFunc void dbChannelFilterShow(dbChannel *chan, const char *intro,
|
||||
epicsShareFunc void dbChannelDelete(dbChannel *chan);
|
||||
|
||||
epicsShareFunc void dbRegisterFilter(const char *key, const chFilterIf *fif, void *puser);
|
||||
epicsShareFunc db_field_log* dbChannelRunPreChain(dbChannel *chan, db_field_log *pLogIn);
|
||||
epicsShareFunc db_field_log* dbChannelRunPostChain(dbChannel *chan, db_field_log *pLogIn);
|
||||
epicsShareFunc const chFilterPlugin * dbFindFilter(const char *key, size_t len);
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
@@ -621,20 +621,20 @@ int epicsShareAPI db_post_extra_labor (dbEventCtx ctx)
|
||||
}
|
||||
|
||||
/*
|
||||
* DB_POST_SINGLE_EVENT_FIRST()
|
||||
* DB_CREATE_EVENT_LOG()
|
||||
*
|
||||
* NOTE: This assumes that the db scan lock is already applied
|
||||
* (as it copies data from the record)
|
||||
*/
|
||||
db_field_log* db_post_single_event_first (struct evSubscrip *pevent)
|
||||
static db_field_log* db_create_event_log (struct evSubscrip *pevent)
|
||||
{
|
||||
db_field_log *pLog = (db_field_log *) freeListCalloc(dbevFieldLogFreeList);;
|
||||
db_field_log *pLog = (db_field_log *) freeListCalloc(dbevFieldLogFreeList);
|
||||
|
||||
if (pLog) {
|
||||
struct dbChannel *chan = pevent->chan;
|
||||
struct dbCommon *prec = dbChannelRecord(chan);
|
||||
if (pevent->useValque) {
|
||||
pLog->type = dbfl_type_val;
|
||||
pLog->type = dbfl_type_value;
|
||||
pLog->stat = prec->stat;
|
||||
pLog->sevr = prec->sevr;
|
||||
pLog->time = prec->time;
|
||||
@@ -656,10 +656,10 @@ db_field_log* db_post_single_event_first (struct evSubscrip *pevent)
|
||||
}
|
||||
|
||||
/*
|
||||
* DB_POST_SINGLE_EVENT_FINAL()
|
||||
* DB_QUEUE_EVENT_LOG()
|
||||
*
|
||||
*/
|
||||
void db_post_single_event_final (void *pvt, evSubscrip *pevent, db_field_log *pLog)
|
||||
static void db_queue_event_log (evSubscrip *pevent, db_field_log *pLog)
|
||||
{
|
||||
struct event_que *ev_que;
|
||||
int firstEventFlag;
|
||||
@@ -783,10 +783,9 @@ unsigned int caEventMask
|
||||
*/
|
||||
if ( (dbChannelField(pevent->chan) == (void *)pField || pField==NULL) &&
|
||||
(caEventMask & pevent->select)) {
|
||||
/* Call the head of the filter chain */
|
||||
pevent->chan->pre_event_cb(pevent->chan->pre_event_arg,
|
||||
pevent,
|
||||
db_post_single_event_first(pevent));
|
||||
db_field_log *pLog = db_create_event_log(pevent);
|
||||
pLog = dbChannelRunPreChain(pevent->chan, pLog);
|
||||
db_queue_event_log(pevent, pLog);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -805,10 +804,9 @@ void epicsShareAPI db_post_single_event (dbEventSubscription event)
|
||||
|
||||
dbScanLock (prec);
|
||||
|
||||
/* Call the head of the filter chain */
|
||||
pevent->chan->pre_event_cb(pevent->chan->pre_event_arg,
|
||||
pevent,
|
||||
db_post_single_event_first(pevent));
|
||||
db_field_log *pLog = db_create_event_log(pevent);
|
||||
pLog = dbChannelRunPreChain(pevent->chan, pLog);
|
||||
db_queue_event_log(pevent, pLog);
|
||||
|
||||
dbScanUnlock (prec);
|
||||
}
|
||||
|
||||
@@ -72,7 +72,6 @@ epicsShareFunc void epicsShareAPI db_cancel_event (dbEventSubscription es);
|
||||
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 void epicsShareAPI db_post_single_event_final (void *pvt, struct evSubscrip *pevent, struct db_field_log *pLog);
|
||||
|
||||
epicsShareFunc void epicsShareAPI db_delete_field_log (struct db_field_log *pfl);
|
||||
|
||||
|
||||
@@ -52,11 +52,12 @@ typedef void (dbfl_freeFunc)(struct db_field_log *pfl);
|
||||
/* Types of db_field_log: rec = use record, val = val inside, ref = reference inside */
|
||||
typedef enum dbfl_type {
|
||||
dbfl_type_rec = 0,
|
||||
dbfl_type_val,
|
||||
dbfl_type_ref
|
||||
dbfl_type_value,
|
||||
dbfl_type_ref,
|
||||
dbfl_type_probe
|
||||
} dbfl_type;
|
||||
|
||||
#define dbflTypeStr(t) (t==dbfl_type_val?"val":t==dbfl_type_rec?"rec":"ref")
|
||||
#define dbflTypeStr(t) (t==dbfl_type_value?"val":t==dbfl_type_rec?"rec":t==dbfl_type_probe?"prb":"ref")
|
||||
|
||||
struct dbfl_val {
|
||||
union native_value field; /* Field value */
|
||||
@@ -74,7 +75,7 @@ typedef struct db_field_log {
|
||||
unsigned short stat; /* Alarm Status */
|
||||
unsigned short sevr; /* Alarm Severity */
|
||||
short field_type; /* DBF type of data */
|
||||
short field_size; /* Data size */
|
||||
short element_size; /* Data size */
|
||||
long no_elements; /* No of array elements */
|
||||
union {
|
||||
struct dbfl_val v;
|
||||
|
||||
@@ -44,14 +44,6 @@ typedef struct myStruct {
|
||||
int sent6;
|
||||
char c;
|
||||
char c1[2];
|
||||
chPostEventFunc *pe_pre;
|
||||
void *pe_pre_arg;
|
||||
chPostEventFunc *pe_post;
|
||||
void *pe_post_arg;
|
||||
chPostEventFunc *st_pre;
|
||||
void *st_pre_arg;
|
||||
chPostEventFunc *st_post;
|
||||
void *st_post_arg;
|
||||
} myStruct;
|
||||
|
||||
static const
|
||||
@@ -173,26 +165,16 @@ static long channel_open(dbChannel *chan, void *user)
|
||||
return c_open_return;
|
||||
}
|
||||
|
||||
static void channelRegisterPreEventQue(dbChannel *chan, void *user,
|
||||
chPostEventFunc *pe_in, void *pe_arg_in,
|
||||
chSetTypeFunc *st_in, void *st_arg_in,
|
||||
chPostEventFunc **pe_out, void **pe_arg_out,
|
||||
chSetTypeFunc **st_out, void **st_arg_out)
|
||||
static void channelRegisterPre(dbChannel *chan, void *user,
|
||||
chPostEventFunc **cb_out, void **arg_out)
|
||||
{
|
||||
myStruct *my = (myStruct*)user;
|
||||
my->pe_pre = pe_in;
|
||||
my->pe_pre_arg = pe_arg_in;
|
||||
}
|
||||
|
||||
static void channelRegisterPostEventQue(dbChannel *chan, void *user,
|
||||
chPostEventFunc *pe_in, void *pe_arg_in,
|
||||
chSetTypeFunc *st_in, void *st_arg_in,
|
||||
chPostEventFunc **pe_out, void **pe_arg_out,
|
||||
chSetTypeFunc **st_out, void **st_arg_out)
|
||||
static void channelRegisterPost(dbChannel *chan, void *user,
|
||||
chPostEventFunc **cb_out, void **arg_out)
|
||||
{
|
||||
myStruct *my = (myStruct*)user;
|
||||
my->pe_post = pe_in;
|
||||
my->pe_post_arg = pe_arg_in;
|
||||
}
|
||||
|
||||
static void channel_report(dbChannel *chan, void *user, const char *intro, int level)
|
||||
@@ -217,8 +199,8 @@ static chfPluginIf myPif = {
|
||||
parse_ok,
|
||||
|
||||
channel_open,
|
||||
channelRegisterPreEventQue,
|
||||
channelRegisterPostEventQue,
|
||||
channelRegisterPre,
|
||||
channelRegisterPost,
|
||||
channel_report,
|
||||
channel_close
|
||||
};
|
||||
|
||||
@@ -116,17 +116,13 @@ long c_open(chFilter *filter)
|
||||
testOk(e & e_open, "channel_open called");
|
||||
return 0;
|
||||
}
|
||||
void c_reg_pre(chFilter *filter,
|
||||
chPostEventFunc *pe_in, void *pe_arg_in, chSetTypeFunc *st_in, void *st_arg_in,
|
||||
chPostEventFunc **pe_out, void **arg_out, chSetTypeFunc **st_out, void **st_arg_out)
|
||||
void c_reg_pre(chFilter *filter, chPostEventFunc **cb_out, void **arg_out)
|
||||
{
|
||||
testOk(e & e_reg_pre, "channel_register_pre_event_queue called");
|
||||
testOk(e & e_reg_pre, "channel_register_pre called");
|
||||
}
|
||||
void c_reg_post(chFilter *filter,
|
||||
chPostEventFunc *pe_in, void *pe_arg_in, chSetTypeFunc *st_in, void *st_arg_in,
|
||||
chPostEventFunc **pe_out, void **arg_out, chSetTypeFunc **st_out, void **st_arg_out)
|
||||
void c_reg_post(chFilter *filter, chPostEventFunc **cb_out, void **arg_out)
|
||||
{
|
||||
testOk(e & e_reg_post, "channel_register_post_event_queue called");
|
||||
testOk(e & e_reg_post, "channel_register_post called");
|
||||
}
|
||||
void c_report(chFilter *filter, const char *intro, int level)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user