diff options
Diffstat (limited to 'src/vlib')
-rw-r--r-- | src/vlib/punt.c | 34 | ||||
-rw-r--r-- | src/vlib/punt.h | 9 |
2 files changed, 39 insertions, 4 deletions
diff --git a/src/vlib/punt.c b/src/vlib/punt.c index 7c2daf25ee4..d5e13004caf 100644 --- a/src/vlib/punt.c +++ b/src/vlib/punt.c @@ -47,6 +47,21 @@ typedef struct punt_reason_data_t_ * Clients/owners that have registered this reason */ u32 *pd_owners; + + /** + * clients interested/listening to this reason + */ + u32 pd_users; + + /** + * function to invoke if a client becomes interested in the code. + */ + punt_interested_listener_t pd_fn; + + /** + * Data to pass to the callback + */ + void *pd_data; } punt_reason_data_t; /** @@ -249,8 +264,8 @@ punt_reg_mk_dp (vlib_punt_reason_t reason) } int -vlib_punt_register (vlib_punt_hdl_t client, vlib_punt_reason_t reason, - const char *node_name) +vlib_punt_register (vlib_punt_hdl_t client, + vlib_punt_reason_t reason, const char *node_name) { vlib_node_t *punt_to, *punt_from; punt_client_t *pc; @@ -298,6 +313,11 @@ vlib_punt_register (vlib_punt_hdl_t client, vlib_punt_reason_t reason, pri = pr - punt_reg_pool; + if (0 == punt_reason_data[reason].pd_users++ && + NULL != punt_reason_data[reason].pd_fn) + punt_reason_data[reason].pd_fn (VLIB_ENABLE, + punt_reason_data[reason].pd_data); + punt_reg_add (pr); } @@ -353,6 +373,10 @@ vlib_punt_unregister (vlib_punt_hdl_t client, if (0 == pr->pr_locks) { + if (0 == --punt_reason_data[reason].pd_users && + NULL != punt_reason_data[reason].pd_fn) + punt_reason_data[reason].pd_fn (VLIB_DISABLE, + punt_reason_data[reason].pd_data); punt_reg_remove (pr); pool_put (punt_reg_pool, pr); } @@ -377,7 +401,9 @@ vlib_punt_reason_validate (vlib_punt_reason_t reason) int vlib_punt_reason_alloc (vlib_punt_hdl_t client, - const char *reason_name, vlib_punt_reason_t * reason) + const char *reason_name, + punt_interested_listener_t fn, + void *data, vlib_punt_reason_t * reason) { vlib_punt_reason_t new; @@ -388,6 +414,8 @@ vlib_punt_reason_alloc (vlib_punt_hdl_t client, vec_validate (punt_reason_data, new); punt_reason_data[new].pd_name = format (NULL, "%s", reason_name); punt_reason_data[new].pd_reason = new; + punt_reason_data[new].pd_fn = fn; + punt_reason_data[new].pd_data = data; vec_add1 (punt_reason_data[new].pd_owners, client); vlib_validate_combined_counter (&punt_counters, new); diff --git a/src/vlib/punt.h b/src/vlib/punt.h index 7a3e5da2da6..d93b5eac599 100644 --- a/src/vlib/punt.h +++ b/src/vlib/punt.h @@ -56,12 +56,19 @@ typedef int vlib_punt_hdl_t; */ vlib_punt_hdl_t vlib_punt_client_register (const char *who); +typedef void (*punt_interested_listener_t) (vlib_enable_or_disable_t i, + void *data); + /** * Allocate a new punt reason + * @param fn - A callback to invoke when an entity becomes [un]interested + * in the punt code. + * @param data - To be passed in the callback function. */ extern int vlib_punt_reason_alloc (vlib_punt_hdl_t client, const char *reason_name, - vlib_punt_reason_t * reason); + punt_interested_listener_t fn, + void *data, vlib_punt_reason_t * reason); /** * Validate that a punt reason is assigned |