VCL IOEvent external API callback
[vpp.git] / src / vcl / vcl_event.h
1 /*
2  * Copyright (c) 2018 Cisco and/or its affiliates.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this
5  * You may obtain a copy of the License at:
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
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.
14  */
15
16 #ifndef VPP_VCL_EVENT_H
17 #define VPP_VCL_EVENT_H
18
19 /**
20  * @file
21  * @brief VPP Communications Library (VCL) event handler.
22  *
23  * Declarations for generic event handling in VCL.
24  */
25
26 #include <vppinfra/types.h>
27 #include <vppinfra/lock.h>
28 #include <pthread.h>
29
30 typedef union vce_event_key_
31 {
32   struct {
33     u32 eid;
34     u32 session_index;
35   };
36   u64 as_u64;
37 } vce_event_key_t;
38
39 typedef struct vce_event_
40 {
41   vce_event_key_t evk;
42   u32 recycle;
43   u64 data[2]; // Hard code size to avoid allocator thrashing.
44 } vce_event_t;
45
46 typedef void (*vce_event_callback_t) (void *reg /*vce_event_handler_reg_t* */);
47
48 typedef struct vce_event_handler_reg_
49 {
50   vce_event_callback_t handler_fn;
51   pthread_mutex_t handler_lock;
52   pthread_cond_t handler_cond;
53   u32 ev_idx;
54   u64 evk; //Event key
55   u32 replaced_handler_idx;
56   void *handler_fn_args;
57 } vce_event_handler_reg_t;
58
59 typedef struct vce_event_thread_
60 {
61   pthread_t thread;
62   pthread_mutex_t generator_lock;
63   pthread_cond_t generator_cond;
64   u32 *event_index_fifo;
65   u8 recycle_event;
66   clib_spinlock_t events_lockp;
67   vce_event_t *vce_events; //pool
68   clib_spinlock_t handlers_lockp;
69   vce_event_handler_reg_t *vce_event_handlers; //pool
70   uword *handlers_index_by_event_key; //hash
71 } vce_event_thread_t;
72
73 /**
74  * @brief vce_generate_event
75  * - used to trigger an event in the event thread so that registered
76  *   handlers are notified
77  *
78  * @param evt - vce_event_thread_t - event system state
79  * @param ev_idx - index to vce_event_thread_t vce_event pool
80  *
81  * @return success/failure rv
82  */
83 int vce_generate_event (vce_event_thread_t *evt, u32 ev_idx);
84
85 /**
86  * @brief vce_clear_event()
87  * - removes event from event_pool
88  *
89  * @param evt - vce_event_thread_t - event system state
90  * @param ev_idx  - u32 - index of event to remove
91  */
92 void vce_clear_event (vce_event_thread_t *evt, u32 ev_idx);
93
94 /**
95  * @brief vce_get_event_from_index()
96  *
97  * @param evt - vce_event_thread_t - event system state
98  * @param ev_idx - index to vce_event_thread_t vce_event pool
99  *
100  * @return vce_event_t *
101  */
102 vce_event_t * vce_get_event_from_index(vce_event_thread_t *evt, u32 ev_idx);
103
104 /**
105  * @brief vce_get_event_data()
106  *
107  * @param ev - vce_event_t * - event
108  * @param data_size - u32 - required size of data
109  *
110  * @return vce_event_t *
111  */
112 always_inline void * vce_get_event_data(vce_event_t *ev, u32 data_size)
113 {
114         ASSERT(sizeof(ev->data) >= data_size);
115         return (&ev->data);
116 }
117
118 /**
119  * @brief vce_get_event_handler()
120  * - returns handler if exists or 0
121  * @param evt - vce_event_thread_t - event system state
122  * @param evk - event key
123  * @return vce_event_handler_reg_t *
124  */
125 vce_event_handler_reg_t * vce_get_event_handler (vce_event_thread_t *evt,
126                                                  vce_event_key_t *evk);
127
128 /**
129  * @brief vce_register_handler
130  * - used by functions who need to be notified that an event has occurred
131  *   on a vce_event_key_t (i.e. event type (enum) and sessionID)
132  * - if a handler already exists, the index to the old handler is stored
133  *   inside the new handler for re-instatement on vce_unregister_handler()
134
135  * @param evt - vce_event_thread_t - event system state
136  * @param evk - vce_event_key_t current an eventID from enum in consumer and
137  *              sessionID
138  * @param cb  - vce_event_callback_t function to handle event
139  * @param cb_args - args that the callback needs passed back to it.
140  * @return vce_handler_reg_t - the function that needs event notification
141  *   needs to block on a condvar mutex to reduce spin. That is in here.
142  */
143 vce_event_handler_reg_t * vce_register_handler (vce_event_thread_t *evt,
144                                                 vce_event_key_t *evk,
145                                                 vce_event_callback_t cb,
146                                                 void *cb_args);
147
148 /**
149  * @brief vce_unregister_handler
150  * - used by functions to remove need to be notified that an event has occurred
151  *   on a vce_event_key_t (i.e. event type (enum) and sessionID)
152  * - if this handler replaced an existing one, re-instate it.
153  *
154  * @param evt - vce_event_thread_t - event system state
155  * @param handler - handler to be unregistered
156  * @return success/failure rv
157  */
158 int vce_unregister_handler (vce_event_thread_t *evt,
159                             vce_event_handler_reg_t *handler);
160
161 /**
162  * @brief vce_event_thread_fn
163  * - main event thread that waits on a generic condvar/mutex that a signal
164  *   has been generated.
165  *   - loops through all registered handlers for that vce_event_key_t
166  *   (event enum + sessionID)
167  *
168  * @param arg - cast to type of event defined in consuming program.
169  * @return
170  */
171 extern void * vce_event_thread_fn (void *arg);
172
173 /**
174  * @brief vce_start_event_thread
175  * - as name suggests. What is important is that vce_event_thread_t is allocated
176  * on the same heap as "everything else". ie use clib_mem_alloc.
177  * @param evt - vce_event_thread_t - event system state
178  * @param max_events - depth of event FIFO for max number of outstanding events.
179  * @return succes/failure
180  */
181 int vce_start_event_thread (vce_event_thread_t *evt, u8 max_events);
182
183 #endif //VPP_VCL_EVENT_H