X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=src%2Fvlibmemory%2Fmemory_client.c;h=c61c3cbdd5130babc38feababdd2fccd7848b88e;hb=920180e5e0722c78c258ff26476fd5efa434032d;hp=a0b5cc99cd4657efc72476b2e770f788669998e4;hpb=4d9b9d8e74f12a26404ccdd8baf46c61b44584db;p=vpp.git diff --git a/src/vlibmemory/memory_client.c b/src/vlibmemory/memory_client.c index a0b5cc99cd4..c61c3cbdd51 100644 --- a/src/vlibmemory/memory_client.c +++ b/src/vlibmemory/memory_client.c @@ -44,17 +44,6 @@ #include #undef vl_printfun -typedef struct -{ - u8 rx_thread_jmpbuf_valid; - u8 connected_to_vlib; - jmp_buf rx_thread_jmpbuf; - pthread_t rx_thread_handle; - /* Plugin message base lookup scheme */ - volatile u8 first_msg_id_reply_ready; - u16 first_msg_id_reply; -} memory_client_main_t; - memory_client_main_t memory_client_main; static void * @@ -63,7 +52,6 @@ rx_thread_fn (void *arg) svm_queue_t *q; memory_client_main_t *mm = &memory_client_main; api_main_t *am = &api_main; - int i; q = am->vl_input_queue; @@ -71,25 +59,7 @@ rx_thread_fn (void *arg) if (setjmp (mm->rx_thread_jmpbuf) == 0) { mm->rx_thread_jmpbuf_valid = 1; - /* - * Find an unused slot in the per-cpu-mheaps array, - * and grab it for this thread. We need to be able to - * push/pop the thread heap without affecting other thread(s). - */ - if (__os_thread_index == 0) - { - for (i = 0; i < ARRAY_LEN (clib_per_cpu_mheaps); i++) - { - if (clib_per_cpu_mheaps[i] == 0) - { - /* Copy the main thread mheap pointer */ - clib_per_cpu_mheaps[i] = clib_per_cpu_mheaps[0]; - __os_thread_index = i; - break; - } - } - ASSERT (__os_thread_index > 0); - } + clib_mem_set_thread_index (); while (1) vl_msg_api_queue_handler (q); } @@ -100,8 +70,31 @@ 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); + if (mm->rx_thread_jmpbuf_valid) + longjmp (mm->rx_thread_jmpbuf, 1); +} + +static void +vl_api_name_and_crc_free (void) +{ + api_main_t *am = &api_main; + int i; + u8 **keys = 0; + hash_pair_t *hp; + + if (!am->msg_index_by_name_and_crc) + return; + + /* *INDENT-OFF* */ + hash_foreach_pair (hp, am->msg_index_by_name_and_crc, + ({ + vec_add1 (keys, (u8 *) hp->key); + })); + /* *INDENT-ON* */ + for (i = 0; i < vec_len (keys); i++) + vec_free (keys[i]); + vec_free (keys); + hash_free (am->msg_index_by_name_and_crc); } static void @@ -119,21 +112,7 @@ vl_api_memclnt_create_reply_t_handler (vl_api_memclnt_create_reply_t * mp) am->my_registration = (vl_api_registration_t *) (uword) mp->handle; /* Clean out any previous hash table (unlikely) */ - if (am->msg_index_by_name_and_crc) - { - int i; - u8 **keys = 0; - hash_pair_t *hp; - /* *INDENT-OFF* */ - hash_foreach_pair (hp, am->msg_index_by_name_and_crc, - ({ - vec_add1 (keys, (u8 *) hp->key); - })); - /* *INDENT-ON* */ - for (i = 0; i < vec_len (keys); i++) - vec_free (keys[i]); - vec_free (keys); - } + vl_api_name_and_crc_free (); am->msg_index_by_name_and_crc = hash_create_string (0, sizeof (uword)); @@ -155,6 +134,7 @@ noop_handler (void *notused) { } +void vl_msg_api_send_shmem (svm_queue_t * q, u8 * elem); int vl_client_connect (const char *name, int ctx_quota, int input_queue_size) { @@ -190,17 +170,17 @@ vl_client_connect (const char *name, int ctx_quota, int input_queue_size) pthread_mutex_lock (&svm->mutex); oldheap = svm_push_data_heap (svm); - vl_input_queue = - svm_queue_init (input_queue_size, sizeof (uword), getpid (), 0); - pthread_mutex_unlock (&svm->mutex); + vl_input_queue = svm_queue_alloc_and_init (input_queue_size, sizeof (uword), + getpid ()); svm_pop_heap (oldheap); + pthread_mutex_unlock (&svm->mutex); am->my_client_index = ~0; am->my_registration = 0; am->vl_input_queue = vl_input_queue; mp = vl_msg_api_alloc (sizeof (vl_api_memclnt_create_t)); - memset (mp, 0, sizeof (*mp)); + clib_memset (mp, 0, sizeof (*mp)); mp->_vl_msg_id = ntohs (VL_API_MEMCLNT_CREATE); mp->ctx_quota = ctx_quota; mp->input_queue = (uword) vl_input_queue; @@ -218,7 +198,7 @@ vl_client_connect (const char *name, int ctx_quota, int input_queue_size) for (i = 0; i < 1000; i++) { qstatus = svm_queue_sub (vl_input_queue, (u8 *) & rp, - 1 /* nowait */ ); + SVM_Q_NOWAIT, 0); if (qstatus == 0) goto read_one_msg; ts.tv_sec = 0; @@ -262,34 +242,41 @@ vl_api_memclnt_delete_reply_t_handler (vl_api_memclnt_delete_reply_t * mp) } void -vl_client_disconnect (void) +vl_client_send_disconnect (u8 do_cleanup) { vl_api_memclnt_delete_t *mp; - vl_api_memclnt_delete_reply_t *rp; - svm_queue_t *vl_input_queue; vl_shmem_hdr_t *shmem_hdr; - time_t begin; api_main_t *am = &api_main; ASSERT (am->vlib_rp); shmem_hdr = am->shmem_hdr; ASSERT (shmem_hdr && shmem_hdr->vl_input_queue); - vl_input_queue = am->vl_input_queue; - mp = vl_msg_api_alloc (sizeof (vl_api_memclnt_delete_t)); - memset (mp, 0, sizeof (*mp)); + clib_memset (mp, 0, sizeof (*mp)); mp->_vl_msg_id = ntohs (VL_API_MEMCLNT_DELETE); mp->index = am->my_client_index; mp->handle = (uword) am->my_registration; + mp->do_cleanup = do_cleanup; vl_msg_api_send_shmem (shmem_hdr->vl_input_queue, (u8 *) & mp); +} + +int +vl_client_disconnect (void) +{ + vl_api_memclnt_delete_reply_t *rp; + svm_queue_t *vl_input_queue; + api_main_t *am = &api_main; + time_t begin; + + vl_input_queue = am->vl_input_queue; + vl_client_send_disconnect (0 /* wait for reply */ ); /* * Have to be careful here, in case the client is disconnecting * because e.g. the vlib process died, or is unresponsive. */ - begin = time (0); while (1) { @@ -303,9 +290,9 @@ vl_client_disconnect (void) am->my_client_index = ~0; am->my_registration = 0; am->shmem_hdr = 0; - break; + return -1; } - if (svm_queue_sub (vl_input_queue, (u8 *) & rp, 1) < 0) + if (svm_queue_sub (vl_input_queue, (u8 *) & rp, SVM_Q_NOWAIT, 0) < 0) continue; /* drain the queue */ @@ -318,6 +305,9 @@ vl_client_disconnect (void) vl_msg_api_handler ((void *) rp); break; } + + vl_api_name_and_crc_free (); + return 0; } /** @@ -335,7 +325,7 @@ vl_api_memclnt_keepalive_t_handler (vl_api_memclnt_keepalive_t * mp) shmem_hdr = am->shmem_hdr; rmp = vl_msg_api_alloc_as_if_client (sizeof (*rmp)); - memset (rmp, 0, sizeof (*rmp)); + clib_memset (rmp, 0, sizeof (*rmp)); rmp->_vl_msg_id = ntohs (VL_API_MEMCLNT_KEEPALIVE_REPLY); rmp->context = mp->context; vl_msg_api_send_shmem (shmem_hdr->vl_input_queue, (u8 *) & rmp); @@ -362,7 +352,6 @@ vl_client_install_client_message_handlers (void) #undef _ } - int vl_client_api_map (const char *region_name) { @@ -378,16 +367,24 @@ vl_client_api_map (const char *region_name) void vl_client_api_unmap (void) { - vl_unmap_shmem (); + vl_unmap_shmem_client (); +} + +u8 +vl_mem_client_is_connected (void) +{ + return (memory_client_main.connected_to_vlib != 0); } static int connect_to_vlib_internal (const char *svm_name, const char *client_name, - int rx_queue_size, int want_pthread, int do_map) + int rx_queue_size, void *(*thread_fn) (void *), + int do_map) { int rv = 0; memory_client_main_t *mm = &memory_client_main; + api_main_t *am = &api_main; if (do_map && (rv = vl_client_api_map (svm_name))) { @@ -404,12 +401,19 @@ connect_to_vlib_internal (const char *svm_name, /* Start the rx queue thread */ - if (want_pthread) + if (thread_fn) { rv = pthread_create (&mm->rx_thread_handle, - NULL /*attr */ , rx_thread_fn, 0); + NULL /*attr */ , thread_fn, 0); if (rv) - clib_warning ("pthread_create returned %d", rv); + { + clib_warning ("pthread_create returned %d", rv); + am->rx_thread_handle = 0; + } + else + { + am->rx_thread_handle = mm->rx_thread_handle; + } } mm->connected_to_vlib = 1; @@ -421,8 +425,7 @@ vl_client_connect_to_vlib (const char *svm_name, const char *client_name, int rx_queue_size) { return connect_to_vlib_internal (svm_name, client_name, rx_queue_size, - 1 /* want pthread */ , - 1 /* do map */ ); + rx_thread_fn, 1 /* do map */ ); } int @@ -431,7 +434,7 @@ vl_client_connect_to_vlib_no_rx_pthread (const char *svm_name, int rx_queue_size) { return connect_to_vlib_internal (svm_name, client_name, rx_queue_size, - 0 /* want pthread */ , + 0 /* no rx_thread_fn */ , 1 /* do map */ ); } @@ -440,12 +443,32 @@ vl_client_connect_to_vlib_no_map (const char *svm_name, const char *client_name, int rx_queue_size) { return connect_to_vlib_internal (svm_name, client_name, rx_queue_size, - 1 /* want pthread */ , + rx_thread_fn, 0 /* dont map */ ); +} + +int +vl_client_connect_to_vlib_no_rx_pthread_no_map (const char *svm_name, + const char *client_name, + int rx_queue_size) +{ + return connect_to_vlib_internal (svm_name, client_name, rx_queue_size, + 0 /* want pthread */ , 0 /* dont map */ ); } -void -vl_client_disconnect_from_vlib (void) +int +vl_client_connect_to_vlib_thread_fn (const char *svm_name, + const char *client_name, + int rx_queue_size, + void *(*thread_fn) (void *)) +{ + return connect_to_vlib_internal (svm_name, client_name, rx_queue_size, + thread_fn, 1 /* do map */ ); +} + + +static void +disconnect_from_vlib_internal (u8 do_unmap) { memory_client_main_t *mm = &memory_client_main; api_main_t *am = &api_main; @@ -462,9 +485,22 @@ vl_client_disconnect_from_vlib (void) if (mm->connected_to_vlib) { vl_client_disconnect (); - vl_client_api_unmap (); + if (do_unmap) + vl_client_api_unmap (); } - memset (mm, 0, sizeof (*mm)); + clib_memset (mm, 0, sizeof (*mm)); +} + +void +vl_client_disconnect_from_vlib (void) +{ + disconnect_from_vlib_internal (1); +} + +void +vl_client_disconnect_from_vlib_no_unmap (void) +{ + disconnect_from_vlib_internal (0); } static void vl_api_get_first_msg_id_reply_t_handler @@ -491,7 +527,7 @@ vl_client_get_first_plugin_msg_id (const char *plugin_name) if (strlen (plugin_name) + 1 > sizeof (mp->name)) return (rv); - memset (&clib_time, 0, sizeof (clib_time)); + clib_memset (&clib_time, 0, sizeof (clib_time)); clib_time_init (&clib_time); /* Push this plugin's first_msg_id_reply handler */ @@ -506,7 +542,7 @@ vl_client_get_first_plugin_msg_id (const char *plugin_name) if (!am->my_registration) { mp = vl_socket_client_msg_alloc (sizeof (*mp)); - memset (mp, 0, sizeof (*mp)); + clib_memset (mp, 0, sizeof (*mp)); mp->_vl_msg_id = ntohs (VL_API_GET_FIRST_MSG_ID); mp->client_index = am->my_client_index; strncpy ((char *) mp->name, plugin_name, sizeof (mp->name) - 1); @@ -531,7 +567,7 @@ vl_client_get_first_plugin_msg_id (const char *plugin_name) else { mp = vl_msg_api_alloc (sizeof (*mp)); - memset (mp, 0, sizeof (*mp)); + clib_memset (mp, 0, sizeof (*mp)); mp->_vl_msg_id = ntohs (VL_API_GET_FIRST_MSG_ID); mp->client_index = am->my_client_index; strncpy ((char *) mp->name, plugin_name, sizeof (mp->name) - 1);