2 * Copyright (c) 2018 Cisco and/or its affiliates.
3 * Licensed under the Apache License, Version 2.0 (the "License");
5 * You may obtain a copy of the License at:
7 * http://www.apache.org/licenses/LICENSE-2.0
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
16 #ifndef VPP_VCL_EVENT_H
17 #define VPP_VCL_EVENT_H
19 #include <vppinfra/cache.h>
20 #include <vppinfra/mem.h>
22 #define VCE_EVENTS_LOCK() clib_spinlock_lock (&(evt->events_lockp))
23 #define VCE_EVENTS_UNLOCK() clib_spinlock_unlock (&(evt->events_lockp))
24 #define VCE_HANDLERS_LOCK() clib_spinlock_lock (&(evt->handlers_lockp))
25 #define VCE_HANDLERS_UNLOCK() clib_spinlock_unlock (&(evt->handlers_lockp))
26 #define VCE_IO_SESSIONS_LOCK() clib_spinlock_lock (&(evt->io_sessions_lockp))
27 #define VCE_IO_SESSIONS_UNLOCK() \
28 clib_spinlock_unlock (&(evt->io_sessions_lockp))
30 typedef struct vppcom_ioevent_
32 uint32_t session_index;
38 * @brief VPP Communications Library (VCL) event handler.
40 * Declarations for generic event handling in VCL.
43 #include <vppinfra/types.h>
44 #include <vppinfra/lock.h>
48 * User registered callback for when connection arrives on listener created
49 * with vppcom_session_register_listener()
50 * @param uint32_t - newly accepted session_index
51 * @param vppcom_endpt_t* - ip/port information of remote
52 * @param void* - user passed arg to pass back
54 typedef void (*vppcom_session_listener_cb) (uint32_t, vppcom_endpt_t *,
58 * User registered callback for IO events (rx/tx)
59 * @param vppcom_ioevent_t* -
60 * @param void* - user passed arg to pass back
62 typedef void (*vppcom_session_ioevent_cb) (vppcom_ioevent_t *, void *);
65 * User registered ERROR callback for any errors associated with
66 * handling vppcom_session_register_listener() and connections
67 * @param void* - user passed arg to pass back
69 typedef void (*vppcom_session_listener_errcb) (void *);
72 typedef enum vcl_event_id_
74 VCL_EVENT_INVALID_EVENT,
75 VCL_EVENT_CONNECT_REQ_ACCEPTED,
76 VCL_EVENT_IOEVENT_RX_FIFO,
77 VCL_EVENT_IOEVENT_TX_FIFO,
81 /* VPPCOM Event typedefs */
82 typedef struct vppcom_session_listener
84 vppcom_session_listener_cb user_cb;
85 vppcom_session_listener_errcb user_errcb;
87 } vppcom_session_listener_t;
89 typedef struct vppcom_session_ioevent_
91 vppcom_session_ioevent_cb user_cb;
93 } vppcom_session_ioevent_t;
95 typedef struct vppcom_session_io_thread_
98 pthread_mutex_t vce_io_lock;
99 pthread_cond_t vce_io_cond;
100 u32 *active_session_indexes; //pool
101 vppcom_session_ioevent_t *ioevents; //pool
102 clib_spinlock_t io_sessions_lockp;
103 } vppcom_session_io_thread_t;
105 typedef struct vce_event_connect_request_
107 u32 accepted_session_index;
108 } vce_event_connect_request_t;
110 typedef union vce_event_key_
119 typedef struct vce_event_
123 u64 data[2]; // Hard code size to avoid allocator thrashing.
126 typedef void (*vce_event_callback_t) (void *reg /*vce_event_handler_reg_t* */);
128 typedef struct vce_event_handler_reg_
130 vce_event_callback_t handler_fn;
131 pthread_mutex_t handler_lock;
132 pthread_cond_t handler_cond;
135 u32 replaced_handler_idx;
136 void *handler_fn_args;
137 } vce_event_handler_reg_t;
139 typedef struct vce_event_thread_
142 pthread_mutex_t generator_lock;
143 pthread_cond_t generator_cond;
144 u32 *event_index_fifo;
146 clib_spinlock_t events_lockp;
147 vce_event_t *vce_events; //pool
148 clib_spinlock_t handlers_lockp;
149 vce_event_handler_reg_t *vce_event_handlers; //pool
150 uword *handlers_index_by_event_key; //hash
151 } vce_event_thread_t;
155 * @brief vppcom_session_register_listener accepts a bound session_index, and
156 * listens for connections.
158 * On successful connection, calls registered callback (cb) with new
161 * On error, calls registered error callback (errcb).
163 * @param session_index - bound session_index to create listener on
164 * @param cb - on new accepted session callback
165 * @param errcb - on failure callback
166 * @param flags - placeholder for future use. Must be ZERO
167 * @param q_len - max listener connection backlog
168 * @param ptr - user data
171 extern int vppcom_session_register_ioevent_cb (uint32_t session_index,
172 vppcom_session_ioevent_cb cb,
173 uint8_t rx, void *ptr);
176 * @brief vppcom_session_register_listener accepts a bound session_index, and
177 * listens for connections.
179 * On successful connection, calls registered callback (cb) with new
182 * On error, calls registered error callback (errcb).
184 * @param session_index - bound session_index to create listener on
185 * @param cb - on new accepted session callback
186 * @param errcb - on failure callback
187 * @param flags - placeholder for future use. Must be ZERO
188 * @param q_len - max listener connection backlog
189 * @param ptr - user data
192 extern int vppcom_session_register_listener (uint32_t session_index,
193 vppcom_session_listener_cb cb,
194 vppcom_session_listener_errcb
195 errcb, uint8_t flags, int q_len,
199 * @brief vce_generate_event
200 * - used to trigger an event in the event thread so that registered
201 * handlers are notified
203 * @param evt - vce_event_thread_t - event system state
204 * @param ev_idx - index to vce_event_thread_t vce_event pool
206 * @return success/failure rv
208 int vce_generate_event (vce_event_thread_t *evt, u32 ev_idx);
211 * @brief vce_clear_event()
212 * - removes event from event_pool
214 * @param evt - vce_event_thread_t - event system state
215 * @param ev_idx - u32 - index of event to remove
217 void vce_clear_event (vce_event_thread_t *evt, u32 ev_idx);
220 * @brief vce_get_event_from_index()
222 * @param evt - vce_event_thread_t - event system state
223 * @param ev_idx - index to vce_event_thread_t vce_event pool
225 * @return vce_event_t *
227 vce_event_t * vce_get_event_from_index(vce_event_thread_t *evt, u32 ev_idx);
230 * @brief vce_get_event_data()
232 * @param ev - vce_event_t * - event
233 * @param data_size - u32 - required size of data
235 * @return vce_event_t *
237 always_inline void * vce_get_event_data(vce_event_t *ev, u32 data_size)
239 ASSERT(sizeof(ev->data) >= data_size);
244 * @brief vce_get_event_handler()
245 * - returns handler if exists or 0
246 * @param evt - vce_event_thread_t - event system state
247 * @param evk - event key
248 * @return vce_event_handler_reg_t *
250 vce_event_handler_reg_t * vce_get_event_handler (vce_event_thread_t *evt,
251 vce_event_key_t *evk);
254 * @brief vce_register_handler
255 * - used by functions who need to be notified that an event has occurred
256 * on a vce_event_key_t (i.e. event type (enum) and sessionID)
257 * - if a handler already exists, the index to the old handler is stored
258 * inside the new handler for re-instatement on vce_unregister_handler()
260 * @param evt - vce_event_thread_t - event system state
261 * @param evk - vce_event_key_t current an eventID from enum in consumer and
263 * @param cb - vce_event_callback_t function to handle event
264 * @param cb_args - args that the callback needs passed back to it.
265 * @return vce_handler_reg_t - the function that needs event notification
266 * needs to block on a condvar mutex to reduce spin. That is in here.
268 vce_event_handler_reg_t * vce_register_handler (vce_event_thread_t *evt,
269 vce_event_key_t *evk,
270 vce_event_callback_t cb,
274 * @brief vce_unregister_handler
275 * - used by functions to remove need to be notified that an event has occurred
276 * on a vce_event_key_t (i.e. event type (enum) and sessionID)
277 * - if this handler replaced an existing one, re-instate it.
279 * @param evt - vce_event_thread_t - event system state
280 * @param handler - handler to be unregistered
281 * @return success/failure rv
283 int vce_unregister_handler (vce_event_thread_t *evt,
284 vce_event_handler_reg_t *handler);
287 * @brief vce_event_thread_fn
288 * - main event thread that waits on a generic condvar/mutex that a signal
289 * has been generated.
290 * - loops through all registered handlers for that vce_event_key_t
291 * (event enum + sessionID)
293 * @param arg - cast to type of event defined in consuming program.
296 extern void * vce_event_thread_fn (void *arg);
299 * @brief vce_start_event_thread
300 * - as name suggests. What is important is that vce_event_thread_t is allocated
301 * on the same heap as "everything else". ie use clib_mem_alloc.
302 * @param evt - vce_event_thread_t - event system state
303 * @param max_events - depth of event FIFO for max number of outstanding events.
304 * @return succes/failure
306 int vce_start_event_thread (vce_event_thread_t *evt, u8 max_events);
309 * * @brief vce_connect_request_handler_fn
310 * - used for listener sessions
311 * - when a vl_api_accept_session_t_handler() generates an event
312 * this callback is alerted and sets fields that consumers such as
313 * vppcom_session_accept() expect to see, ie. accepted_client_index
315 * @param arg - void* to be cast to vce_event_handler_reg_t*
318 vce_connect_request_handler_fn (void *arg)
320 vce_event_handler_reg_t *reg = (vce_event_handler_reg_t *) arg;
322 pthread_mutex_lock (®->handler_lock);
323 pthread_cond_signal (®->handler_cond);
324 pthread_mutex_unlock (®->handler_lock);
327 #endif //VPP_VCL_EVENT_H