X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=src%2Fvpp-api%2Fclient%2Fclient.c;h=cd0b5b9e45dde17097bdc39fa6736f0868d7fbd5;hb=73710c7da2f8deaea83dbbbfce8737c9c6cd2949;hp=8bdcda01c4d15d34a2b31be9a0fbb7567f897cf5;hpb=5fec1e8b2282f4d3d1d02556020254a84c3b6e3d;p=vpp.git diff --git a/src/vpp-api/client/client.c b/src/vpp-api/client/client.c index 8bdcda01c4d..cd0b5b9e45d 100644 --- a/src/vpp-api/client/client.c +++ b/src/vpp-api/client/client.c @@ -72,6 +72,35 @@ vac_callback_t vac_callback; u16 read_timeout = 0; bool rx_is_running = false; +/* Set to true to enable memory tracing */ +bool mem_trace = false; + +__attribute__((constructor)) +static void +vac_client_constructor (void) +{ + u8 *heap; + mheap_t *h; + clib_mem_init (0, 1 << 30); + heap = clib_mem_get_per_cpu_heap (); + h = mheap_header (heap); + /* make the main heap thread-safe */ + h->flags |= MHEAP_FLAG_THREAD_SAFE; + 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)); +} + + static void init (void) { @@ -90,14 +119,14 @@ static void cleanup (void) { vac_main_t *pm = &vac_main; + pthread_mutex_destroy(&pm->queue_lock); pthread_cond_destroy(&pm->suspend_cv); pthread_cond_destroy(&pm->resume_cv); + pthread_mutex_destroy(&pm->timeout_lock); pthread_cond_destroy(&pm->timeout_cv); pthread_cond_destroy(&pm->timeout_cancel_cv); pthread_cond_destroy(&pm->terminate_cv); - pthread_mutex_destroy(&pm->queue_lock); - pthread_mutex_destroy(&pm->timeout_lock); - memset (pm, 0, sizeof (*pm)); + memset(pm, 0, sizeof(*pm)); } /* @@ -132,15 +161,18 @@ vac_api_handler (void *msg) static void * vac_rx_thread_fn (void *arg) { - unix_shared_memory_queue_t *q; + svm_queue_t *q; + 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; + vl_shmem_hdr_t *shmem_hdr; uword msg; q = am->vl_input_queue; while (1) - while (!unix_shared_memory_queue_sub(q, (u8 *)&msg, 0)) + while (!svm_queue_sub(q, (u8 *)&msg, SVM_Q_WAIT, 0)) { u16 id = ntohs(*((u16 *)msg)); switch (id) { @@ -169,6 +201,17 @@ vac_rx_thread_fn (void *arg) vl_msg_api_free((void *) msg); break; + case VL_API_MEMCLNT_KEEPALIVE: + mp = (void *)msg; + rmp = vl_msg_api_alloc (sizeof (*rmp)); + memset (rmp, 0, sizeof (*rmp)); + rmp->_vl_msg_id = ntohs(VL_API_MEMCLNT_KEEPALIVE_REPLY); + rmp->context = mp->context; + shmem_hdr = am->shmem_hdr; + vl_msg_api_send_shmem(shmem_hdr->vl_input_queue, (u8 *)&rmp); + vl_msg_api_free((void *) msg); + break; + default: vac_api_handler((void *)msg); } @@ -303,17 +346,36 @@ vac_connect (char * name, char * chroot_prefix, vac_callback_t cb, return (0); } +static void +set_timeout (unsigned short timeout) +{ + vac_main_t *pm = &vac_main; + pthread_mutex_lock(&pm->timeout_lock); + read_timeout = timeout; + pthread_cond_signal(&pm->timeout_cv); + pthread_mutex_unlock(&pm->timeout_lock); +} + +static void +unset_timeout (void) +{ + vac_main_t *pm = &vac_main; + pthread_mutex_lock(&pm->timeout_lock); + pthread_cond_signal(&pm->timeout_cancel_cv); + pthread_mutex_unlock(&pm->timeout_lock); +} + int vac_disconnect (void) { api_main_t *am = &api_main; vac_main_t *pm = &vac_main; + uword junk; if (!pm->connected_to_vlib) return 0; if (pm->rx_thread_handle) { vl_api_rx_thread_exit_t *ep; - uword junk; ep = vl_msg_api_alloc (sizeof (*ep)); ep->_vl_msg_id = ntohs(VL_API_RX_THREAD_EXIT); vl_msg_api_send_shmem(am->vl_input_queue, (u8 *)&ep); @@ -333,8 +395,12 @@ vac_disconnect (void) else pthread_join(pm->rx_thread_handle, (void **) &junk); } - if (pm->timeout_thread_handle) + if (pm->timeout_thread_handle) { + /* cancel, wake then join the timeout thread */ pthread_cancel(pm->timeout_thread_handle); + set_timeout(0); + pthread_join(pm->timeout_thread_handle, (void **) &junk); + } vl_client_disconnect(); vl_client_api_unmap(); @@ -345,33 +411,18 @@ vac_disconnect (void) return (0); } -static void -set_timeout (unsigned short timeout) -{ - vac_main_t *pm = &vac_main; - pthread_mutex_lock(&pm->timeout_lock); - read_timeout = timeout; - pthread_cond_signal(&pm->timeout_cv); - pthread_mutex_unlock(&pm->timeout_lock); -} - -static void -unset_timeout (void) -{ - vac_main_t *pm = &vac_main; - pthread_mutex_lock(&pm->timeout_lock); - pthread_cond_signal(&pm->timeout_cancel_cv); - pthread_mutex_unlock(&pm->timeout_lock); -} - int vac_read (char **p, int *l, u16 timeout) { - unix_shared_memory_queue_t *q; + svm_queue_t *q; api_main_t *am = &api_main; vac_main_t *pm = &vac_main; + vl_api_memclnt_keepalive_t *mp; + vl_api_memclnt_keepalive_reply_t *rmp; uword msg; msgbuf_t *msgbuf; + int rv; + vl_shmem_hdr_t *shmem_hdr; if (!pm->connected_to_vlib) return -1; @@ -384,12 +435,16 @@ vac_read (char **p, int *l, u16 timeout) set_timeout(timeout); q = am->vl_input_queue; - int rv = unix_shared_memory_queue_sub(q, (u8 *)&msg, 0); + + again: + rv = svm_queue_sub(q, (u8 *)&msg, SVM_Q_WAIT, 0); + if (rv == 0) { u16 msg_id = ntohs(*((u16 *)msg)); switch (msg_id) { case VL_API_RX_THREAD_EXIT: printf("Received thread exit\n"); + vl_msg_api_free((void *) msg); return -1; case VL_API_MEMCLNT_RX_THREAD_SUSPEND: printf("Received thread suspend\n"); @@ -397,6 +452,21 @@ vac_read (char **p, int *l, u16 timeout) case VL_API_MEMCLNT_READ_TIMEOUT: printf("Received read timeout %ds\n", timeout); goto error; + case VL_API_MEMCLNT_KEEPALIVE: + /* Handle an alive-check ping from vpp. */ + mp = (void *)msg; + rmp = vl_msg_api_alloc (sizeof (*rmp)); + memset (rmp, 0, sizeof (*rmp)); + rmp->_vl_msg_id = ntohs(VL_API_MEMCLNT_KEEPALIVE_REPLY); + rmp->context = mp->context; + 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... + */ + goto again; default: msgbuf = (msgbuf_t *)(((u8 *)msg) - offsetof(msgbuf_t, data)); @@ -443,7 +513,7 @@ vac_write (char *p, int l) int rv = -1; api_main_t *am = &api_main; vl_api_header_t *mp = vl_msg_api_alloc(l); - unix_shared_memory_queue_t *q; + svm_queue_t *q; vac_main_t *pm = &vac_main; if (!pm->connected_to_vlib) return -1; @@ -452,7 +522,7 @@ vac_write (char *p, int l) memcpy(mp, p, l); mp->client_index = vac_client_index(); q = am->shmem_hdr->vl_input_queue; - rv = unix_shared_memory_queue_add(q, (u8 *)&mp, 0); + rv = svm_queue_add(q, (u8 *)&mp, 0); if (rv != 0) { clib_warning("vpe_api_write fails: %d\n", rv); /* Clear message */ @@ -464,7 +534,7 @@ vac_write (char *p, int l) int vac_get_msg_index (unsigned char * name) { - return vl_api_get_msg_index (name); + return vl_msg_api_get_msg_index (name); } int