static void vl_api_rx_thread_exit_t_handler ( vl_api_rx_thread_exit_t *mp) { memory_client_main_t *mm = &memory_client_main; vl_msg_api_free (mp); longjmp (mm->rx_thread_jmpbuf, 1); }
void vl_msg_api_cleanup_handler (void *the_msg) { api_main_t *am = &api_main; u16 id = ntohs(*((u16 *)the_msg)); if (PREDICT_FALSE(id >= vec_len(am->msg_cleanup_handlers))) { clib_warning ("_vl_msg_id too large: %d\n", id); return; } if (am->msg_cleanup_handlers[id]) (*am->msg_cleanup_handlers[id])(the_msg); vl_msg_api_free(the_msg); }
always_inline void msg_handler_internal (api_main_t * am, void *the_msg, int trace_it, int do_it, int free_it) { u16 id = ntohs (*((u16 *) the_msg)); u8 *(*print_fp) (void *, void *); if (id < vec_len (am->msg_handlers) && am->msg_handlers[id]) { if (trace_it) vl_msg_api_trace (am, am->rx_trace, the_msg); if (am->msg_print_flag) { fformat (stdout, "[%d]: %s\n", id, am->msg_names[id]); print_fp = (void *) am->msg_print_handlers[id]; if (print_fp == 0) { fformat (stdout, " [no registered print fn]\n"); } else { (*print_fp) (the_msg, stdout); } } if (do_it) { if (!am->is_mp_safe[id]) vl_msg_api_barrier_sync (); (*am->msg_handlers[id]) (the_msg); if (!am->is_mp_safe[id]) vl_msg_api_barrier_release (); } } else { clib_warning ("no handler for msg id %d", id); } if (free_it) vl_msg_api_free (the_msg); }
/* This is only to be called from a vlib/vnet app */ void vl_msg_api_handler_with_vm_node (api_main_t * am, void *the_msg, vlib_main_t * vm, vlib_node_runtime_t * node) { u16 id = ntohs (*((u16 *) the_msg)); u8 *(*handler) (void *, void *, void *); #if ELOG_API_MESSAGE_HANDLERS > 0 { /* *INDENT-OFF* */ ELOG_TYPE_DECLARE (e) = { .format = "api-msg: %s", .format_args = "T4", }; /* *INDENT-ON* */ struct { u32 c; } *ed; ed = ELOG_DATA (&vm->elog_main, e); if (id < vec_len (am->msg_names)) ed->c = elog_id_for_msg_name (vm, am->msg_names[id]); else ed->c = elog_id_for_msg_name (vm, "BOGUS"); } #endif if (id < vec_len (am->msg_handlers) && am->msg_handlers[id]) { handler = (void *) am->msg_handlers[id]; if (am->rx_trace && am->rx_trace->enabled) vl_msg_api_trace (am, am->rx_trace, the_msg); if (!am->is_mp_safe[id]) vl_msg_api_barrier_sync (); (*handler) (the_msg, vm, node); if (!am->is_mp_safe[id]) vl_msg_api_barrier_release (); } else { clib_warning ("no hander for msg id %d", id); } /* * Special-case, so we can e.g. bounce messages off the vnet * main thread without copying them... */ if (!(am->message_bounce[id])) vl_msg_api_free (the_msg); #if ELOG_API_MESSAGE_HANDLERS > 0 { /* *INDENT-OFF* */ ELOG_TYPE_DECLARE (e) = { .format = "api-msg-done: %s", .format_args = "T4", }; /* *INDENT-ON* */ struct { u32 c; } *ed; ed = ELOG_DATA (&vm->elog_main, e); if (id < vec_len (am->msg_names)) ed->c = elog_id_for_msg_name (vm, am->msg_names[id]); else ed->c = elog_id_for_msg_name (vm, "BOGUS"); } #endif } void vl_msg_api_handler (void *the_msg) { api_main_t *am = &api_main; msg_handler_internal (am, the_msg, (am->rx_trace && am->rx_trace->enabled) /* trace_it */ , 1 /* do_it */ , 1 /* free_it */ ); } void vl_msg_api_handler_no_free (void *the_msg) { api_main_t *am = &api_main; msg_handler_internal (am, the_msg, (am->rx_trace && am->rx_trace->enabled) /* trace_it */ , 1 /* do_it */ , 0 /* free_it */ ); }