vlsh = ldp_fd_to_vlsh (fd);
if (vlsh != VLS_INVALID_HANDLE)
{
- epfd = vls_attr (vlsh, VPPCOM_ATTR_GET_LIBC_EPFD, 0, 0);
+ epfd = vls_get_libc_epfd (vlsh);
if (epfd > 0)
{
ldp_worker_ctx_t *ldpw = ldp_worker_get_current ();
- u32 size = sizeof (epfd);
LDBG (0, "fd %d: calling libc_close: epfd %u", fd, epfd);
libc_close (epfd);
ldpw->mq_epfd_added = 0;
- epfd = 0;
- (void) vls_attr (vlsh, VPPCOM_ATTR_SET_LIBC_EPFD, &epfd, &size);
+ vls_set_libc_epfd (vlsh, 0);
}
else if (PREDICT_FALSE (epfd < 0))
{
else
{
int libc_epfd;
- u32 size = sizeof (epfd);
- libc_epfd = vls_attr (vep_vlsh, VPPCOM_ATTR_GET_LIBC_EPFD, 0, 0);
+ libc_epfd = vls_get_libc_epfd (vep_vlsh);
if (!libc_epfd)
{
LDBG (1, "epfd %d, vep_vlsh %d calling libc_epoll_create1: "
goto done;
}
- rv = vls_attr (vep_vlsh, VPPCOM_ATTR_SET_LIBC_EPFD, &libc_epfd,
- &size);
+ rv = vls_set_libc_epfd (vep_vlsh, libc_epfd);
if (rv < 0)
{
errno = -rv;
time_to_wait = ((timeout >= 0) ? (double) timeout / 1000 : 0);
max_time = clib_time_now (&ldpw->clib_time) + time_to_wait;
- libc_epfd = vls_attr (ep_vlsh, VPPCOM_ATTR_GET_LIBC_EPFD, 0, 0);
+ libc_epfd = vls_get_libc_epfd (ep_vlsh);
if (PREDICT_FALSE (libc_epfd < 0))
{
errno = -libc_epfd;
return -1;
}
- libc_epfd = vls_attr (ep_vlsh, VPPCOM_ATTR_GET_LIBC_EPFD, 0, 0);
+ libc_epfd = vls_get_libc_epfd (ep_vlsh);
if (PREDICT_FALSE (!libc_epfd))
{
- u32 size = sizeof (epfd);
-
LDBG (1, "epfd %d, vep_vlsh %d calling libc_epoll_create1: "
"EPOLL_CLOEXEC", epfd, ep_vlsh);
libc_epfd = libc_epoll_create1 (EPOLL_CLOEXEC);
goto done;
}
- rv = vls_attr (ep_vlsh, VPPCOM_ATTR_SET_LIBC_EPFD, &libc_epfd, &size);
+ rv = vls_set_libc_epfd (ep_vlsh, libc_epfd);
if (rv < 0)
{
errno = -rv;
u32 shared_data_index; /**< shared data index if any */
u32 owner_vcl_wrk_index; /**< vcl wrk of the vls wrk at alloc */
uword *vcl_wrk_index_to_session_index; /**< map vcl wrk to session */
+ int libc_epfd; /**< epoll fd for libc epoll */
} vcl_locked_session_t;
typedef struct vls_worker_
return vcl_worker_get_current ()->vcl_needs_real_epoll;
}
+int
+vls_set_libc_epfd (vls_handle_t ep_vlsh, int libc_epfd)
+{
+ vcl_locked_session_t *vls;
+
+ vls_mt_detect ();
+ if (!(vls = vls_get_w_dlock (ep_vlsh)))
+ return VPPCOM_EBADFD;
+ if (vls_mt_session_should_migrate (vls))
+ {
+ vls = vls_mt_session_migrate (vls);
+ if (PREDICT_FALSE (!vls))
+ return VPPCOM_EBADFD;
+ }
+ vls->libc_epfd = libc_epfd;
+ vls_unlock (vls);
+ vls_mt_pool_runlock ();
+ return 0;
+}
+
+int
+vls_get_libc_epfd (vls_handle_t ep_vlsh)
+{
+ vcl_locked_session_t *vls;
+ int rv;
+
+ vls_mt_detect ();
+ vls_mt_pool_rlock ();
+
+ vls = vls_get (ep_vlsh);
+ if (!vls)
+ {
+ vls_mt_pool_runlock ();
+ return VPPCOM_EBADFD;
+ }
+
+ /* Avoid locking. In mt scenarios, one thread might be blocking waiting on
+ * the fd while another might be closing it. While closing, this attribute
+ * might be retrieved, so avoid deadlock */
+ rv = vls->libc_epfd;
+
+ vls_mt_pool_runlock ();
+
+ return rv;
+}
+
void
vls_register_vcl_worker (void)
{
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_register_vcl_worker (void);
#endif /* SRC_VCL_VCL_LOCKED_H_ */
session_handle_t parent_handle;
u32 listener_index; /**< index of parent listener (if any) */
int n_accepted_sessions; /**< sessions accepted by this listener */
- vppcom_epoll_t vep;
+ vppcom_epoll_t vep; /**< epoll context */
u32 attributes; /**< see @ref vppcom_session_attr_t */
- int libc_epfd;
u32 vrf;
u16 gso_size;
rv = VPPCOM_EINVAL;
break;
- case VPPCOM_ATTR_GET_LIBC_EPFD:
- rv = session->libc_epfd;
- VDBG (2, "VPPCOM_ATTR_GET_LIBC_EPFD: libc_epfd %d", rv);
- break;
-
- case VPPCOM_ATTR_SET_LIBC_EPFD:
- if (PREDICT_TRUE (buffer && buflen &&
- (*buflen == sizeof (session->libc_epfd))))
- {
- session->libc_epfd = *(int *) buffer;
- *buflen = sizeof (session->libc_epfd);
-
- VDBG (2, "VPPCOM_ATTR_SET_LIBC_EPFD: libc_epfd %d, buflen %d",
- session->libc_epfd, *buflen);
- }
- else
- rv = VPPCOM_EINVAL;
- break;
-
case VPPCOM_ATTR_GET_PROTOCOL:
if (buffer && buflen && (*buflen >= sizeof (int)))
{
VPPCOM_ATTR_GET_LCL_ADDR,
VPPCOM_ATTR_SET_LCL_ADDR,
VPPCOM_ATTR_GET_PEER_ADDR,
- VPPCOM_ATTR_GET_LIBC_EPFD,
- VPPCOM_ATTR_SET_LIBC_EPFD,
+ VPPCOM_ATTR_GET_UNUSED,
+ VPPCOM_ATTR_SET_UNUSED,
VPPCOM_ATTR_GET_PROTOCOL,
VPPCOM_ATTR_GET_LISTEN,
VPPCOM_ATTR_GET_ERROR,