diff options
-rw-r--r-- | src/vcl/CMakeLists.txt | 4 | ||||
-rw-r--r-- | src/vcl/test_vcl_listener_client.c | 58 | ||||
-rw-r--r-- | src/vcl/test_vcl_listener_server.c | 105 | ||||
-rw-r--r-- | src/vcl/vcl_event.c | 554 | ||||
-rw-r--r-- | src/vcl/vcl_event.h | 327 | ||||
-rw-r--r-- | src/vcl/vcl_private.h | 8 | ||||
-rw-r--r-- | src/vcl/vppcom.c | 1 | ||||
-rw-r--r-- | src/vcl/vppcom.h | 5 |
8 files changed, 0 insertions, 1062 deletions
diff --git a/src/vcl/CMakeLists.txt b/src/vcl/CMakeLists.txt index c86f40bb0f2..9fead608702 100644 --- a/src/vcl/CMakeLists.txt +++ b/src/vcl/CMakeLists.txt @@ -19,7 +19,6 @@ add_vpp_library(vppcom vppcom.c vcl_bapi.c vcl_cfg.c - vcl_event.c vcl_private.c LINK_LIBRARIES @@ -40,7 +39,6 @@ add_vpp_library(vcl_ldpreload add_vpp_headers(vcl ldp.h - vcl_event.h sock_test.h ldp_glibc_socket.h vcl_test.h @@ -59,8 +57,6 @@ if(VPP_BUILD_VCL_TESTS) vcl_test_client sock_test_server sock_test_client - test_vcl_listener_server - test_vcl_listener_client ) add_vpp_executable(${test} SOURCES ${test}.c LINK_LIBRARIES vppcom pthread NO_INSTALL) diff --git a/src/vcl/test_vcl_listener_client.c b/src/vcl/test_vcl_listener_client.c deleted file mode 100644 index 41c3cef773b..00000000000 --- a/src/vcl/test_vcl_listener_client.c +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright (c) 2018 Cisco and/or its affiliates. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include <stdio.h> -#include <sys/socket.h> -#include <netinet/in.h> -#include <string.h> -#include <arpa/inet.h> -#include <unistd.h> -#include <vcl/vppcom.h> - -int main(){ - int client_session; - char buffer[1024]; - struct sockaddr_in server_address; - vppcom_endpt_t endpt; - int rv; - - rv = vppcom_app_create ("test_vcl_listener_client"); - if (rv) return rv; - - client_session = vppcom_session_create(VPPCOM_PROTO_TCP, 0); - - memset(&server_address, 0, sizeof(server_address)); - server_address.sin_family = AF_INET; - server_address.sin_port = htons(9995); - server_address.sin_addr.s_addr = inet_addr("127.0.0.1"); - - endpt.is_ip4 = (server_address.sin_family == AF_INET); - endpt.ip = (uint8_t *) & server_address.sin_addr; - endpt.port = (uint16_t) server_address.sin_port; - - - vppcom_session_connect(client_session, &endpt); - - /*---- Read the message from the server into the buffer ----*/ - vppcom_session_read (client_session, buffer, 1024); - - /*---- Print the received message ----*/ - printf("Data received: %s",buffer); - - printf("Press ENTER key to Continue\n"); - (void) getchar(); - - return 0; -} diff --git a/src/vcl/test_vcl_listener_server.c b/src/vcl/test_vcl_listener_server.c deleted file mode 100644 index 0963af03e21..00000000000 --- a/src/vcl/test_vcl_listener_server.c +++ /dev/null @@ -1,105 +0,0 @@ -/* - * Copyright (c) 2018 Cisco and/or its affiliates. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - - -#include <string.h> -#include <errno.h> -#include <stdio.h> -#include <signal.h> -#include <stdlib.h> -#include <netinet/in.h> -#include <arpa/inet.h> -#include <sys/socket.h> - - -#include <vcl/vppcom.h> -#include <vcl/vcl_event.h> -#include <unistd.h> - -char MESSAGE[] = "Hello, World!\n"; - -static const int PORT = 9995; - -void -listener_cb (uint32_t new_session_index, vppcom_endpt_t *ep, void *stuff) -{ - - vppcom_session_write (new_session_index, &MESSAGE, sizeof (MESSAGE)); - printf ("\n Heard from port: %d\n", ep->port); -} - - -typedef struct vppcomm_listener_main_ -{ - int new_fd; - - struct event *event; - -} vppcomm_listener_main_t; - -vppcomm_listener_main_t _vlm_main; -vppcomm_listener_main_t *vlm = &_vlm_main; - - -int -main (int argc, char **argv) -{ - - int rv; - struct sockaddr_in sin; - uint32_t listen_fd; - vppcom_endpt_t endpt; - - clib_mem_init_thread_safe (0, 64<<20); - - //Address stuff - memset (&sin, 0, sizeof (sin)); - sin.sin_family = AF_INET; - sin.sin_port = htons (PORT); - //sin.sin_addr.s_addr = inet_addr("127.0.0.1"); - - endpt.is_ip4 = (sin.sin_family == AF_INET); - endpt.ip = (uint8_t *) & sin.sin_addr; - endpt.port = (uint16_t) sin.sin_port; - - //VCL stuff - rv = vppcom_app_create ("test_vcl_listener_server"); - if (rv) return rv; - - listen_fd = vppcom_session_create (VPPCOM_PROTO_TCP, - 0 /* is_nonblocking */ ); - - rv = vppcom_session_bind (listen_fd, &endpt); - - //Make a listener and dispatch - rv = vppcom_session_register_listener (listen_fd, listener_cb, 0, - 0, 0, &MESSAGE); - - if (rv) - { - fprintf (stderr, "Could not create a listener!\n"); - return 1; - } - - while (1) - { - sleep (3); - } - - printf ("done\n"); - return 0; -} - - diff --git a/src/vcl/vcl_event.c b/src/vcl/vcl_event.c deleted file mode 100644 index 38a78535ee7..00000000000 --- a/src/vcl/vcl_event.c +++ /dev/null @@ -1,554 +0,0 @@ -/* - * Copyright (c) 2019 Cisco and/or its affiliates. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include <vppinfra/fifo.h> -#include <vppinfra/pool.h> -#include <vppinfra/hash.h> -#include <vnet/api_errno.h> - -#include <vcl/vppcom.h> -#include <vcl/vcl_event.h> -#include <vcl/vcl_private.h> - -/** - * @file - * @brief VPP Communications Library (VCL) event handler. - * - * Definitions for generic event handling in VCL. - */ - -#define VCL_EVENTS_LOCK() \ - clib_spinlock_lock (&(vcm->event_thread.events_lockp)) -#define VCL_EVENTS_UNLOCK() \ - clib_spinlock_unlock (&(vcm->event_thread.events_lockp)) -#define VCL_IO_SESSIONS_LOCK() \ - clib_spinlock_lock (&(vcm->session_io_thread.io_sessions_lockp)) -#define VCL_IO_SESSIONS_UNLOCK() \ - clib_spinlock_unlock (&(vcm->session_io_thread.io_sessions_lockp)) - -int -vce_generate_event (vce_event_thread_t * evt, u32 ev_idx) -{ - int elts, rv = 0; - vce_event_t *p; - - pthread_mutex_lock (&(evt->generator_lock)); - - /* Check there is event data for this event */ - - VCE_EVENTS_LOCK (); - p = pool_elt_at_index (evt->vce_events, ev_idx); - ASSERT (p); - - elts = (int) clib_fifo_free_elts (evt->event_index_fifo); - if (PREDICT_TRUE (elts)) - { - /* Add event to queue */ - clib_fifo_add1 (evt->event_index_fifo, ev_idx); - pthread_cond_signal (&(evt->generator_cond)); - } - else - { - rv = VNET_API_ERROR_QUEUE_FULL; - } - - VCE_EVENTS_UNLOCK (); - pthread_mutex_unlock (&(evt->generator_lock)); - - return rv; -} - -void -vce_clear_event (vce_event_thread_t * evt, u32 ev_idx) -{ - VCE_EVENTS_LOCK (); - pool_put_index (evt->vce_events, ev_idx); - VCE_EVENTS_UNLOCK (); -} - -vce_event_t * -vce_get_event_from_index (vce_event_thread_t * evt, u32 ev_idx) -{ - vce_event_t *ev = 0; - /* Assumes caller has obtained the spinlock (evt->events_lockp) */ - - if (!pool_is_free_index (evt->vce_events, ev_idx)) - ev = pool_elt_at_index (evt->vce_events, ev_idx); - - return ev; -} - -vce_event_handler_reg_t * -vce_get_event_handler (vce_event_thread_t * evt, vce_event_key_t * evk) -{ - vce_event_handler_reg_t *handler = 0; - uword *p; - - VCE_HANDLERS_LOCK (); - p = hash_get (evt->handlers_index_by_event_key, evk->as_u64); - if (p) - handler = pool_elt_at_index (evt->vce_event_handlers, p[0]); - VCE_HANDLERS_UNLOCK (); - - return handler; -} - -vce_event_handler_reg_t * -vce_register_handler (vce_event_thread_t * evt, vce_event_key_t * evk, - vce_event_callback_t cb, void *cb_args) -{ - vce_event_handler_reg_t *handler; - vce_event_handler_reg_t *old_handler = 0; - uword *p; - u32 handler_index; - - /* TODO - multiple handler support. For now we can replace - * and re-instate, which is useful for event recycling */ - - VCE_HANDLERS_LOCK (); - - p = hash_get (evt->handlers_index_by_event_key, evk->as_u64); - if (p) - { - old_handler = pool_elt_at_index (evt->vce_event_handlers, p[0]); - /* If we are just re-registering, ignore and move on - * else store the old handler_fn for unregister to re-instate */ - if (old_handler->handler_fn == cb) - { - - VCE_HANDLERS_UNLOCK (); - - /* Signal event thread that a handler exists in case any - * recycled events requiring this handler are pending */ - pthread_mutex_lock (&(evt->generator_lock)); - pthread_cond_signal (&(evt->generator_cond)); - pthread_mutex_unlock (&(evt->generator_lock)); - return old_handler; - } - } - - pool_get (evt->vce_event_handlers, handler); - handler_index = (u32) (handler - evt->vce_event_handlers); - - handler->handler_fn = cb; - handler->replaced_handler_idx = (u32) ((p) ? p[0] : ~0); - handler->ev_idx = (u32) ~ 0; //This will be set by the event thread if event happens - handler->evk = evk->as_u64; - handler->handler_fn_args = cb_args; - - hash_set (evt->handlers_index_by_event_key, evk->as_u64, handler_index); - - pthread_cond_init (&(handler->handler_cond), NULL); - pthread_mutex_init (&(handler->handler_lock), NULL); - - VCE_HANDLERS_UNLOCK (); - - /* Signal event thread that a new handler exists in case any - * recycled events requiring this handler are pending */ - pthread_mutex_lock (&(evt->generator_lock)); - pthread_cond_signal (&(evt->generator_cond)); - pthread_mutex_unlock (&(evt->generator_lock)); - - return handler; -} - -int -vce_unregister_handler (vce_event_thread_t * evt, - vce_event_handler_reg_t * handler) -{ - uword *p; - u64 evk = handler->evk; - u8 generate_signal = 0; - - VCE_HANDLERS_LOCK (); - - p = hash_get (evt->handlers_index_by_event_key, evk); - if (!p) - { - VCE_HANDLERS_UNLOCK (); - return VNET_API_ERROR_NO_SUCH_ENTRY; - } - - handler = pool_elt_at_index (evt->vce_event_handlers, p[0]); - - /* If this handler replaced another handler, re-instate it */ - if (handler->replaced_handler_idx != ~0) - { - hash_set (evt->handlers_index_by_event_key, evk, - handler->replaced_handler_idx); - generate_signal = 1; - } - else - { - hash_unset (evt->handlers_index_by_event_key, evk); - } - - pthread_mutex_destroy (&(handler->handler_lock)); - pthread_cond_destroy (&(handler->handler_cond)); - pool_put (evt->vce_event_handlers, handler); - - VCE_HANDLERS_UNLOCK (); - - if (generate_signal) - { - /* Signal event thread that a new handler exists in case any - * recycled events requiring this handler are pending */ - pthread_mutex_lock (&(evt->generator_lock)); - pthread_cond_signal (&(evt->generator_cond)); - pthread_mutex_unlock (&(evt->generator_lock)); - } - - return 0; -} - -void * -vce_event_thread_fn (void *arg) -{ - vce_event_thread_t *evt = (vce_event_thread_t *) arg; - vce_event_t *ev; - u32 ev_idx; - vce_event_handler_reg_t *handler; - uword *p; - u32 recycle_count = 0; - - pthread_mutex_lock (&(evt->generator_lock)); - while (1) - { - uword fifo_depth = clib_fifo_elts (evt->event_index_fifo); - while ((fifo_depth == 0) || (recycle_count == fifo_depth)) - { - recycle_count = 0; - pthread_cond_wait (&(evt->generator_cond), &(evt->generator_lock)); - fifo_depth = clib_fifo_elts (evt->event_index_fifo); - } - - /* Remove event */ - VCE_EVENTS_LOCK (); - clib_fifo_sub1 (evt->event_index_fifo, ev_idx); - ev = vce_get_event_from_index (evt, ev_idx); - ASSERT (ev); - if (recycle_count && ev->recycle) - { - clib_fifo_add1 (evt->event_index_fifo, ev_idx); - VCE_EVENTS_UNLOCK (); - continue; - } - VCE_HANDLERS_LOCK (); - - p = hash_get (evt->handlers_index_by_event_key, ev->evk.as_u64); - if (!p) - { - /* If an event falls in the woods, and there is no handler to hear it, - * does it make any sound? - * I don't know either, so lets biff the event */ - pool_put (evt->vce_events, ev); - VCE_EVENTS_UNLOCK (); - VCE_HANDLERS_UNLOCK (); - pthread_mutex_unlock (&(evt->generator_lock)); - } - else - { - u32 evt_recycle = ev->recycle; - handler = pool_elt_at_index (evt->vce_event_handlers, p[0]); - handler->ev_idx = ev_idx; - ev->recycle = 0; - - VCE_EVENTS_UNLOCK (); - VCE_HANDLERS_UNLOCK (); - pthread_mutex_unlock (&(evt->generator_lock)); - - (handler->handler_fn) (handler); - - VCE_EVENTS_LOCK (); - ev = vce_get_event_from_index (evt, ev_idx); - recycle_count += (!evt_recycle && ev && ev->recycle) ? 1 : 0; - VCE_EVENTS_UNLOCK (); - } - - pthread_mutex_lock (&(evt->generator_lock)); - } - return NULL; -} - -int -vce_start_event_thread (vce_event_thread_t * evt, u8 max_events) -{ - clib_fifo_validate (evt->event_index_fifo, max_events); - evt->handlers_index_by_event_key = hash_create (0, sizeof (uword)); - - pthread_cond_init (&(evt->generator_cond), NULL); - pthread_mutex_init (&(evt->generator_lock), NULL); - - clib_spinlock_init (&(evt->events_lockp)); - clib_spinlock_init (&(evt->handlers_lockp)); - - return pthread_create (&(evt->thread), NULL /* attr */ , - vce_event_thread_fn, evt); -} - -static void * -vppcom_session_io_thread_fn (void *arg) -{ - vppcom_session_io_thread_t *evt = (vppcom_session_io_thread_t *) arg; - u32 *session_indexes = 0, *session_index; - int i; - u32 bytes = 0; - vcl_session_t *session; - - while (1) - { - vec_reset_length (session_indexes); - VCE_IO_SESSIONS_LOCK (); - /* *INDENT-OFF* */ - pool_foreach (session_index, evt->active_session_indexes, ({ - vec_add1 (session_indexes, *session_index); - })); - /* *INDENT-ON* */ - VCE_IO_SESSIONS_UNLOCK (); - if (session_indexes) - { - for (i = 0; i < vec_len (session_indexes); ++i) - { - session = vcl_session_get (0, session_indexes[i]); - if (!session) - return NULL; - bytes = svm_fifo_max_dequeue (session->rx_fifo); - - if (bytes) - { - vppcom_ioevent_t *eio; - vce_event_t *ev; - u32 ev_idx; - - VCL_EVENTS_LOCK (); - - pool_get (vcm->event_thread.vce_events, ev); - ev_idx = (u32) (ev - vcm->event_thread.vce_events); - eio = vce_get_event_data (ev, sizeof (*eio)); - ev->evk.eid = VCL_EVENT_IOEVENT_RX_FIFO; - ev->evk.session_index = session_indexes[i]; - eio->bytes = bytes; - eio->session_index = session_indexes[i]; - - VCL_EVENTS_UNLOCK (); - - vce_generate_event (&vcm->event_thread, ev_idx); - } - } - } - struct timespec ts; - ts.tv_sec = 0; - ts.tv_nsec = 1000000; /* 1 millisecond */ - nanosleep (&ts, NULL); - } - return NULL; -} - -static int -vppcom_start_io_event_thread (vppcom_session_io_thread_t * evt, - u8 max_sessions) -{ - pthread_cond_init (&(evt->vce_io_cond), NULL); - pthread_mutex_init (&(evt->vce_io_lock), NULL); - - clib_spinlock_init (&(evt->io_sessions_lockp)); - - return pthread_create (&(evt->thread), NULL /* attr */ , - vppcom_session_io_thread_fn, evt); -} - -static void -vce_registered_ioevent_handler_fn (void *arg) -{ - vce_event_handler_reg_t *reg = (vce_event_handler_reg_t *) arg; - vppcom_ioevent_t *eio; - vce_event_t *ev; - u32 ioevt_ndx = (u64) (reg->handler_fn_args); - vppcom_session_ioevent_t *ioevent, ioevent_; - - VCL_EVENTS_LOCK (); - ev = vce_get_event_from_index (&vcm->event_thread, reg->ev_idx); - eio = vce_get_event_data (ev, sizeof (*eio)); - VCL_EVENTS_UNLOCK (); - - VCL_IO_SESSIONS_LOCK (); - ioevent = pool_elt_at_index (vcm->session_io_thread.ioevents, ioevt_ndx); - ioevent_ = *ioevent; - VCL_IO_SESSIONS_UNLOCK (); - (ioevent_.user_cb) (eio, ioevent_.user_cb_data); - vce_clear_event (&vcm->event_thread, reg->ev_idx); - return; - - /*TODO - Unregister check in close for this listener */ - -} - -void -vce_registered_listener_connect_handler_fn (void *arg) -{ - vce_event_handler_reg_t *reg = (vce_event_handler_reg_t *) arg; - vce_event_connect_request_t *ecr; - vce_event_t *ev; - vppcom_endpt_t ep; - vcl_session_t *new_session; - - vppcom_session_listener_t *session_listener = - (vppcom_session_listener_t *) reg->handler_fn_args; - - VCL_EVENTS_LOCK (); - ev = vce_get_event_from_index (&vcm->event_thread, reg->ev_idx); - ecr = vce_get_event_data (ev, sizeof (*ecr)); - VCL_EVENTS_UNLOCK (); - new_session = vcl_session_get (0, ecr->accepted_session_index); - if (!new_session) - return; - - ep.is_ip4 = new_session->transport.is_ip4; - ep.port = new_session->transport.rmt_port; - if (new_session->transport.is_ip4) - clib_memcpy (&ep.ip, &new_session->transport.rmt_ip.ip4, - sizeof (ip4_address_t)); - else - clib_memcpy (&ep.ip, &new_session->transport.rmt_ip.ip6, - sizeof (ip6_address_t)); - - vppcom_send_accept_session_reply (new_session->vpp_handle, - new_session->client_context, - 0 /* retval OK */ ); - - (session_listener->user_cb) (ecr->accepted_session_index, &ep, - session_listener->user_cb_data); - - if (vcm->session_io_thread.io_sessions_lockp) - { - /* Throw this new accepted session index into the rx poll thread pool */ - VCL_IO_SESSIONS_LOCK (); - u32 *active_session_index; - pool_get (vcm->session_io_thread.active_session_indexes, - active_session_index); - *active_session_index = ecr->accepted_session_index; - VCL_IO_SESSIONS_UNLOCK (); - } - - /*TODO - Unregister check in close for this listener */ - return; - - ASSERT (0); // If we can't get a lock or accepted session fails, lets blow up. -} - -/** - * @brief vce_poll_wait_connect_request_handler_fn - * - used by vppcom_epoll_xxxx() for listener sessions - * - when a vl_api_accept_session_t_handler() generates an event - * this callback is alerted and sets the fields that vppcom_epoll_wait() - * expects to see. - * - * @param arg - void* to be cast to vce_event_handler_reg_t* - */ -void -vce_poll_wait_connect_request_handler_fn (void *arg) -{ - vce_event_handler_reg_t *reg = (vce_event_handler_reg_t *) arg; - vce_event_t *ev; - /* Retrieve the VCL_EVENT_CONNECT_REQ_ACCEPTED event */ - ev = vce_get_event_from_index (&vcm->event_thread, reg->ev_idx); - vce_event_connect_request_t *ecr = vce_get_event_data (ev, sizeof (*ecr)); - - /* Recycling the event. */ - VCL_EVENTS_LOCK (); - ev->recycle = 1; - clib_fifo_add1 (vcm->event_thread.event_index_fifo, reg->ev_idx); - VCL_EVENTS_UNLOCK (); -} - -int -vppcom_session_register_ioevent_cb (uint32_t session_index, - vppcom_session_ioevent_cb cb, - uint8_t rx, void *ptr) -{ - int rv = VPPCOM_OK; - vce_event_key_t evk; - vppcom_session_ioevent_t *ioevent; - - if (!vcm->session_io_thread.io_sessions_lockp) - rv = vppcom_start_io_event_thread (&vcm->session_io_thread, 100); /* DAW_TODO: ??? hard-coded value */ - - if (rv == VPPCOM_OK) - { - void *io_evt_ndx; - - /* Register handler for ioevent on session_index */ - VCL_IO_SESSIONS_LOCK (); - pool_get (vcm->session_io_thread.ioevents, ioevent); - io_evt_ndx = (void *) (ioevent - vcm->session_io_thread.ioevents); - ioevent->user_cb = cb; - ioevent->user_cb_data = ptr; - VCL_IO_SESSIONS_UNLOCK (); - - evk.session_index = session_index; - evk.eid = rx ? VCL_EVENT_IOEVENT_RX_FIFO : VCL_EVENT_IOEVENT_TX_FIFO; - - (void) vce_register_handler (&vcm->event_thread, &evk, - vce_registered_ioevent_handler_fn, - io_evt_ndx); - } - return rv; -} - -int -vppcom_session_register_listener (uint32_t session_index, - vppcom_session_listener_cb cb, - vppcom_session_listener_errcb - errcb, uint8_t flags, int q_len, void *ptr) -{ - int rv = VPPCOM_OK; - vce_event_key_t evk; - vppcom_session_listener_t *listener_args; - - if (!vcm->session_io_thread.io_sessions_lockp) - rv = vppcom_start_io_event_thread (&vcm->session_io_thread, 100); /* DAW_TODO: ??? hard-coded value */ - if (rv) - { - goto done; - } - rv = vppcom_session_listen (session_index, q_len); - if (rv) - { - goto done; - } - - /* Register handler for connect_request event on listen_session_index */ - listener_args = clib_mem_alloc (sizeof (vppcom_session_listener_t)); // DAW_TODO: Use a pool instead of thrashing the memory allocator! - listener_args->user_cb = cb; - listener_args->user_cb_data = ptr; - listener_args->user_errcb = errcb; - - evk.session_index = session_index; - evk.eid = VCL_EVENT_CONNECT_REQ_ACCEPTED; - (void) vce_register_handler (&vcm->event_thread, &evk, - vce_registered_listener_connect_handler_fn, - listener_args); - -done: - return rv; -} - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "gnu") - * End: - */ diff --git a/src/vcl/vcl_event.h b/src/vcl/vcl_event.h deleted file mode 100644 index 69a5ba356c0..00000000000 --- a/src/vcl/vcl_event.h +++ /dev/null @@ -1,327 +0,0 @@ -/* - * Copyright (c) 2018 Cisco and/or its affiliates. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef VPP_VCL_EVENT_H -#define VPP_VCL_EVENT_H - -#include <vppinfra/cache.h> -#include <vppinfra/mem.h> - -#define VCE_EVENTS_LOCK() clib_spinlock_lock (&(evt->events_lockp)) -#define VCE_EVENTS_UNLOCK() clib_spinlock_unlock (&(evt->events_lockp)) -#define VCE_HANDLERS_LOCK() clib_spinlock_lock (&(evt->handlers_lockp)) -#define VCE_HANDLERS_UNLOCK() clib_spinlock_unlock (&(evt->handlers_lockp)) -#define VCE_IO_SESSIONS_LOCK() clib_spinlock_lock (&(evt->io_sessions_lockp)) -#define VCE_IO_SESSIONS_UNLOCK() \ - clib_spinlock_unlock (&(evt->io_sessions_lockp)) - -typedef struct vppcom_ioevent_ -{ - uint32_t session_index; - size_t bytes; -} vppcom_ioevent_t; - -/** - * @file - * @brief VPP Communications Library (VCL) event handler. - * - * Declarations for generic event handling in VCL. - */ - -#include <vppinfra/types.h> -#include <vppinfra/lock.h> -#include <pthread.h> - -/** - * User registered callback for when connection arrives on listener created - * with vppcom_session_register_listener() - * @param uint32_t - newly accepted session_index - * @param vppcom_endpt_t* - ip/port information of remote - * @param void* - user passed arg to pass back - */ -typedef void (*vppcom_session_listener_cb) (uint32_t, vppcom_endpt_t *, - void *); - -/** - * User registered callback for IO events (rx/tx) - * @param vppcom_ioevent_t* - - * @param void* - user passed arg to pass back - */ -typedef void (*vppcom_session_ioevent_cb) (vppcom_ioevent_t *, void *); - -/** - * User registered ERROR callback for any errors associated with - * handling vppcom_session_register_listener() and connections - * @param void* - user passed arg to pass back - */ -typedef void (*vppcom_session_listener_errcb) (void *); - - -typedef enum vcl_event_id_ -{ - VCL_EVENT_INVALID_EVENT, - VCL_EVENT_CONNECT_REQ_ACCEPTED, - VCL_EVENT_IOEVENT_RX_FIFO, - VCL_EVENT_IOEVENT_TX_FIFO, - VCL_EVENT_N_EVENTS -} vcl_event_id_t; - -/* VPPCOM Event typedefs */ -typedef struct vppcom_session_listener -{ - vppcom_session_listener_cb user_cb; - vppcom_session_listener_errcb user_errcb; - void *user_cb_data; -} vppcom_session_listener_t; - -typedef struct vppcom_session_ioevent_ -{ - vppcom_session_ioevent_cb user_cb; - void *user_cb_data; -} vppcom_session_ioevent_t; - -typedef struct vppcom_session_io_thread_ -{ - pthread_t thread; - pthread_mutex_t vce_io_lock; - pthread_cond_t vce_io_cond; - u32 *active_session_indexes; //pool - vppcom_session_ioevent_t *ioevents; //pool - clib_spinlock_t io_sessions_lockp; -} vppcom_session_io_thread_t; - -typedef struct vce_event_connect_request_ -{ - u32 accepted_session_index; -} vce_event_connect_request_t; - -typedef union vce_event_key_ -{ - struct { - u32 eid; - u32 session_index; - }; - u64 as_u64; -} vce_event_key_t; - -typedef struct vce_event_ -{ - vce_event_key_t evk; - u32 recycle; - u64 data[2]; // Hard code size to avoid allocator thrashing. -} vce_event_t; - -typedef void (*vce_event_callback_t) (void *reg /*vce_event_handler_reg_t* */); - -typedef struct vce_event_handler_reg_ -{ - vce_event_callback_t handler_fn; - pthread_mutex_t handler_lock; - pthread_cond_t handler_cond; - u32 ev_idx; - u64 evk; //Event key - u32 replaced_handler_idx; - void *handler_fn_args; -} vce_event_handler_reg_t; - -typedef struct vce_event_thread_ -{ - pthread_t thread; - pthread_mutex_t generator_lock; - pthread_cond_t generator_cond; - u32 *event_index_fifo; - u8 recycle_event; - clib_spinlock_t events_lockp; - vce_event_t *vce_events; //pool - clib_spinlock_t handlers_lockp; - vce_event_handler_reg_t *vce_event_handlers; //pool - uword *handlers_index_by_event_key; //hash -} vce_event_thread_t; - - -/** - * @brief vppcom_session_register_listener accepts a bound session_index, and - * listens for connections. - * - * On successful connection, calls registered callback (cb) with new - * session_index. - * - * On error, calls registered error callback (errcb). - * - * @param session_index - bound session_index to create listener on - * @param cb - on new accepted session callback - * @param errcb - on failure callback - * @param flags - placeholder for future use. Must be ZERO - * @param q_len - max listener connection backlog - * @param ptr - user data - * @return - */ -extern int vppcom_session_register_ioevent_cb (uint32_t session_index, - vppcom_session_ioevent_cb cb, - uint8_t rx, void *ptr); - -/** - * @brief vppcom_session_register_listener accepts a bound session_index, and - * listens for connections. - * - * On successful connection, calls registered callback (cb) with new - * session_index. - * - * On error, calls registered error callback (errcb). - * - * @param session_index - bound session_index to create listener on - * @param cb - on new accepted session callback - * @param errcb - on failure callback - * @param flags - placeholder for future use. Must be ZERO - * @param q_len - max listener connection backlog - * @param ptr - user data - * @return - */ -extern int vppcom_session_register_listener (uint32_t session_index, - vppcom_session_listener_cb cb, - vppcom_session_listener_errcb - errcb, uint8_t flags, int q_len, - void *ptr); - -/** - * @brief vce_generate_event - * - used to trigger an event in the event thread so that registered - * handlers are notified - * - * @param evt - vce_event_thread_t - event system state - * @param ev_idx - index to vce_event_thread_t vce_event pool - * - * @return success/failure rv - */ -int vce_generate_event (vce_event_thread_t *evt, u32 ev_idx); - -/** - * @brief vce_clear_event() - * - removes event from event_pool - * - * @param evt - vce_event_thread_t - event system state - * @param ev_idx - u32 - index of event to remove - */ -void vce_clear_event (vce_event_thread_t *evt, u32 ev_idx); - -/** - * @brief vce_get_event_from_index() - * - * @param evt - vce_event_thread_t - event system state - * @param ev_idx - index to vce_event_thread_t vce_event pool - * - * @return vce_event_t * - */ -vce_event_t * vce_get_event_from_index(vce_event_thread_t *evt, u32 ev_idx); - -/** - * @brief vce_get_event_data() - * - * @param ev - vce_event_t * - event - * @param data_size - u32 - required size of data - * - * @return vce_event_t * - */ -always_inline void * vce_get_event_data(vce_event_t *ev, u32 data_size) -{ - ASSERT(sizeof(ev->data) >= data_size); - return (&ev->data); -} - -/** - * @brief vce_get_event_handler() - * - returns handler if exists or 0 - * @param evt - vce_event_thread_t - event system state - * @param evk - event key - * @return vce_event_handler_reg_t * - */ -vce_event_handler_reg_t * vce_get_event_handler (vce_event_thread_t *evt, - vce_event_key_t *evk); - -/** - * @brief vce_register_handler - * - used by functions who need to be notified that an event has occurred - * on a vce_event_key_t (i.e. event type (enum) and sessionID) - * - if a handler already exists, the index to the old handler is stored - * inside the new handler for re-instatement on vce_unregister_handler() - - * @param evt - vce_event_thread_t - event system state - * @param evk - vce_event_key_t current an eventID from enum in consumer and - * sessionID - * @param cb - vce_event_callback_t function to handle event - * @param cb_args - args that the callback needs passed back to it. - * @return vce_handler_reg_t - the function that needs event notification - * needs to block on a condvar mutex to reduce spin. That is in here. - */ -vce_event_handler_reg_t * vce_register_handler (vce_event_thread_t *evt, - vce_event_key_t *evk, - vce_event_callback_t cb, - void *cb_args); - -/** - * @brief vce_unregister_handler - * - used by functions to remove need to be notified that an event has occurred - * on a vce_event_key_t (i.e. event type (enum) and sessionID) - * - if this handler replaced an existing one, re-instate it. - * - * @param evt - vce_event_thread_t - event system state - * @param handler - handler to be unregistered - * @return success/failure rv - */ -int vce_unregister_handler (vce_event_thread_t *evt, - vce_event_handler_reg_t *handler); - -/** - * @brief vce_event_thread_fn - * - main event thread that waits on a generic condvar/mutex that a signal - * has been generated. - * - loops through all registered handlers for that vce_event_key_t - * (event enum + sessionID) - * - * @param arg - cast to type of event defined in consuming program. - * @return - */ -extern void * vce_event_thread_fn (void *arg); - -/** - * @brief vce_start_event_thread - * - as name suggests. What is important is that vce_event_thread_t is allocated - * on the same heap as "everything else". ie use clib_mem_alloc. - * @param evt - vce_event_thread_t - event system state - * @param max_events - depth of event FIFO for max number of outstanding events. - * @return succes/failure - */ -int vce_start_event_thread (vce_event_thread_t *evt, u8 max_events); - -/** - * * @brief vce_connect_request_handler_fn - * - used for listener sessions - * - when a vl_api_accept_session_t_handler() generates an event - * this callback is alerted and sets fields that consumers such as - * vppcom_session_accept() expect to see, ie. accepted_client_index - * - * @param arg - void* to be cast to vce_event_handler_reg_t* - */ -always_inline void -vce_connect_request_handler_fn (void *arg) -{ - vce_event_handler_reg_t *reg = (vce_event_handler_reg_t *) arg; - - pthread_mutex_lock (®->handler_lock); - pthread_cond_signal (®->handler_cond); - pthread_mutex_unlock (®->handler_lock); -} - -#endif //VPP_VCL_EVENT_H diff --git a/src/vcl/vcl_private.h b/src/vcl/vcl_private.h index 29508415cbe..5975f15ac4f 100644 --- a/src/vcl/vcl_private.h +++ b/src/vcl/vcl_private.h @@ -18,7 +18,6 @@ #include <vnet/session/application_interface.h> #include <vcl/vppcom.h> -#include <vcl/vcl_event.h> #include <vcl/vcl_debug.h> #if (CLIB_DEBUG > 0) @@ -302,13 +301,6 @@ typedef struct vppcom_main_t_ /* VNET_API_ERROR_FOO -> "Foo" hash table */ uword *error_string_by_error_number; - /* Obsolete */ - - /* Event thread */ - vce_event_thread_t event_thread; - - /* IO thread */ - vppcom_session_io_thread_t session_io_thread; } vppcom_main_t; extern vppcom_main_t *vcm; diff --git a/src/vcl/vppcom.c b/src/vcl/vppcom.c index 16b467f5a36..7274749a93d 100644 --- a/src/vcl/vppcom.c +++ b/src/vcl/vppcom.c @@ -17,7 +17,6 @@ #include <stdlib.h> #include <svm/svm_fifo_segment.h> #include <vcl/vppcom.h> -#include <vcl/vcl_event.h> #include <vcl/vcl_debug.h> #include <vcl/vcl_private.h> diff --git a/src/vcl/vppcom.h b/src/vcl/vppcom.h index 63466844a3f..4c7d2092599 100644 --- a/src/vcl/vppcom.h +++ b/src/vcl/vppcom.h @@ -278,11 +278,6 @@ extern int vppcom_data_segment_copy (void *buf, vppcom_data_segments_t ds, */ extern int vppcom_worker_register (void); -/* - * VPPCOM Event Functions - */ -extern void vce_poll_wait_connect_request_handler_fn (void *arg); - /* *INDENT-OFF* */ #ifdef __cplusplus } |