Clean up dead API client reaper callack scheme 42/5742/1
authorDave Barach <dave@barachs.net>
Tue, 14 Mar 2017 13:10:56 +0000 (09:10 -0400)
committerDave Barach <dave@barachs.net>
Tue, 14 Mar 2017 13:36:17 +0000 (09:36 -0400)
Change-Id: Iec3df234ca9f717d87787cefc76b73ed9ad42332
Signed-off-by: Dave Barach <dave@barachs.net>
src/vlibapi/api.h
src/vlibmemory/memory_vlib.c
src/vpp/api/api.c

index 87a5612..a62fa64 100644 (file)
@@ -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 */
 
 /*
index d2e0596..7a536ee 100644 (file)
@@ -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);
                    }
                }
 
index c85dc68..673ffe5 100644 (file)
@@ -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