summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/vlibapi/api.h44
-rw-r--r--src/vlibmemory/memory_vlib.c22
-rw-r--r--src/vpp/api/api.c6
3 files changed, 63 insertions, 9 deletions
diff --git a/src/vlibapi/api.h b/src/vlibapi/api.h
index 87a561211d4..a62fa64493e 100644
--- a/src/vlibapi/api.h
+++ b/src/vlibapi/api.h
@@ -112,6 +112,14 @@ typedef struct
u16 last_msg_id;
} vl_api_msg_range_t;
+typedef clib_error_t *(vl_msg_api_init_function_t) (u32 client_index);
+
+typedef struct _vl_msg_api_init_function_list_elt
+{
+ struct _vl_msg_api_init_function_list_elt *next_init_function;
+ vl_msg_api_init_function_t *f;
+} _vl_msg_api_function_list_elt_t;
+
typedef struct
{
void (**msg_handlers) (void *);
@@ -192,6 +200,10 @@ typedef struct
/* Replay in progress? */
int replay_in_progress;
+
+ /* List of API client reaper functions */
+ _vl_msg_api_function_list_elt_t *reaper_function_registrations;
+
} api_main_t;
extern api_main_t api_main;
@@ -291,6 +303,38 @@ vlib_node_t **vlib_node_unserialize (u8 * vector);
})
+#define _VL_MSG_API_FUNCTION_SYMBOL(x, type) \
+ _vl_msg_api_##type##_function_##x
+
+#define VL_MSG_API_FUNCTION_SYMBOL(x) \
+ _VL_MSG_API_FUNCTION_SYMBOL(x, reaper)
+
+#define VLIB_DECLARE_REAPER_FUNCTION(x, tag) \
+vl_msg_api_init_function_t * _VL_MSG_API_FUNCTION_SYMBOL (x, tag) = x; \
+static void __vl_msg_api_add_##tag##_function_##x (void) \
+ __attribute__((__constructor__)) ; \
+ \
+static void __vl_msg_api_add_##tag##_function_##x (void) \
+{ \
+ api_main_t * am = &api_main; \
+ static _vl_msg_api_function_list_elt_t _vl_msg_api_function; \
+ _vl_msg_api_function.next_init_function \
+ = am->tag##_function_registrations; \
+ am->tag##_function_registrations = &_vl_msg_api_function; \
+ _vl_msg_api_function.f = &x; \
+}
+
+#define VL_MSG_API_REAPER_FUNCTION(x) VLIB_DECLARE_REAPER_FUNCTION(x,reaper)
+
+/* Call reaper function with client index */
+#define vl_msg_api_call_reaper_function(ci) \
+ ({ \
+ extern vlib_init_function_t * VLIB_INIT_FUNCTION_SYMBOL (reaper); \
+ vlib_init_function_t * _f = VLIB_INIT_FUNCTION_SYMBOL (reaper); \
+ clib_error_t * _error = 0; \
+ _error = _f (ci); \
+ })
+
#endif /* included_api_h */
/*
diff --git a/src/vlibmemory/memory_vlib.c b/src/vlibmemory/memory_vlib.c
index d2e0596824d..7a536ee808c 100644
--- a/src/vlibmemory/memory_vlib.c
+++ b/src/vlibmemory/memory_vlib.c
@@ -221,12 +221,20 @@ vl_api_memclnt_create_t_handler (vl_api_memclnt_create_t * mp)
vl_msg_api_send_shmem (q, (u8 *) & rp);
}
-/* Application callback to clean up leftover registrations from this client */
-int vl_api_memclnt_delete_callback (u32 client_index) __attribute__ ((weak));
-
-int
-vl_api_memclnt_delete_callback (u32 client_index)
+static int
+call_reaper_functions (u32 client_index)
{
+ clib_error_t *error = 0;
+ _vl_msg_api_function_list_elt_t *i;
+
+ i = api_main.reaper_function_registrations;
+ while (i)
+ {
+ error = i->f (client_index);
+ if (error)
+ clib_error_report (error);
+ i = i->next_init_function;
+ }
return 0;
}
@@ -246,7 +254,7 @@ vl_api_memclnt_delete_t_handler (vl_api_memclnt_delete_t * mp)
handle = mp->index;
- if (vl_api_memclnt_delete_callback (handle))
+ if (call_reaper_functions (handle))
return;
epoch = vl_msg_api_handle_get_epoch (handle);
@@ -621,7 +629,7 @@ memclnt_process (vlib_main_t * vm,
handle = vl_msg_api_handle_from_index_and_epoch
(dead_indices[i], shm->application_restarts);
- (void) vl_api_memclnt_delete_callback (handle);
+ (void) call_reaper_functions (handle);
}
}
diff --git a/src/vpp/api/api.c b/src/vpp/api/api.c
index c85dc680b28..673ffe5618c 100644
--- a/src/vpp/api/api.c
+++ b/src/vpp/api/api.c
@@ -164,8 +164,8 @@ static int arp_change_delete_callback (u32 pool_index, u8 * notused);
static int nd_change_delete_callback (u32 pool_index, u8 * notused);
/* Clean up all registrations belonging to the indicated client */
-int
-vl_api_memclnt_delete_callback (u32 client_index)
+static clib_error_t *
+memclnt_delete_callback (u32 client_index)
{
vpe_api_main_t *vam = &vpe_api_main;
vpe_client_registration_t *rp;
@@ -186,6 +186,8 @@ vl_api_memclnt_delete_callback (u32 client_index)
return 0;
}
+VL_MSG_API_REAPER_FUNCTION (memclnt_delete_callback);
+
pub_sub_handler (oam_events, OAM_EVENTS);
#define RESOLUTION_EVENT 1