dbEvent.h
Internal publish/subscribe mechanism of process database. Direct usage is discouraged in favor of derived interfaces, principally local and remote PVA/CA.
- Since
7.0.8.1 New usage is recommended to define the USE_TYPED_DBEVENT C macro to select typed arguments of some calls as opposed to void pointers.
Objects
Event context (dbEventCtx)
Event subscription (dbEventSubscription)
Channel (dbChannel)
Event / field log (db_field_log)
Lifecycle
Usage is tied to the lifetime of the process database. Either through IOC lifecycle callback hooks. or Unit testing of record processing . db_init_events() must not be called before initHookAfterInitDatabase or testIocInitOk(). db_close_events() must be called after initHookBeforeFree or testIocShutdownOk().
Subscriptions associated with an Event Context must be deallocated before that Context is deallocated.
Concurrency
Each Event Context has an associated worker thread on which subscription callbacks are invoked. Some API functions implicitly synchronize with that worker thread as noted. The “extra labor” functions may be used to explicitly synchronize with this thread.
Note
testMonitorCreate() and friends are provided to easy handling of subscriptions in unit tests.
Typedefs
-
typedef void *dbEventSubscription
-
typedef void *dbEventCtx
-
typedef void EXTRALABORFUNC(void *extralabor_arg)
-
typedef void EVENTFUNC(void *user_arg, struct dbChannel *chan, int eventsRemaining, struct db_field_log *pfl)
Subscription event callback.
An event callback is expected to call dbChannelGetField() or take equivalent action. eg. explicitly lock the record and call dbChannelGet().
Callee must not delete the db_field_log.
- Since
7.0.5,
may be used to detect which condition(s) triggered this event.pfl->mask
- Param user_arg:
private argument passed to db_add_event()
- Param chan:
dbChannel passed to db_add_event()
- Param eventsRemaining:
Approximate number of events remaining in queued. Not exact. Use is discouraged.
- Param pfl:
db_field_log of this event.
Functions
-
int db_event_list(const char *name, unsigned level)
-
int dbel(const char *name, unsigned level)
-
int db_post_events(void *pRecord, void *pField, unsigned caEventMask)
-
dbEventCtx db_init_events(void)
Allocate event reception context.
On success, call db_start_events(), and then eventually db_close_events().
- Returns:
NULL on error
- Pre:
Call after initHookAfterInitDatabase and before initHookBeforeFree.
-
int db_start_events(dbEventCtx ctx, const char *taskname, void (*init_func)(void*), void *init_func_arg, unsigned osiPriority)
Start listener thread.
Basic lifecycle:
dbEventCtx ctxt = db_init_events(); assert(ctxt); int ret = db_start_events(ctxt, "mymodule", NULL, NULL, 0); assert(ret==DB_EVENT_OK); ... create and close subscriptions db_close_events(ctxt);
Flow control initially disabled, so events can be delivered.
- Parameters:
ctx – Context
taskname – Thread name
init_func – If not NULL, call from the newly created listener thread
init_func_arg – Argument to init_func
osiPriority – Thread priority. See epicsThreadOpts::priority
- Returns:
DB_EVENT_OK Success. DB_EVENT_ERROR, failed to create new thread.
-
void db_close_events(dbEventCtx ctx)
Stop and deallocate event reception context.
- Parameters:
ctx – Context
- Pre:
Call after initHookAfterInitDatabase and before initHookBeforeFree.
- Pre:
All dbEventSubscription must first be deallocated by db_cancel_event().
- Post:
Joins event listener thread.
-
void db_event_flow_ctrl_mode_on(dbEventCtx ctx)
Enable flow control, pause event delivery.
- Parameters:
ctx – Context
-
void db_event_flow_ctrl_mode_off(dbEventCtx ctx)
Disable flow control, resume event delivery.
- Parameters:
ctx – Context
-
int db_add_extra_labor_event(dbEventCtx ctx, EXTRALABORFUNC *func, void *arg)
Setup/Clear extra labor callback.
Does not queue callback. See db_post_extra_labor().
- Parameters:
ctx – Context
func – Extra labor callback, may be NULL to clear previously set callback.
arg – Argument to func
- Returns:
DB_EVENT_OK, always succeeds.
-
void db_flush_extra_labor_event(dbEventCtx)
Wait for extra labor callback.
To ensure completion, call should arrange that db_post_extra_labor() will not be called again.
- Pre:
Do not call from event listener thread.
- Post:
extra labor queued flag is unchanged
-
int db_post_extra_labor(dbEventCtx ctx)
Queue extra labor callback event.
Sets an internal queued flag, which still be set from a previous call.
- Parameters:
ctx – Context
- Returns:
DB_EVENT_OK, always succeeds.
-
void db_event_change_priority(dbEventCtx ctx, unsigned epicsPriority)
Change event listener thread priority.
- Parameters:
ctx – Context
epicsPriority – Thread priority. See epicsThreadOpts::priority
-
dbEventSubscription db_add_event(dbEventCtx ctx, struct dbChannel *chan, EVENTFUNC *user_sub, void *user_arg, unsigned select)
Create subscription to channel.
Creates a new subscription to the specified dbChannel. Callbacks will be delivered on the listener thread of the provided Context.
Creation does not queue any events. Follow with a call to db_post_single_event() to queue an initial event.
Subscription is initially disabled. Call db_event_enable();
Basic lifecycle:
static void mycb(void *priv, struct dbChannel *chan, int eventsRemaining, struct db_field_log *pfl) { (void)eventsRemaining; // use not recommended // dbChannelGetField() locks record. // May read value and meta-data from event (db_field_log). long ret = dbChannelGetField(chan, ..., pfl); } void someaction() { dbEventCtx ctx = ...; // previously created dbChannel *chan = ...; void *priv = ...; dbEventSubscription sub = db_add_event(ctx, chan, mycb, priv, DBE_VALUE|DBE_ALARM); assert(sub); db_cancel_event(sub); }
- Parameters:
ctx – Context
chan – Channel
user_sub – Event callback
user_arg – Private argument
select – Bit mask of DBE_VALUE and others. See caeventmask.h
- Returns:
NULL on error. On success, later call db_cancel_event()
-
void db_cancel_event(dbEventSubscription es)
Deallocate subscription.
Synchronizes with Event Context worker thread to wait for a concurrent callback to complete.
- Parameters:
es – Subscription. Must not be NULL.
-
void db_post_single_event(dbEventSubscription es)
Immediately attempt to queue an event with the present value.
Locks record and runs pre-chain of any server-side filters. Such a filter may drop the new event (a well designed filter should not drop the first event).
- Parameters:
es – Subscription
-
void db_event_enable(dbEventSubscription es)
Enable subscription callback delivery.
- Parameters:
es – Subscription
-
void db_event_disable(dbEventSubscription es)
Disable subscription callback delivery.
Does not synchronize with listener thread, pending callbacks may be delivered. Use extra-labor mechanism and db_flush_extra_labor_event() to synchronize.
- Parameters:
es – Subscription
-
struct db_field_log *db_create_event_log(struct evSubscrip *pevent)
Allocate subscription update event.
- Parameters:
pevent – Subscription
- Returns:
NULL on allocation failure.
-
struct db_field_log *db_create_read_log(struct dbChannel *chan)
Allocate “read” event.
Used by PVA or CA “GET” operations when polling the current value of a Channel.
- Parameters:
pevent – Subscription
- Returns:
NULL on allocation failure.
-
void db_delete_field_log(struct db_field_log *pfl)
db_delete_field_log
- Parameters:
pfl – event structure. May be NULL (no-op).
-
int db_available_logs(void)