2 * Copyright (c) 2019 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 #include <vcl/vcl_locked.h>
17 #include <vcl/vcl_private.h>
19 typedef struct vcl_locked_session_
26 } vcl_locked_session_t;
28 typedef struct vcl_main_
30 vcl_locked_session_t *vls_pool;
31 clib_rwlock_t vls_table_lock;
32 uword *session_index_to_vlsh_table;
36 vls_main_t *vlsm = &vls_main;
39 vls_table_rlock (void)
41 clib_rwlock_reader_lock (&vlsm->vls_table_lock);
45 vls_table_runlock (void)
47 clib_rwlock_reader_unlock (&vlsm->vls_table_lock);
51 vls_table_wlock (void)
53 clib_rwlock_writer_lock (&vlsm->vls_table_lock);
57 vls_table_wunlock (void)
59 clib_rwlock_writer_unlock (&vlsm->vls_table_lock);
62 static inline vcl_session_handle_t
63 vls_to_sh (vcl_locked_session_t * vls)
65 return vppcom_session_handle (vls->session_index);
68 static inline vcl_session_handle_t
69 vls_to_sh_tu (vcl_locked_session_t * vls)
71 vcl_session_handle_t sh;
78 vls_alloc (vcl_session_handle_t sh)
80 vcl_locked_session_t *vls;
83 pool_get (vlsm->vls_pool, vls);
84 vls->session_index = vppcom_session_index (sh);
85 vls->worker_index = vppcom_session_worker (sh);
86 vls->vls_index = vls - vlsm->vls_pool;
87 hash_set (vlsm->session_index_to_vlsh_table, vls->session_index,
89 clib_spinlock_init (&vls->lock);
91 return vls->vls_index;
94 static vcl_locked_session_t *
95 vls_get (vls_handle_t vlsh)
97 if (pool_is_free_index (vlsm->vls_pool, vlsh))
99 return pool_elt_at_index (vlsm->vls_pool, vlsh);
103 vls_free (vcl_locked_session_t * fde)
106 hash_unset (vlsm->session_index_to_vlsh_table, fde->session_index);
107 clib_spinlock_free (&fde->lock);
108 pool_put (vlsm->vls_pool, fde);
111 static vcl_locked_session_t *
112 vls_get_and_lock (vls_handle_t vlsh)
114 vcl_locked_session_t *vls;
115 if (pool_is_free_index (vlsm->vls_pool, vlsh))
117 vls = pool_elt_at_index (vlsm->vls_pool, vlsh);
118 clib_spinlock_lock (&vls->lock);
122 static vcl_locked_session_t *
123 vls_get_w_dlock (vls_handle_t vlsh)
125 vcl_locked_session_t *vls;
127 vls = vls_get_and_lock (vlsh);
129 vls_table_runlock ();
134 vls_unlock (vcl_locked_session_t * vls)
136 clib_spinlock_unlock (&vls->lock);
140 vls_get_and_unlock (vls_handle_t vlsh)
142 vcl_locked_session_t *vls;
144 vls = vls_get (vlsh);
146 vls_table_runlock ();
150 vls_dunlock (vcl_locked_session_t * vls)
153 vls_table_runlock ();
157 vls_get_and_free (vls_handle_t vlsh)
159 vcl_locked_session_t *vls;
162 vls = vls_get (vlsh);
164 vls_table_wunlock ();
168 vls_write (vls_handle_t vlsh, void *buf, size_t nbytes)
170 vcl_locked_session_t *vls;
173 if (!(vls = vls_get_w_dlock (vlsh)))
174 return VPPCOM_EBADFD;
175 rv = vppcom_session_write (vls_to_sh_tu (vls), buf, nbytes);
176 vls_get_and_unlock (vlsh);
181 vls_write_msg (vls_handle_t vlsh, void *buf, size_t nbytes)
183 vcl_locked_session_t *vls;
186 if (!(vls = vls_get_w_dlock (vlsh)))
187 return VPPCOM_EBADFD;
188 rv = vppcom_session_write_msg (vls_to_sh_tu (vls), buf, nbytes);
189 vls_get_and_unlock (vlsh);
194 vls_sendto (vls_handle_t vlsh, void *buf, int buflen, int flags,
197 vcl_locked_session_t *vls;
200 if (!(vls = vls_get_w_dlock (vlsh)))
201 return VPPCOM_EBADFD;
202 rv = vppcom_session_sendto (vls_to_sh_tu (vls), buf, buflen, flags, ep);
203 vls_get_and_unlock (vlsh);
208 vls_read (vls_handle_t vlsh, void *buf, size_t nbytes)
210 vcl_locked_session_t *vls;
213 if (!(vls = vls_get_w_dlock (vlsh)))
214 return VPPCOM_EBADFD;
215 rv = vppcom_session_read (vls_to_sh_tu (vls), buf, nbytes);
216 vls_get_and_unlock (vlsh);
221 vls_recvfrom (vls_handle_t vlsh, void *buffer, uint32_t buflen, int flags,
224 vcl_locked_session_t *vls;
227 if (!(vls = vls_get_w_dlock (vlsh)))
228 return VPPCOM_EBADFD;
229 rv = vppcom_session_recvfrom (vls_to_sh_tu (vls), buffer, buflen, flags,
231 vls_get_and_unlock (vlsh);
236 vls_attr (vls_handle_t vlsh, uint32_t op, void *buffer, uint32_t * buflen)
238 vcl_locked_session_t *vls;
241 if (!(vls = vls_get_w_dlock (vlsh)))
242 return VPPCOM_EBADFD;
243 rv = vppcom_session_attr (vls_to_sh_tu (vls), op, buffer, buflen);
244 vls_get_and_unlock (vlsh);
249 vls_bind (vls_handle_t vlsh, vppcom_endpt_t * ep)
251 vcl_locked_session_t *vls;
254 if (!(vls = vls_get_w_dlock (vlsh)))
255 return VPPCOM_EBADFD;
256 rv = vppcom_session_bind (vls_to_sh_tu (vls), ep);
257 vls_get_and_unlock (vlsh);
262 vls_listen (vls_handle_t vlsh, int q_len)
264 vcl_locked_session_t *vls;
267 if (!(vls = vls_get_w_dlock (vlsh)))
268 return VPPCOM_EBADFD;
269 rv = vppcom_session_listen (vls_to_sh_tu (vls), q_len);
270 vls_get_and_unlock (vlsh);
275 vls_connect (vls_handle_t vlsh, vppcom_endpt_t * server_ep)
277 vcl_locked_session_t *vls;
280 if (!(vls = vls_get_w_dlock (vlsh)))
281 return VPPCOM_EBADFD;
282 rv = vppcom_session_connect (vls_to_sh_tu (vls), server_ep);
283 vls_get_and_unlock (vlsh);
288 vls_accept (vls_handle_t listener_vlsh, vppcom_endpt_t * ep, int flags)
290 vls_handle_t accepted_vlsh;
291 vcl_locked_session_t *vls;
294 if (!(vls = vls_get_w_dlock (listener_vlsh)))
295 return VPPCOM_EBADFD;
296 sh = vppcom_session_accept (vls_to_sh_tu (vls), ep, flags);
297 vls_get_and_unlock (listener_vlsh);
300 accepted_vlsh = vls_alloc (sh);
301 if (PREDICT_FALSE (accepted_vlsh == VLS_INVALID_HANDLE))
302 vppcom_session_close (sh);
303 return accepted_vlsh;
307 vls_create (uint8_t proto, uint8_t is_nonblocking)
309 vcl_session_handle_t sh;
312 sh = vppcom_session_create (proto, is_nonblocking);
313 if (sh == INVALID_SESSION_ID)
314 return VLS_INVALID_HANDLE;
316 vlsh = vls_alloc (sh);
317 if (PREDICT_FALSE (vlsh == VLS_INVALID_HANDLE))
318 vppcom_session_close (sh);
324 vls_close (vls_handle_t vlsh)
326 vcl_locked_session_t *vls;
327 vcl_session_handle_t sh;
330 if (!(vls = vls_get_w_dlock (vlsh)))
331 return VPPCOM_EBADFD;
333 sh = vls_to_sh (vls);
334 refcnt = vppcom_session_attr (sh, VPPCOM_ATTR_GET_REFCNT, 0, 0);
335 if ((rv = vppcom_session_close (sh)))
343 vls_get_and_free (vlsh);
348 vls_epoll_create (void)
350 vcl_session_handle_t sh;
353 sh = vppcom_epoll_create ();
354 if (sh == INVALID_SESSION_ID)
355 return VLS_INVALID_HANDLE;
357 vlsh = vls_alloc (sh);
358 if (vlsh == VLS_INVALID_HANDLE)
359 vppcom_session_close (sh);
365 vls_epoll_ctl (vls_handle_t ep_vlsh, int op, vls_handle_t vlsh,
366 struct epoll_event *event)
368 vcl_locked_session_t *ep_vls, *vls;
369 vcl_session_handle_t ep_sh, sh;
373 ep_vls = vls_get_and_lock (ep_vlsh);
374 vls = vls_get_and_lock (vlsh);
375 ep_sh = vls_to_sh (ep_vls);
376 sh = vls_to_sh (vls);
377 vls_table_runlock ();
379 rv = vppcom_epoll_ctl (ep_sh, op, sh, event);
382 ep_vls = vls_get (ep_vlsh);
383 vls = vls_get (vlsh);
386 vls_table_runlock ();
391 vls_epoll_wait (vls_handle_t ep_vlsh, struct epoll_event *events,
392 int maxevents, double wait_for_time)
394 vcl_locked_session_t *vls;
397 if (!(vls = vls_get_w_dlock (ep_vlsh)))
398 return VPPCOM_EBADFD;
399 rv = vppcom_epoll_wait (vls_to_sh_tu (vls), events, maxevents,
401 vls_get_and_unlock (ep_vlsh);
406 vlsh_to_sh (vls_handle_t vlsh)
408 vcl_locked_session_t *vls;
411 vls = vls_get_w_dlock (vlsh);
413 return INVALID_SESSION_ID;
414 rv = vls_to_sh (vls);
420 vlsh_to_session_index (vls_handle_t vlsh)
422 vcl_session_handle_t sh;
423 sh = vlsh_to_sh (vlsh);
424 return vppcom_session_index (sh);
428 vls_session_index_to_vlsh (uint32_t session_index)
434 vlshp = hash_get (vlsm->session_index_to_vlsh_table, session_index);
435 vlsh = vlshp ? *vlshp : VLS_INVALID_HANDLE;
436 vls_table_runlock ();
442 vls_app_create (char *app_name)
445 if ((rv = vppcom_app_create (app_name)))
447 clib_rwlock_init (&vlsm->vls_table_lock);
452 * fd.io coding-style-patch-verification: ON
455 * eval: (c-set-style "gnu")