u32 vlsh_bit_mask;
u32 debug;
- /** vcl needs next epoll_create to go to libc_epoll */
- u8 vcl_needs_real_epoll;
-
/**
* crypto state used only for testing
*/
ldp_init_cfg ();
ldp->init = 1;
- ldp->vcl_needs_real_epoll = 1;
+ vls_set_epoll_fns (
+ (vls_epoll_fns_t){ libc_epoll_create1, libc_epoll_ctl, libc_epoll_wait });
rv = vls_app_create (ldp_get_app_name ());
if (rv != VPPCOM_OK)
{
- ldp->vcl_needs_real_epoll = 0;
if (rv == VPPCOM_EEXIST)
return 0;
LDBG (2,
ldp->init = 0;
return rv;
}
- ldp->vcl_needs_real_epoll = 0;
LDBG (0, "LDP initialization: done!");
int
epoll_create1 (int flags)
{
- ldp_worker_ctx_t *ldpw = ldp_worker_get_current ();
vls_handle_t vlsh;
int rv;
ldp_init_check ();
- if (ldp->vcl_needs_real_epoll || vls_use_real_epoll ())
- {
- rv = libc_epoll_create1 (flags);
- ldp->vcl_needs_real_epoll = 0;
- /* Assume this is a request to create the mq epfd */
- ldpw->vcl_mq_epfd = rv;
- LDBG (0, "created vcl epfd %u", rv);
- return rv;
- }
-
vlsh = vls_epoll_create ();
if (PREDICT_FALSE (vlsh == VLS_INVALID_HANDLE))
{
if (PREDICT_FALSE (vppcom_worker_index () == ~0))
vls_register_vcl_worker ();
- ldpw = ldp_worker_get_current ();
- if (epfd == ldpw->vcl_mq_epfd)
- return libc_epoll_pwait (epfd, events, maxevents, timeout, sigmask);
-
ep_vlsh = ldp_fd_to_vlsh (epfd);
if (PREDICT_FALSE (ep_vlsh == VLS_INVALID_HANDLE))
{
return -1;
}
+ ldpw = ldp_worker_get_current ();
if (PREDICT_FALSE (ldpw->clib_time.init_cpu_time == 0))
clib_time_init (&ldpw->clib_time);
time_to_wait = ((timeout >= 0) ? (double) timeout / 1000 : 0);
vls_register_vcl_worker ();
ldpw = ldp_worker_get_current ();
- if (epfd == ldpw->vcl_mq_epfd)
- return libc_epoll_pwait (epfd, events, maxevents, timeout, sigmask);
-
ep_vlsh = ldp_fd_to_vlsh (epfd);
if (PREDICT_FALSE (ep_vlsh == VLS_INVALID_HANDLE))
{
ldpw->vcl_mq_epfd = vppcom_mq_epoll_fd ();
e.events = EPOLLIN;
e.data.fd = ldpw->vcl_mq_epfd;
- if (libc_epoll_ctl (libc_epfd, EPOLL_CTL_ADD, ldpw->vcl_mq_epfd, &e) <
- 0)
+ if (libc_epoll_ctl (libc_epfd, EPOLL_CTL_ADD, ldpw->vcl_mq_epfd, &e) < 0)
{
LDBG (0, "epfd %d, add libc mq epoll fd %d to libc epoll fd %d",
epfd, ldpw->vcl_mq_epfd, libc_epfd);
return vcm->cfg.mt_wrk_supported;
}
-int
-vls_use_real_epoll (void)
-{
- if (vcl_get_worker_index () == ~0)
- return 0;
-
- return vcl_worker_get_current ()->vcl_needs_real_epoll;
-}
-
int
vls_set_libc_epfd (vls_handle_t ep_vlsh, int libc_epfd)
{
return rv;
}
+void
+vls_set_epoll_fns (vls_epoll_fns_t ep_fns)
+{
+ vcm->vcl_epoll_create1 = ep_fns.epoll_create1_fn;
+ vcm->vcl_epoll_ctl = ep_fns.epoll_ctl_fn;
+ vcm->vcl_epoll_wait = ep_fns.epoll_wait_fn;
+}
+
void
vls_register_vcl_worker (void)
{
#define VLS_WORKER_RPC_TIMEOUT 3 /* timeout to wait rpc response. */
typedef int vls_handle_t;
+typedef struct vls_epoll_fns_
+{
+ int (*epoll_create1_fn) (int flags);
+ int (*epoll_ctl_fn) (int epfd, int op, int fd, struct epoll_event *event);
+ int (*epoll_wait_fn) (int epfd, struct epoll_event *events, int maxevents,
+ int timeout);
+} vls_epoll_fns_t;
vls_handle_t vls_create (uint8_t proto, uint8_t is_nonblocking);
int vls_shutdown (vls_handle_t vlsh, int how);
int vls_app_create (char *app_name);
unsigned char vls_use_eventfd (void);
unsigned char vls_mt_wrk_supported (void);
-int vls_use_real_epoll (void);
int vls_set_libc_epfd (vls_handle_t ep_vlsh, int libc_epfd);
int vls_get_libc_epfd (vls_handle_t ep_vlsh);
+void vls_set_epoll_fns (vls_epoll_fns_t ep_fns);
void vls_register_vcl_worker (void);
#endif /* SRC_VCL_VCL_LOCKED_H_ */
int rv;
e.data.u32 = VCL_EP_SAPIFD_EVT;
- rv = epoll_ctl (wrk->mqs_epfd, EPOLL_CTL_ADD, cs->fd, &e);
+ rv = vcm->vcl_epoll_ctl (wrk->mqs_epfd, EPOLL_CTL_ADD, cs->fd, &e);
if (rv != EEXIST && rv < 0)
return -1;
e.events = EPOLLIN;
e.data.u32 = mqc_index;
- if (epoll_ctl (wrk->mqs_epfd, EPOLL_CTL_ADD, mq_fd, &e) < 0)
+ if (vcm->vcl_epoll_ctl (wrk->mqs_epfd, EPOLL_CTL_ADD, mq_fd, &e) < 0)
{
VDBG (0, "failed to add mq eventfd to mq epoll fd");
return -1;
return -1;
mqc = vcl_mq_evt_conn_get (wrk, mqc_index);
- if (epoll_ctl (wrk->mqs_epfd, EPOLL_CTL_DEL, mqc->mq_fd, 0) < 0)
+ if (vcm->vcl_epoll_ctl (wrk->mqs_epfd, EPOLL_CTL_DEL, mqc->mq_fd, 0) < 0)
{
VDBG (0, "failed to del mq eventfd to mq epoll fd");
return -1;
struct epoll_event evt = {};
evt.events = EPOLLIN;
evt.data.u32 = VCL_EP_PIPEFD_EVT;
- if (epoll_ctl (wrk->mqs_epfd, EPOLL_CTL_ADD, wrk->detached_pipefds[0],
- &evt) < 0)
+ if (vcm->vcl_epoll_ctl (wrk->mqs_epfd, EPOLL_CTL_ADD,
+ wrk->detached_pipefds[0], &evt) < 0)
{
VDBG (0, "failed to add mq eventfd to mq epoll fd");
exit (1);
void
vcl_worker_detached_stop_signal_mq (vcl_worker_t *wrk)
{
- if (epoll_ctl (wrk->mqs_epfd, EPOLL_CTL_DEL, wrk->detached_pipefds[0], 0) <
- 0)
+ if (vcm->vcl_epoll_ctl (wrk->mqs_epfd, EPOLL_CTL_DEL,
+ wrk->detached_pipefds[0], 0) < 0)
{
VDBG (0, "failed to del mq eventfd to mq epoll fd");
exit (1);
wrk->mqs_epfd = -1;
if (vcm->cfg.use_mq_eventfd)
{
- wrk->vcl_needs_real_epoll = 1;
- wrk->mqs_epfd = epoll_create (1);
- wrk->vcl_needs_real_epoll = 0;
+ wrk->mqs_epfd = vcm->vcl_epoll_create1 (0);
if (wrk->mqs_epfd < 0)
{
clib_unix_warning ("epoll_create() returned");
return wrk->ctrl_mq;
}
+void
+vcl_init_epoll_fns ()
+{
+ if (!vcm->vcl_epoll_create1)
+ vcm->vcl_epoll_create1 = epoll_create1;
+ if (!vcm->vcl_epoll_ctl)
+ vcm->vcl_epoll_ctl = epoll_ctl;
+ if (!vcm->vcl_epoll_wait)
+ vcm->vcl_epoll_wait = epoll_wait;
+}
+
int
vcl_session_read_ready (vcl_session_t * s)
{
int session_attr_op_rv;
transport_endpt_attr_t session_attr_rv;
- /** vcl needs next epoll_create to go to libc_epoll */
- u8 vcl_needs_real_epoll;
volatile int rpc_done;
/* functions to be called pre/post wait if vcl managed by vls */
vcl_rpc_fn_t *wrk_rpc_fn;
+ /*
+ * Pointers to libc epoll fns to avoid loops when ldp is on
+ */
+ int (*vcl_epoll_create1) (int flags);
+ int (*vcl_epoll_ctl) (int epfd, int op, int fd, struct epoll_event *event);
+ int (*vcl_epoll_wait) (int epfd, struct epoll_event *events, int maxevents,
+ int timeout);
+
/*
* Binary api context
*/
void vcl_worker_detached_start_signal_mq (vcl_worker_t *wrk);
void vcl_worker_detached_signal_mq (vcl_worker_t *wrk);
void vcl_worker_detached_stop_signal_mq (vcl_worker_t *wrk);
+
+void vcl_init_epoll_fns (void);
+
/*
* VCL Binary API
*/
cs->flags =
CLIB_SOCKET_F_IS_CLIENT | CLIB_SOCKET_F_SEQPACKET | CLIB_SOCKET_F_BLOCKING;
- wrk->vcl_needs_real_epoll = 1;
-
if ((err = clib_socket_init (cs)))
{
/* don't report the error to avoid flood of error messages during
done:
- wrk->vcl_needs_real_epoll = 0;
-
return rv;
}
vcm->main_cpu = pthread_self ();
vcm->main_pid = getpid ();
vcm->app_name = format (0, "%s", app_name);
+ vcl_init_epoll_fns ();
fifo_segment_main_init (&vcm->segment_main, (uword) ~0,
20 /* timeout in secs */);
pool_alloc (vcm->workers, vcl_cfg->max_workers);
do
{
- n_mq_evts = epoll_wait (wrk->mqs_epfd, wrk->mq_events,
- vec_len (wrk->mq_events), time_to_wait);
+ n_mq_evts = vcm->vcl_epoll_wait (wrk->mqs_epfd, wrk->mq_events,
+ vec_len (wrk->mq_events), time_to_wait);
if (n_mq_evts < 0)
{
if (errno == EINTR)
do
{
- n_mq_evts = epoll_wait (wrk->mqs_epfd, wrk->mq_events,
- vec_len (wrk->mq_events), timeout_ms);
+ n_mq_evts = vcm->vcl_epoll_wait (wrk->mqs_epfd, wrk->mq_events,
+ vec_len (wrk->mq_events), timeout_ms);
if (n_mq_evts < 0)
{
if (errno == EINTR)