* See the License for the specific language governing permissions and
* limitations under the License.
*/
+#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <stddef.h>
#include <vlibapi/api.h>
#include <vlibmemory/api.h>
-#include <vpp/api/vpe_msg_enum.h>
+#include <vlibmemory/memclnt.api_enum.h>
+#include <vlibmemory/memclnt.api_types.h>
#include "vppapiclient.h"
* vac_read() -> resumes RX thread
*/
-#define vl_typedefs /* define message structures */
-#include <vpp/api/vpe_all_api_h.h>
-#undef vl_typedefs
-
-#define vl_endianfun /* define message structures */
-#include <vpp/api/vpe_all_api_h.h>
-#undef vl_endianfun
-
-vlib_main_t vlib_global_main;
-vlib_main_t **vlib_mains;
-
typedef struct {
u8 connected_to_vlib;
pthread_t rx_thread_handle;
bool rx_is_running = false;
bool timeout_thread_cancelled = false;
-/* Set to true to enable memory tracing */
-bool mem_trace = false;
-
-__attribute__((constructor))
-static void
-vac_client_constructor (void)
-{
- clib_mem_init (0, 1 << 30);
-#if USE_DLMALLOC == 0
- {
- u8 *heap;
- mheap_t *h;
-
- heap = clib_mem_get_per_cpu_heap ();
- h = mheap_header (heap);
- /* make the main heap thread-safe */
- h->flags |= MHEAP_FLAG_THREAD_SAFE;
- }
-#endif
- if (mem_trace)
- clib_mem_trace (1);
-}
-
-__attribute__((destructor))
-static void
-vac_client_destructor (void)
-{
- if (mem_trace)
- fformat(stderr, "TRACE: %s",
- format (0, "%U\n",
- format_mheap, clib_mem_get_heap (), 1));
-}
-
+/* Only ever allocate one heap */
+bool mem_initialized = false;
static void
init (void)
clib_memset(pm, 0, sizeof(*pm));
}
-/*
- * Satisfy external references when -lvlib is not available.
- */
-void vlib_cli_output (struct vlib_main_t * vm, char * fmt, ...)
-{
- clib_warning ("vlib_cli_output called...");
-}
-
void
vac_free (void * msg)
{
vl_api_memclnt_keepalive_t *mp;
vl_api_memclnt_keepalive_reply_t *rmp;
vac_main_t *pm = &vac_main;
- api_main_t *am = &api_main;
+ api_main_t *am = vlibapi_get_main();
vl_shmem_hdr_t *shmem_hdr;
uword msg;
while (1)
while (!svm_queue_sub(q, (u8 *)&msg, SVM_Q_WAIT, 0))
{
+ VL_MSG_API_UNPOISON((void *)msg);
u16 id = ntohs(*((u16 *)msg));
switch (id) {
case VL_API_RX_THREAD_EXIT:
{
vl_api_memclnt_read_timeout_t *ep;
vac_main_t *pm = &vac_main;
- api_main_t *am = &api_main;
+ api_main_t *am = vlibapi_get_main();
struct timespec ts;
struct timeval tv;
int rv;
void
vac_rx_suspend (void)
{
- api_main_t *am = &api_main;
+ api_main_t *am = vlibapi_get_main();
vac_main_t *pm = &vac_main;
vl_api_memclnt_rx_thread_suspend_t *ep;
static uword *
vac_msg_table_get_hash (void)
{
- api_main_t *am = &api_main;
+ api_main_t *am = vlibapi_get_main();
return (am->msg_index_by_name_and_crc);
}
int
vac_msg_table_size(void)
{
- api_main_t *am = &api_main;
+ api_main_t *am = vlibapi_get_main();
return hash_elts(am->msg_index_by_name_and_crc);
}
int
vac_connect (char * name, char * chroot_prefix, vac_callback_t cb,
- int rx_qlen)
+ int rx_qlen)
{
rx_thread_done = false;
int rv = 0;
vac_main_t *pm = &vac_main;
+ assert (clib_mem_get_heap ());
init();
if (chroot_prefix != NULL)
vl_set_memory_root_path (chroot_prefix);
int
vac_disconnect (void)
{
- api_main_t *am = &api_main;
+ api_main_t *am = vlibapi_get_main();
vac_main_t *pm = &vac_main;
uword junk;
int rv = 0;
vl_client_disconnect();
vl_client_api_unmap();
- vac_callback = 0;
+ //vac_callback = 0;
cleanup();
vac_read (char **p, int *l, u16 timeout)
{
svm_queue_t *q;
- api_main_t *am = &api_main;
+ api_main_t *am = vlibapi_get_main();
vac_main_t *pm = &vac_main;
vl_api_memclnt_keepalive_t *mp;
vl_api_memclnt_keepalive_reply_t *rmp;
int rv;
vl_shmem_hdr_t *shmem_hdr;
- if (!pm->connected_to_vlib) return -1;
+ /* svm_queue_sub(below) returns {-1, -2} */
+ if (!pm->connected_to_vlib)
+ return VAC_NOT_CONNECTED;
*l = 0;
- if (am->our_pid == 0) return (-1);
+ /* svm_queue_sub(below) returns {-1, -2} */
+ if (am->our_pid == 0)
+ return (VAC_SHM_NOT_READY);
/* Poke timeout thread */
if (timeout)
rv = svm_queue_sub(q, (u8 *)&msg, SVM_Q_WAIT, 0);
if (rv == 0) {
+ VL_MSG_API_UNPOISON((void *)msg);
u16 msg_id = ntohs(*((u16 *)msg));
switch (msg_id) {
case VL_API_RX_THREAD_EXIT:
shmem_hdr = am->shmem_hdr;
vl_msg_api_send_shmem(shmem_hdr->vl_input_queue, (u8 *)&rmp);
vl_msg_api_free((void *) msg);
- /*
+ /*
* Python code is blissfully unaware of these pings, so
* act as if it never happened...
*/
vl_msg_api_free((void *) msg);
/* Client might forget to resume RX thread on failure */
vac_rx_resume ();
- return -1;
+ return VAC_TIMEOUT;
}
/*
* XXX: Makes the assumption that client_index is the first member
*/
-typedef VL_API_PACKED(struct _vl_api_header {
+typedef struct _vl_api_header
+{
u16 _vl_msg_id;
u32 client_index;
-}) vl_api_header_t;
+} __attribute__ ((packed)) vl_api_header_t;
static u32
vac_client_index (void)
{
- return (api_main.my_client_index);
+ return (vlibapi_get_main()->my_client_index);
}
int
vac_write (char *p, int l)
{
int rv = -1;
- api_main_t *am = &api_main;
+ api_main_t *am = vlibapi_get_main();
vl_api_header_t *mp = vl_msg_api_alloc(l);
svm_queue_t *q;
vac_main_t *pm = &vac_main;
- if (!pm->connected_to_vlib) return -1;
+ if (!pm->connected_to_vlib)
+ return VAC_NOT_CONNECTED;
if (!mp) return (-1);
memcpy(mp, p, l);
}
int
-vac_get_msg_index (unsigned char * name)
+vac_get_msg_index (char * name)
{
- return vl_msg_api_get_msg_index (name);
+ return vl_msg_api_get_msg_index ((u8 *)name);
}
int
void
vac_set_error_handler (vac_error_callback_t cb)
{
+ assert (clib_mem_get_heap ());
if (cb) clib_error_register_handler (cb, 0);
}
+
+/*
+ * Required if application doesn't use a VPP heap.
+ */
+void
+vac_mem_init (size_t size)
+{
+ if (mem_initialized)
+ return;
+ if (size == 0)
+ clib_mem_init (0, 1 << 30); // default
+ else
+ clib_mem_init (0, size);
+ mem_initialized = true;
+}