X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=src%2Fvcl%2Fldp.c;h=dfbb383f04647adc45f167efaaf58882f1f9d6a6;hb=30e273b3055174f0b6fefd240a39fe93253669cd;hp=ce243df1c96c9b5f961cf692f5d29562b9769c23;hpb=aa8f63ca4bd73dbb007e8828ed1967f90517aa72;p=vpp.git diff --git a/src/vcl/ldp.c b/src/vcl/ldp.c index ce243df1c96..dfbb383f046 100644 --- a/src/vcl/ldp.c +++ b/src/vcl/ldp.c @@ -29,6 +29,9 @@ #include #include #include +#include +#include +#include #define HAVE_CONSTRUCTOR_ATTRIBUTE #ifdef HAVE_CONSTRUCTOR_ATTRIBUTE @@ -46,6 +49,13 @@ #define DESTRUCTOR_ATTRIBUTE #endif +typedef struct ldp_fd_entry_ +{ + u32 sid; + u32 fd; + u32 fd_index; +} ldp_fd_entry_t; + typedef struct { int init; @@ -65,11 +75,23 @@ typedef struct clib_bitmap_t *libc_wr_bitmap; clib_bitmap_t *libc_ex_bitmap; vcl_poll_t *vcl_poll; + struct pollfd *libc_poll; + u16 *libc_poll_idxs; u8 select_vcl; u8 epoll_wait_vcl; + u8 vcl_needs_real_epoll; /*< vcl needs next epoll_create to + go to libc_epoll */ + int vcl_mq_epfd; + ldp_fd_entry_t *fd_pool; + clib_rwlock_t fd_table_lock; + uword *sid_to_fd_table; } ldp_main_t; #define LDP_DEBUG ldp->debug +#define LDBG(_lvl, _fmt, _args...) \ + if (ldp->debug > _lvl) \ + clib_warning (_fmt, ##_args) + static ldp_main_t ldp_main = { .sid_bit_val = (1 << LDP_SID_BIT_MIN), .sid_bit_mask = (1 << LDP_SID_BIT_MIN) - 1, @@ -100,132 +122,190 @@ ldp_get_app_name () return ldp->app_name; } +static int +ldp_fd_alloc (u32 sid) +{ + ldp_fd_entry_t *fde; + + clib_rwlock_writer_lock (&ldp->fd_table_lock); + if (pool_elts (ldp->fd_pool) >= (1ULL << 32) - ldp->sid_bit_val) + { + clib_rwlock_writer_unlock (&ldp->fd_table_lock); + return -1; + } + pool_get (ldp->fd_pool, fde); + fde->sid = sid; + fde->fd_index = fde - ldp->fd_pool; + fde->fd = fde->fd_index + ldp->sid_bit_val; + hash_set (ldp->sid_to_fd_table, sid, fde->fd); + clib_rwlock_writer_unlock (&ldp->fd_table_lock); + return fde->fd; +} + +static ldp_fd_entry_t * +ldp_fd_entry_get_w_lock (u32 fd_index) +{ + clib_rwlock_reader_lock (&ldp->fd_table_lock); + if (pool_is_free_index (ldp->fd_pool, fd_index)) + return 0; + + return pool_elt_at_index (ldp->fd_pool, fd_index); +} + static inline int ldp_fd_from_sid (u32 sid) { - if (PREDICT_FALSE (sid >= ldp->sid_bit_val)) - return -EMFILE; - else - return (sid | ldp->sid_bit_val); + uword *fdp; + int fd; + + clib_rwlock_reader_lock (&ldp->fd_table_lock); + fdp = hash_get (ldp->sid_to_fd_table, sid); + fd = fdp ? *fdp : -EMFILE; + clib_rwlock_reader_unlock (&ldp->fd_table_lock); + + return fd; } static inline int ldp_fd_is_sid (int fd) { - return ((u32) fd & ldp->sid_bit_val) ? 1 : 0; + return fd >= ldp->sid_bit_val; } static inline u32 ldp_sid_from_fd (int fd) { - return (ldp_fd_is_sid (fd) ? ((u32) fd & ldp->sid_bit_mask) : - INVALID_SESSION_ID); + ldp_fd_entry_t *fde; + u32 fd_index, sid; + + if (!ldp_fd_is_sid (fd)) + return INVALID_SESSION_ID; + + fd_index = fd - ldp->sid_bit_val; + fde = ldp_fd_entry_get_w_lock (fd_index); + sid = fde ? fde->sid : INVALID_SESSION_ID; + clib_rwlock_reader_unlock (&ldp->fd_table_lock); + + /* Handle forks */ + sid = vppcom_session_handle (vppcom_session_index (sid)); + return sid; +} + +static void +ldp_fd_free_w_sid (u32 sid) +{ + ldp_fd_entry_t *fde; + u32 fd_index; + int fd; + + fd = ldp_fd_from_sid (sid); + if (!fd) + return; + + fd_index = fd - ldp->sid_bit_val; + fde = ldp_fd_entry_get_w_lock (fd_index); + if (fde) + { + hash_unset (ldp->sid_to_fd_table, fde->sid); + pool_put (ldp->fd_pool, fde); + } + clib_rwlock_writer_unlock (&ldp->fd_table_lock); } static inline int ldp_init (void) { - int rv = 0; + int rv; + + if (PREDICT_TRUE (ldp->init)) + return 0; + + ldp->init = 1; + ldp->vcl_needs_real_epoll = 1; + rv = vppcom_app_create (ldp_get_app_name ()); + if (rv != VPPCOM_OK) + { + fprintf (stderr, "\nLDP<%d>: ERROR: ldp_init: vppcom_app_create()" + " failed! rv = %d (%s)\n", + getpid (), rv, vppcom_retval_str (rv)); + ldp->init = 0; + return rv; + } + ldp->vcl_needs_real_epoll = 0; - if (PREDICT_FALSE (!ldp->init)) + char *env_var_str = getenv (LDP_ENV_DEBUG); + if (env_var_str) { - ldp->init = 1; - rv = vppcom_app_create (ldp_get_app_name ()); - if (rv == VPPCOM_OK) + u32 tmp; + if (sscanf (env_var_str, "%u", &tmp) != 1) + clib_warning ("LDP<%d>: WARNING: Invalid LDP debug level specified in" + " the env var " LDP_ENV_DEBUG " (%s)!", getpid (), + env_var_str); + else { - char *env_var_str = getenv (LDP_ENV_DEBUG); - if (env_var_str) - { - u32 tmp; - if (sscanf (env_var_str, "%u", &tmp) != 1) - clib_warning ("LDP<%d>: WARNING: Invalid LDP debug level " - "specified in the env var " LDP_ENV_DEBUG - " (%s)!", getpid (), env_var_str); - else - { - ldp->debug = tmp; - if (LDP_DEBUG > 0) - clib_warning ("LDP<%d>: configured LDP debug level (%u) " - "from the env var " LDP_ENV_DEBUG "!", - getpid (), ldp->debug); - } - } + ldp->debug = tmp; + LDBG (0, "LDP<%d>: configured LDP debug level (%u) from env var " + LDP_ENV_DEBUG "!", getpid (), ldp->debug); + } + } - env_var_str = getenv (LDP_ENV_APP_NAME); - if (env_var_str) - { - ldp_set_app_name (env_var_str); - if (LDP_DEBUG > 0) - clib_warning ("LDP<%d>: configured LDP app name (%s) " - "from the env var " LDP_ENV_APP_NAME "!", - getpid (), ldp->app_name); - } + env_var_str = getenv (LDP_ENV_APP_NAME); + if (env_var_str) + { + ldp_set_app_name (env_var_str); + LDBG (0, "LDP<%d>: configured LDP app name (%s) from the env var " + LDP_ENV_APP_NAME "!", getpid (), ldp->app_name); + } - env_var_str = getenv (LDP_ENV_SID_BIT); - if (env_var_str) - { - u32 sb; - if (sscanf (env_var_str, "%u", &sb) != 1) - { - clib_warning ("LDP<%d>: WARNING: Invalid LDP sid bit " - "specified in the env var " - LDP_ENV_SID_BIT " (%s)!" - "sid bit value %d (0x%x)", - getpid (), env_var_str, - ldp->sid_bit_val, ldp->sid_bit_val); - } - else if (sb < LDP_SID_BIT_MIN) - { - ldp->sid_bit_val = (1 << LDP_SID_BIT_MIN); - ldp->sid_bit_mask = ldp->sid_bit_val - 1; - - clib_warning ("LDP<%d>: WARNING: LDP sid bit (%u) " - "specified in the env var " - LDP_ENV_SID_BIT " (%s) is too small. " - "Using LDP_SID_BIT_MIN (%d)! " - "sid bit value %d (0x%x)", - getpid (), sb, env_var_str, LDP_SID_BIT_MIN, - ldp->sid_bit_val, ldp->sid_bit_val); - } - else if (sb > LDP_SID_BIT_MAX) - { - ldp->sid_bit_val = (1 << LDP_SID_BIT_MAX); - ldp->sid_bit_mask = ldp->sid_bit_val - 1; - - clib_warning ("LDP<%d>: WARNING: LDP sid bit (%u) " - "specified in the env var " - LDP_ENV_SID_BIT " (%s) is too big. " - "Using LDP_SID_BIT_MAX (%d)! " - "sid bit value %d (0x%x)", - getpid (), sb, env_var_str, LDP_SID_BIT_MAX, - ldp->sid_bit_val, ldp->sid_bit_val); - } - else - { - ldp->sid_bit_val = (1 << sb); - ldp->sid_bit_mask = ldp->sid_bit_val - 1; - - if (LDP_DEBUG > 0) - clib_warning ("LDP<%d>: configured LDP sid bit (%u) " - "from " LDP_ENV_SID_BIT - "! sid bit value %d (0x%x)", getpid (), - sb, ldp->sid_bit_val, ldp->sid_bit_val); - } - } + env_var_str = getenv (LDP_ENV_SID_BIT); + if (env_var_str) + { + u32 sb; + if (sscanf (env_var_str, "%u", &sb) != 1) + { + clib_warning ("LDP<%d>: WARNING: Invalid LDP sid bit specified in" + " the env var " LDP_ENV_SID_BIT " (%s)! sid bit " + "value %d (0x%x)", getpid (), env_var_str, + ldp->sid_bit_val, ldp->sid_bit_val); + } + else if (sb < LDP_SID_BIT_MIN) + { + ldp->sid_bit_val = (1 << LDP_SID_BIT_MIN); + ldp->sid_bit_mask = ldp->sid_bit_val - 1; + + clib_warning ("LDP<%d>: WARNING: LDP sid bit (%u) specified in the" + " env var " LDP_ENV_SID_BIT " (%s) is too small. " + "Using LDP_SID_BIT_MIN (%d)! sid bit value %d (0x%x)", + getpid (), sb, env_var_str, LDP_SID_BIT_MIN, + ldp->sid_bit_val, ldp->sid_bit_val); + } + else if (sb > LDP_SID_BIT_MAX) + { + ldp->sid_bit_val = (1 << LDP_SID_BIT_MAX); + ldp->sid_bit_mask = ldp->sid_bit_val - 1; - clib_time_init (&ldp->clib_time); - if (LDP_DEBUG > 0) - clib_warning ("LDP<%d>: LDP initialization: done!", getpid ()); + clib_warning ("LDP<%d>: WARNING: LDP sid bit (%u) specified in the" + " env var " LDP_ENV_SID_BIT " (%s) is too big. Using" + " LDP_SID_BIT_MAX (%d)! sid bit value %d (0x%x)", + getpid (), sb, env_var_str, LDP_SID_BIT_MAX, + ldp->sid_bit_val, ldp->sid_bit_val); } else { - fprintf (stderr, "\nLDP<%d>: ERROR: ldp_init: vppcom_app_create()" - " failed! rv = %d (%s)\n", - getpid (), rv, vppcom_retval_str (rv)); - ldp->init = 0; + ldp->sid_bit_val = (1 << sb); + ldp->sid_bit_mask = ldp->sid_bit_val - 1; + + LDBG (0, "LDP<%d>: configured LDP sid bit (%u) from " + LDP_ENV_SID_BIT "! sid bit value %d (0x%x)", getpid (), sb, + ldp->sid_bit_val, ldp->sid_bit_val); } } - return rv; + + clib_time_init (&ldp->clib_time); + clib_rwlock_init (&ldp->fd_table_lock); + LDBG (0, "LDP<%d>: LDP initialization: done!", getpid ()); + + return 0; } int @@ -248,10 +328,8 @@ close (int fd) { func_str = "libc_close"; - if (LDP_DEBUG > 0) - clib_warning - ("LDP<%d>: fd %d (0x%x): calling %s(): epfd %u (0x%x)", - getpid (), fd, fd, func_str, epfd, epfd); + LDBG (0, "LDP<%d>: fd %d (0x%x): calling %s(): epfd %u (0x%x)", + getpid (), fd, fd, func_str, epfd, epfd); rv = libc_close (epfd); if (rv < 0) @@ -272,10 +350,10 @@ close (int fd) func_str = "vppcom_session_close"; - if (LDP_DEBUG > 0) - clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): sid %u (0x%x)", - getpid (), fd, fd, func_str, sid, sid); + LDBG (0, "LDP<%d>: fd %d (0x%x): calling %s(): sid %u (0x%x)", + getpid (), fd, fd, func_str, sid, sid); + ldp_fd_free_w_sid (sid); rv = vppcom_session_close (sid); if (rv != VPPCOM_OK) { @@ -287,9 +365,8 @@ close (int fd) { func_str = "libc_close"; - if (LDP_DEBUG > 0) - clib_warning ("LDP<%d>: fd %d (0x%x): calling %s()", - getpid (), fd, fd, func_str); + LDBG (0, "LDP<%d>: fd %d (0x%x): calling %s()", getpid (), fd, fd, + func_str); rv = libc_close (fd); } @@ -617,36 +694,35 @@ fcntl (int fd, int cmd, ...) { case F_SETFL: func_str = "vppcom_session_attr[SET_FLAGS]"; - if (LDP_DEBUG > 2) - clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): " - "sid %u (0x%x) flags %d (0x%x), size %d", - getpid (), fd, fd, func_str, sid, sid, - flags, flags, size); + LDBG (2, "LDP<%d>: fd %d (0x%x): calling %s(): sid %u (0x%x) " + "flags %d (0x%x), size %d", getpid (), fd, fd, func_str, sid, + sid, flags, flags, size); - rv = - vppcom_session_attr (sid, VPPCOM_ATTR_SET_FLAGS, &flags, &size); + rv = vppcom_session_attr (sid, VPPCOM_ATTR_SET_FLAGS, &flags, + &size); break; case F_GETFL: func_str = "vppcom_session_attr[GET_FLAGS]"; - if (LDP_DEBUG > 2) - clib_warning - ("LDP<%d>: fd %d (0x%x): calling %s(): sid %u (0x%x), " - "flags %d (0x%x), size %d", getpid (), fd, fd, func_str, sid, - sid, flags, flags, size); + LDBG (2, "LDP<%d>: fd %d (0x%x): calling %s(): sid %u (0x%x), " + "flags %d (0x%x), size %d", getpid (), fd, fd, func_str, sid, + sid, flags, flags, size); - rv = - vppcom_session_attr (sid, VPPCOM_ATTR_GET_FLAGS, &flags, &size); + rv = vppcom_session_attr (sid, VPPCOM_ATTR_GET_FLAGS, &flags, + &size); if (rv == VPPCOM_OK) { - if (LDP_DEBUG > 2) - clib_warning ("LDP<%d>: fd %d (0x%x), cmd %d (F_GETFL): " - "%s() returned flags %d (0x%x)", - getpid (), fd, fd, cmd, func_str, flags, flags); + LDBG (2, "LDP<%d>: fd %d (0x%x), cmd %d (F_GETFL): %s() " + "returned flags %d (0x%x)", getpid (), fd, fd, cmd, + func_str, flags, flags); rv = flags; } break; - + case F_SETFD: + /* TODO handle this */ + LDBG (0, "F_SETFD ignored flags %u", flags); + rv = 0; + break; default: rv = -EOPNOTSUPP; break; @@ -782,13 +858,11 @@ ldp_pselect (int nfds, fd_set * __restrict readfds, const struct timespec *__restrict timeout, const __sigset_t * __restrict sigmask) { - int rv; + uword sid_bits, sid_bits_set, libc_bits, libc_bits_set; + u32 minbits = clib_max (nfds, BITS (uword)), sid; char *func_str = "##"; f64 time_out; - int fd; - uword sid_bits, sid_bits_set, libc_bits, libc_bits_set; - u32 minbits = clib_max (nfds, BITS (uword)); - u32 sid; + int rv, fd; if (nfds < 0) { @@ -805,9 +879,8 @@ ldp_pselect (int nfds, fd_set * __restrict readfds, /* select as fine grained sleep */ if (!nfds) { - if (LDP_DEBUG > 3) - clib_warning ("LDP<%d>: sleeping for %.02f seconds", - getpid (), time_out); + LDBG (3, "LDP<%d>: sleeping for %.02f seconds", getpid (), + time_out); time_out += clib_time_now (&ldp->clib_time); while (clib_time_now (&ldp->clib_time) < time_out) @@ -828,11 +901,9 @@ ldp_pselect (int nfds, fd_set * __restrict readfds, { func_str = "libc_pselect"; - if (LDP_DEBUG > 3) - clib_warning - ("LDP<%d>: calling %s(): nfds %d, readfds %p, writefds %p, " - "exceptfds %p, timeout %p, sigmask %p", getpid (), func_str, nfds, - readfds, writefds, exceptfds, timeout, sigmask); + LDBG (3, "LDP<%d>: calling %s(): nfds %d, readfds %p, writefds %p, " + "exceptfds %p, timeout %p, sigmask %p", getpid (), func_str, nfds, + readfds, writefds, exceptfds, timeout, sigmask); rv = libc_pselect (nfds, readfds, writefds, exceptfds, timeout, sigmask); @@ -850,27 +921,28 @@ ldp_pselect (int nfds, fd_set * __restrict readfds, } sid_bits = libc_bits = 0; + u32 n_bytes = nfds / 8 + ((nfds % 8) ? 1 : 0); if (readfds) { clib_bitmap_validate (ldp->sid_rd_bitmap, minbits); clib_bitmap_validate (ldp->libc_rd_bitmap, minbits); clib_bitmap_validate (ldp->rd_bitmap, minbits); - clib_memcpy (ldp->rd_bitmap, readfds, - vec_len (ldp->rd_bitmap) * sizeof (clib_bitmap_t)); - FD_ZERO (readfds); + clib_memcpy_fast (ldp->rd_bitmap, readfds, n_bytes); + memset (readfds, 0, n_bytes); /* *INDENT-OFF* */ - clib_bitmap_foreach (fd, ldp->rd_bitmap, - ({ - sid = ldp_sid_from_fd (fd); - if (LDP_DEBUG > 3) - clib_warning ("LDP<%d>: readfds: fd %d (0x%x), sid %u (0x%x)", - getpid (), fd, fd, sid, sid); - if (sid == INVALID_SESSION_ID) - clib_bitmap_set_no_check (ldp->libc_rd_bitmap, fd, 1); - else - clib_bitmap_set_no_check (ldp->sid_rd_bitmap, sid, 1); - })); + clib_bitmap_foreach (fd, ldp->rd_bitmap, ({ + if (fd > nfds) + break; + sid = ldp_sid_from_fd (fd); + LDBG (3, "LDP<%d>: readfds: fd %d (0x%x), sid %u (0x%x)", + getpid (), fd, fd, sid, sid); + if (sid == INVALID_SESSION_ID) + clib_bitmap_set_no_check (ldp->libc_rd_bitmap, fd, 1); + else + clib_bitmap_set_no_check (ldp->sid_rd_bitmap, + vppcom_session_index (sid), 1); + })); /* *INDENT-ON* */ sid_bits_set = clib_bitmap_last_set (ldp->sid_rd_bitmap) + 1; @@ -879,32 +951,31 @@ ldp_pselect (int nfds, fd_set * __restrict readfds, libc_bits_set = clib_bitmap_last_set (ldp->libc_rd_bitmap) + 1; libc_bits = (libc_bits_set > libc_bits) ? libc_bits_set : libc_bits; - if (LDP_DEBUG > 3) - clib_warning ("LDP<%d>: readfds: sid_bits_set %d, sid_bits %d, " - "libc_bits_set %d, libc_bits %d", getpid (), - sid_bits_set, sid_bits, libc_bits_set, libc_bits); + LDBG (3, "LDP<%d>: readfds: sid_bits_set %d, sid_bits %d, " + "libc_bits_set %d, libc_bits %d", getpid (), sid_bits_set, + sid_bits, libc_bits_set, libc_bits); } if (writefds) { clib_bitmap_validate (ldp->sid_wr_bitmap, minbits); clib_bitmap_validate (ldp->libc_wr_bitmap, minbits); clib_bitmap_validate (ldp->wr_bitmap, minbits); - clib_memcpy (ldp->wr_bitmap, writefds, - vec_len (ldp->wr_bitmap) * sizeof (clib_bitmap_t)); - FD_ZERO (writefds); + clib_memcpy_fast (ldp->wr_bitmap, writefds, n_bytes); + memset (writefds, 0, n_bytes); /* *INDENT-OFF* */ - clib_bitmap_foreach (fd, ldp->wr_bitmap, - ({ - sid = ldp_sid_from_fd (fd); - if (LDP_DEBUG > 3) - clib_warning ("LDP<%d>: writefds: fd %d (0x%x), sid %u (0x%x)", - getpid (), fd, fd, sid, sid); - if (sid == INVALID_SESSION_ID) - clib_bitmap_set_no_check (ldp->libc_wr_bitmap, fd, 1); - else - clib_bitmap_set_no_check (ldp->sid_wr_bitmap, sid, 1); - })); + clib_bitmap_foreach (fd, ldp->wr_bitmap, ({ + if (fd > nfds) + break; + sid = ldp_sid_from_fd (fd); + LDBG (3, "LDP<%d>: writefds: fd %d (0x%x), sid %u (0x%x)", + getpid (), fd, fd, sid, sid); + if (sid == INVALID_SESSION_ID) + clib_bitmap_set_no_check (ldp->libc_wr_bitmap, fd, 1); + else + clib_bitmap_set_no_check (ldp->sid_wr_bitmap, + vppcom_session_index (sid), 1); + })); /* *INDENT-ON* */ sid_bits_set = clib_bitmap_last_set (ldp->sid_wr_bitmap) + 1; @@ -913,32 +984,31 @@ ldp_pselect (int nfds, fd_set * __restrict readfds, libc_bits_set = clib_bitmap_last_set (ldp->libc_wr_bitmap) + 1; libc_bits = (libc_bits_set > libc_bits) ? libc_bits_set : libc_bits; - if (LDP_DEBUG > 3) - clib_warning ("LDP<%d>: writefds: sid_bits_set %d, sid_bits %d, " - "libc_bits_set %d, libc_bits %d", getpid (), - sid_bits_set, sid_bits, libc_bits_set, libc_bits); + LDBG (3, "LDP<%d>: writefds: sid_bits_set %d, sid_bits %d, " + "libc_bits_set %d, libc_bits %d", getpid (), + sid_bits_set, sid_bits, libc_bits_set, libc_bits); } if (exceptfds) { clib_bitmap_validate (ldp->sid_ex_bitmap, minbits); clib_bitmap_validate (ldp->libc_ex_bitmap, minbits); clib_bitmap_validate (ldp->ex_bitmap, minbits); - clib_memcpy (ldp->ex_bitmap, exceptfds, - vec_len (ldp->ex_bitmap) * sizeof (clib_bitmap_t)); - FD_ZERO (exceptfds); + clib_memcpy_fast (ldp->ex_bitmap, exceptfds, n_bytes); + memset (exceptfds, 0, n_bytes); /* *INDENT-OFF* */ - clib_bitmap_foreach (fd, ldp->ex_bitmap, - ({ - sid = ldp_sid_from_fd (fd); - if (LDP_DEBUG > 3) - clib_warning ("LDP<%d>: exceptfds: fd %d (0x%x), sid %u (0x%x)", - getpid (), fd, fd, sid, sid); - if (sid == INVALID_SESSION_ID) - clib_bitmap_set_no_check (ldp->libc_ex_bitmap, fd, 1); - else - clib_bitmap_set_no_check (ldp->sid_ex_bitmap, sid, 1); - })); + clib_bitmap_foreach (fd, ldp->ex_bitmap, ({ + if (fd > nfds) + break; + sid = ldp_sid_from_fd (fd); + LDBG (3, "LDP<%d>: exceptfds: fd %d (0x%x), sid %u (0x%x)", + getpid (), fd, fd, sid, sid); + if (sid == INVALID_SESSION_ID) + clib_bitmap_set_no_check (ldp->libc_ex_bitmap, fd, 1); + else + clib_bitmap_set_no_check (ldp->sid_ex_bitmap, + vppcom_session_index (sid), 1); + })); /* *INDENT-ON* */ sid_bits_set = clib_bitmap_last_set (ldp->sid_ex_bitmap) + 1; @@ -947,10 +1017,9 @@ ldp_pselect (int nfds, fd_set * __restrict readfds, libc_bits_set = clib_bitmap_last_set (ldp->libc_ex_bitmap) + 1; libc_bits = (libc_bits_set > libc_bits) ? libc_bits_set : libc_bits; - if (LDP_DEBUG > 3) - clib_warning ("LDP<%d>: exceptfds: sid_bits_set %d, sid_bits %d, " - "libc_bits_set %d, libc_bits %d", getpid (), - sid_bits_set, sid_bits, libc_bits_set, libc_bits); + LDBG (3, "LDP<%d>: exceptfds: sid_bits_set %d, sid_bits %d, " + "libc_bits_set %d, libc_bits %d", getpid (), + sid_bits_set, sid_bits, libc_bits_set, libc_bits); } if (PREDICT_FALSE (!sid_bits && !libc_bits)) @@ -969,17 +1038,17 @@ ldp_pselect (int nfds, fd_set * __restrict readfds, func_str = "vppcom_select"; if (readfds) - clib_memcpy (ldp->rd_bitmap, ldp->sid_rd_bitmap, - vec_len (ldp->rd_bitmap) * - sizeof (clib_bitmap_t)); + clib_memcpy_fast (ldp->rd_bitmap, ldp->sid_rd_bitmap, + vec_len (ldp->rd_bitmap) * + sizeof (clib_bitmap_t)); if (writefds) - clib_memcpy (ldp->wr_bitmap, ldp->sid_wr_bitmap, - vec_len (ldp->wr_bitmap) * - sizeof (clib_bitmap_t)); + clib_memcpy_fast (ldp->wr_bitmap, ldp->sid_wr_bitmap, + vec_len (ldp->wr_bitmap) * + sizeof (clib_bitmap_t)); if (exceptfds) - clib_memcpy (ldp->ex_bitmap, ldp->sid_ex_bitmap, - vec_len (ldp->ex_bitmap) * - sizeof (clib_bitmap_t)); + clib_memcpy_fast (ldp->ex_bitmap, ldp->sid_ex_bitmap, + vec_len (ldp->ex_bitmap) * + sizeof (clib_bitmap_t)); rv = vppcom_select (sid_bits, readfds ? ldp->rd_bitmap : NULL, @@ -997,7 +1066,7 @@ ldp_pselect (int nfds, fd_set * __restrict readfds, /* *INDENT-OFF* */ clib_bitmap_foreach (sid, ldp->rd_bitmap, ({ - fd = ldp_fd_from_sid (sid); + fd = ldp_fd_from_sid (vppcom_session_handle (sid)); if (PREDICT_FALSE (fd < 0)) { errno = EBADFD; @@ -1013,7 +1082,7 @@ ldp_pselect (int nfds, fd_set * __restrict readfds, /* *INDENT-OFF* */ clib_bitmap_foreach (sid, ldp->wr_bitmap, ({ - fd = ldp_fd_from_sid (sid); + fd = ldp_fd_from_sid (vppcom_session_handle (sid)); if (PREDICT_FALSE (fd < 0)) { errno = EBADFD; @@ -1029,7 +1098,7 @@ ldp_pselect (int nfds, fd_set * __restrict readfds, /* *INDENT-OFF* */ clib_bitmap_foreach (sid, ldp->ex_bitmap, ({ - fd = ldp_fd_from_sid (sid); + fd = ldp_fd_from_sid (vppcom_session_handle (sid)); if (PREDICT_FALSE (fd < 0)) { errno = EBADFD; @@ -1054,14 +1123,17 @@ ldp_pselect (int nfds, fd_set * __restrict readfds, func_str = "libc_pselect"; if (readfds) - clib_memcpy (readfds, ldp->libc_rd_bitmap, - vec_len (ldp->rd_bitmap) * sizeof (clib_bitmap_t)); + clib_memcpy_fast (readfds, ldp->libc_rd_bitmap, + vec_len (ldp->rd_bitmap) * + sizeof (clib_bitmap_t)); if (writefds) - clib_memcpy (writefds, ldp->libc_wr_bitmap, - vec_len (ldp->wr_bitmap) * sizeof (clib_bitmap_t)); + clib_memcpy_fast (writefds, ldp->libc_wr_bitmap, + vec_len (ldp->wr_bitmap) * + sizeof (clib_bitmap_t)); if (exceptfds) - clib_memcpy (exceptfds, ldp->libc_ex_bitmap, - vec_len (ldp->ex_bitmap) * sizeof (clib_bitmap_t)); + clib_memcpy_fast (exceptfds, ldp->libc_ex_bitmap, + vec_len (ldp->ex_bitmap) * + sizeof (clib_bitmap_t)); tspec.tv_sec = tspec.tv_nsec = 0; rv = libc_pselect (libc_bits, readfds ? readfds : NULL, @@ -1076,15 +1148,15 @@ ldp_pselect (int nfds, fd_set * __restrict readfds, done: /* TBD: set timeout to amount of time left */ - vec_reset_length (ldp->rd_bitmap); - vec_reset_length (ldp->sid_rd_bitmap); - vec_reset_length (ldp->libc_rd_bitmap); - vec_reset_length (ldp->wr_bitmap); - vec_reset_length (ldp->sid_wr_bitmap); - vec_reset_length (ldp->libc_wr_bitmap); - vec_reset_length (ldp->ex_bitmap); - vec_reset_length (ldp->sid_ex_bitmap); - vec_reset_length (ldp->libc_ex_bitmap); + clib_bitmap_zero (ldp->rd_bitmap); + clib_bitmap_zero (ldp->sid_rd_bitmap); + clib_bitmap_zero (ldp->libc_rd_bitmap); + clib_bitmap_zero (ldp->wr_bitmap); + clib_bitmap_zero (ldp->sid_wr_bitmap); + clib_bitmap_zero (ldp->libc_wr_bitmap); + clib_bitmap_zero (ldp->ex_bitmap); + clib_bitmap_zero (ldp->sid_ex_bitmap); + clib_bitmap_zero (ldp->libc_ex_bitmap); if (LDP_DEBUG > 3) { @@ -1151,11 +1223,9 @@ socket (int domain, int type, int protocol) func_str = "vppcom_session_create"; - if (LDP_DEBUG > 0) - clib_warning ("LDP<%d>: : calling %s(): " - "proto %u (%s), is_nonblocking %u", - getpid (), func_str, proto, - vppcom_proto_str (proto), is_nonblocking); + LDBG (0, "LDP<%d>: : calling %s(): proto %u (%s), is_nonblocking %u", + getpid (), func_str, proto, vppcom_proto_str (proto), + is_nonblocking); sid = vppcom_session_create (proto, is_nonblocking); if (sid < 0) @@ -1166,7 +1236,7 @@ socket (int domain, int type, int protocol) else { func_str = "ldp_fd_from_sid"; - rv = ldp_fd_from_sid (sid); + rv = ldp_fd_alloc (sid); if (rv < 0) { (void) vppcom_session_close (sid); @@ -1179,8 +1249,7 @@ socket (int domain, int type, int protocol) { func_str = "libc_socket"; - if (LDP_DEBUG > 0) - clib_warning ("LDP<%d>: : calling %s()", getpid (), func_str); + LDBG (0, "LDP<%d>: : calling %s()", getpid (), func_str); rv = libc_socket (domain, type, protocol); } @@ -1232,10 +1301,9 @@ socketpair (int domain, int type, int protocol, int fds[2]) { func_str = "libc_socket"; - if (LDP_DEBUG > 1) - clib_warning ("LDP<%d>: : calling %s()", getpid (), func_str); + LDBG (1, "LDP<%d>: : calling %s()", getpid (), func_str); - rv = libc_socket (domain, type, protocol); + rv = libc_socketpair (domain, type, protocol, fds); } if (LDP_DEBUG > 1) @@ -2765,10 +2833,8 @@ listen (int fd, int n) { func_str = "vppcom_session_listen"; - if (LDP_DEBUG > 0) - clib_warning - ("LDP<%d>: fd %d (0x%x): calling %s(): sid %u (0x%x), n %d", - getpid (), fd, fd, func_str, sid, sid, n); + LDBG (0, "LDP<%d>: fd %d (0x%x): calling %s(): sid %u (0x%x), n %d", + getpid (), fd, fd, func_str, sid, sid, n); rv = vppcom_session_listen (sid, n); if (rv != VPPCOM_OK) @@ -2781,9 +2847,8 @@ listen (int fd, int n) { func_str = "libc_listen"; - if (LDP_DEBUG > 0) - clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): n %d", - getpid (), fd, fd, func_str, n); + LDBG (0, "LDP<%d>: fd %d (0x%x): calling %s(): n %d", getpid (), fd, + fd, func_str, n); rv = libc_listen (fd, n); } @@ -2856,7 +2921,7 @@ ldp_accept4 (int listen_fd, __SOCKADDR_ARG addr, "accept sid %u (0x%x), ep %p, flags 0x%x", getpid (), listen_fd, listen_fd, func_str, accept_sid, accept_sid, ep, flags); - rv = ldp_fd_from_sid ((u32) accept_sid); + rv = ldp_fd_alloc ((u32) accept_sid); if (rv < 0) { (void) vppcom_session_close ((u32) accept_sid); @@ -2922,11 +2987,8 @@ shutdown (int fd, int how) if (sid != INVALID_SESSION_ID) { - func_str = __func__; - - clib_warning ("LDP<%d>: LDP-TBD", getpid ()); - errno = ENOSYS; - rv = -1; + func_str = "vppcom_session_close[TODO]"; + rv = close (fd); } else { @@ -2966,10 +3028,17 @@ epoll_create1 (int flags) if ((errno = -ldp_init ())) return -1; + if (ldp->vcl_needs_real_epoll) + { + rv = libc_epoll_create1 (flags); + ldp->vcl_needs_real_epoll = 0; + ldp->vcl_mq_epfd = rv; + LDBG (0, "LDP<%d>: created vcl epfd %u", getpid (), rv); + return rv; + } func_str = "vppcom_epoll_create"; - if (LDP_DEBUG > 1) - clib_warning ("LDP<%d>: calling %s()", getpid (), func_str); + LDBG (1, "LDP<%d>: calling %s()", getpid (), func_str); rv = vppcom_epoll_create (); @@ -2979,7 +3048,7 @@ epoll_create1 (int flags) rv = -1; } else - rv = ldp_fd_from_sid ((u32) rv); + rv = ldp_fd_alloc ((u32) rv); if (LDP_DEBUG > 1) { @@ -3007,121 +3076,105 @@ epoll_create (int size) int epoll_ctl (int epfd, int op, int fd, struct epoll_event *event) { - int rv; + u32 vep_idx = ldp_sid_from_fd (epfd), sid; const char *func_str; - u32 vep_idx = ldp_sid_from_fd (epfd); + int rv; if ((errno = -ldp_init ())) return -1; - if (PREDICT_TRUE (vep_idx != INVALID_SESSION_ID)) + if (PREDICT_FALSE (vep_idx == INVALID_SESSION_ID)) { - u32 sid = ldp_sid_from_fd (fd); + /* The LDP epoll_create1 always creates VCL epfd's. + * The app should never have a kernel base epoll fd unless it + * was acquired outside of the LD_PRELOAD process context. + * In any case, if we get one, punt it to libc_epoll_ctl. + */ + func_str = "libc_epoll_ctl"; - if (LDP_DEBUG > 1) - clib_warning ("LDP<%d>: epfd %d (0x%x), vep_idx %d (0x%x), " - "sid %d (0x%x)", getpid (), epfd, epfd, - vep_idx, vep_idx, sid, sid); + LDBG (1, "LDP<%d>: epfd %d (0x%x): calling %s(): op %d, fd %d (0x%x)," + " event %p", getpid (), epfd, epfd, func_str, op, fd, fd, event); - if (sid != INVALID_SESSION_ID) - { - func_str = "vppcom_epoll_ctl"; + rv = libc_epoll_ctl (epfd, op, fd, event); + goto done; + } - if (LDP_DEBUG > 1) - clib_warning ("LDP<%d>: epfd %d (0x%x): calling %s(): " - "vep_idx %d (0x%x), op %d, sid %u (0x%x), event %p", - getpid (), epfd, epfd, func_str, vep_idx, vep_idx, - sid, sid, event); + sid = ldp_sid_from_fd (fd); - rv = vppcom_epoll_ctl (vep_idx, op, sid, event); - if (rv != VPPCOM_OK) - { - errno = -rv; - rv = -1; - } + LDBG (0, "LDP<%d>: epfd %d (0x%x), vep_idx %d (0x%x), sid %d (0x%x)", + getpid (), epfd, epfd, vep_idx, vep_idx, sid, sid); + + if (sid != INVALID_SESSION_ID) + { + func_str = "vppcom_epoll_ctl"; + + LDBG (1, "LDP<%d>: epfd %d (0x%x): calling %s(): vep_idx %d (0x%x)," + " op %d, sid %u (0x%x), event %p", getpid (), epfd, epfd, + func_str, vep_idx, vep_idx, sid, sid, event); + + rv = vppcom_epoll_ctl (vep_idx, op, sid, event); + if (rv != VPPCOM_OK) + { + errno = -rv; + rv = -1; } - else + } + else + { + int libc_epfd; + u32 size = sizeof (epfd); + + func_str = "vppcom_session_attr[GET_LIBC_EPFD]"; + libc_epfd = vppcom_session_attr (vep_idx, VPPCOM_ATTR_GET_LIBC_EPFD, 0, + 0); + LDBG (1, "LDP<%d>: epfd %d (0x%x), vep_idx %d (0x%x): %s() " + "returned libc_epfd %d (0x%x)", getpid (), epfd, epfd, + vep_idx, vep_idx, func_str, libc_epfd, libc_epfd); + + if (!libc_epfd) { - int libc_epfd; - u32 size = sizeof (epfd); + func_str = "libc_epoll_create1"; - func_str = "vppcom_session_attr[GET_LIBC_EPFD]"; - libc_epfd = vppcom_session_attr (vep_idx, - VPPCOM_ATTR_GET_LIBC_EPFD, 0, 0); - if (LDP_DEBUG > 1) - clib_warning ("LDP<%d>: epfd %d (0x%x), vep_idx %d (0x%x): " - "%s() returned libc_epfd %d (0x%x)", - getpid (), epfd, epfd, vep_idx, vep_idx, - func_str, libc_epfd, libc_epfd); + LDBG (1, "LDP<%d>: epfd %d (0x%x), vep_idx %d (0x%x): " + "calling %s(): EPOLL_CLOEXEC", getpid (), epfd, epfd, + vep_idx, vep_idx, func_str); - if (!libc_epfd) + libc_epfd = libc_epoll_create1 (EPOLL_CLOEXEC); + if (libc_epfd < 0) { - func_str = "libc_epoll_create1"; - - if (LDP_DEBUG > 1) - clib_warning ("LDP<%d>: epfd %d (0x%x), vep_idx %d (0x%x): " - "calling %s(): EPOLL_CLOEXEC", - getpid (), epfd, epfd, vep_idx, vep_idx, - func_str); + rv = libc_epfd; + goto done; + } - libc_epfd = libc_epoll_create1 (EPOLL_CLOEXEC); - if (libc_epfd < 0) - { - rv = libc_epfd; - goto done; - } + func_str = "vppcom_session_attr[SET_LIBC_EPFD]"; + LDBG (1, "LDP<%d>: epfd %d (0x%x): calling %s(): vep_idx %d (0x%x)," + " VPPCOM_ATTR_SET_LIBC_EPFD, libc_epfd %d (0x%x), size %d", + getpid (), epfd, epfd, func_str, vep_idx, vep_idx, libc_epfd, + libc_epfd, size); - func_str = "vppcom_session_attr[SET_LIBC_EPFD]"; - if (LDP_DEBUG > 1) - clib_warning ("LDP<%d>: epfd %d (0x%x): calling %s(): " - "vep_idx %d (0x%x), VPPCOM_ATTR_SET_LIBC_EPFD, " - "libc_epfd %d (0x%x), size %d", - getpid (), epfd, epfd, func_str, - vep_idx, vep_idx, libc_epfd, libc_epfd, size); - - rv = vppcom_session_attr (vep_idx, VPPCOM_ATTR_SET_LIBC_EPFD, - &libc_epfd, &size); - if (rv < 0) - { - errno = -rv; - rv = -1; - goto done; - } - } - else if (PREDICT_FALSE (libc_epfd < 0)) + rv = vppcom_session_attr (vep_idx, VPPCOM_ATTR_SET_LIBC_EPFD, + &libc_epfd, &size); + if (rv < 0) { - errno = -epfd; + errno = -rv; rv = -1; goto done; } - - func_str = "libc_epoll_ctl"; - - if (LDP_DEBUG > 1) - clib_warning ("LDP<%d>: epfd %d (0x%x): calling %s(): " - "libc_epfd %d (0x%x), op %d, " - "fd %d (0x%x), event %p", - getpid (), epfd, epfd, func_str, - libc_epfd, libc_epfd, op, fd, fd, event); - - rv = libc_epoll_ctl (libc_epfd, op, fd, event); } - } - else - { - /* The LDP epoll_create1 always creates VCL epfd's. - * The app should never have a kernel base epoll fd unless it - * was acquired outside of the LD_PRELOAD process context. - * In any case, if we get one, punt it to libc_epoll_ctl. - */ + else if (PREDICT_FALSE (libc_epfd < 0)) + { + errno = -epfd; + rv = -1; + goto done; + } + func_str = "libc_epoll_ctl"; - if (LDP_DEBUG > 1) - clib_warning ("LDP<%d>: epfd %d (0x%x): calling %s(): " - "op %d, fd %d (0x%x), event %p", - getpid (), epfd, epfd, func_str, op, fd, fd, event); + LDBG (1, "LDP<%d>: epfd %d (0x%x): calling %s(): libc_epfd %d (0x%x), " + "op %d, fd %d (0x%x), event %p", getpid (), epfd, epfd, func_str, + libc_epfd, libc_epfd, op, fd, fd, event); - rv = libc_epoll_ctl (epfd, op, fd, event); + rv = libc_epoll_ctl (libc_epfd, op, fd, event); } done: @@ -3144,15 +3197,13 @@ done: } static inline int -ldp_epoll_pwait (int epfd, struct epoll_event *events, - int maxevents, int timeout, const sigset_t * sigmask) +ldp_epoll_pwait (int epfd, struct epoll_event *events, int maxevents, + int timeout, const sigset_t * sigmask) { - const char *func_str; - int rv = 0; - double time_to_wait = (double) 0; - double time_out, now = 0; + double time_to_wait = (double) 0, time_out, now = 0; u32 vep_idx = ldp_sid_from_fd (epfd); - int libc_epfd; + int libc_epfd, rv = 0; + const char *func_str; if ((errno = -ldp_init ())) return -1; @@ -3163,6 +3214,9 @@ ldp_epoll_pwait (int epfd, struct epoll_event *events, return -1; } + if (epfd == ldp->vcl_mq_epfd) + return libc_epoll_pwait (epfd, events, maxevents, timeout, sigmask); + if (PREDICT_FALSE (vep_idx == INVALID_SESSION_ID)) { clib_warning ("LDP<%d>: ERROR: epfd %d (0x%x): bad vep_idx %d (0x%x)!", @@ -3171,7 +3225,7 @@ ldp_epoll_pwait (int epfd, struct epoll_event *events, return -1; } - time_to_wait = ((timeout >= 0) ? (double) timeout / (double) 1000 : 0); + time_to_wait = ((timeout >= 0) ? (double) timeout : 0); time_out = clib_time_now (&ldp->clib_time) + time_to_wait; func_str = "vppcom_session_attr[GET_LIBC_EPFD]"; @@ -3183,24 +3237,19 @@ ldp_epoll_pwait (int epfd, struct epoll_event *events, goto done; } - if (LDP_DEBUG > 2) - clib_warning ("LDP<%d>: epfd %d (0x%x): vep_idx %d (0x%x), " - "libc_epfd %d (0x%x), events %p, maxevents %d, " - "timeout %d, sigmask %p: time_to_wait %.02f", - getpid (), epfd, epfd, vep_idx, vep_idx, - libc_epfd, libc_epfd, events, maxevents, timeout, - sigmask, time_to_wait, time_out); + LDBG (2, "LDP<%d>: epfd %d (0x%x): vep_idx %d (0x%x), libc_epfd %d (0x%x), " + "events %p, maxevents %d, timeout %d, sigmask %p: time_to_wait %.02f", + getpid (), epfd, epfd, vep_idx, vep_idx, libc_epfd, libc_epfd, events, + maxevents, timeout, sigmask, time_to_wait, time_out); do { if (!ldp->epoll_wait_vcl) { func_str = "vppcom_epoll_wait"; - if (LDP_DEBUG > 3) - clib_warning ("LDP<%d>: epfd %d (0x%x): calling %s(): " - "vep_idx %d (0x%x), events %p, maxevents %d", - getpid (), epfd, epfd, func_str, - vep_idx, vep_idx, events, maxevents); + LDBG (3, "LDP<%d>: epfd %d (0x%x): calling %s(): vep_idx %d (0x%x)," + " events %p, maxevents %d", getpid (), epfd, epfd, func_str, + vep_idx, vep_idx, events, maxevents); rv = vppcom_epoll_wait (vep_idx, events, maxevents, 0); if (rv > 0) @@ -3222,12 +3271,10 @@ ldp_epoll_pwait (int epfd, struct epoll_event *events, { func_str = "libc_epoll_pwait"; - if (LDP_DEBUG > 3) - clib_warning ("LDP<%d>: epfd %d (0x%x): calling %s(): " - "libc_epfd %d (0x%x), events %p, " - "maxevents %d, sigmask %p", - getpid (), epfd, epfd, func_str, - libc_epfd, libc_epfd, events, maxevents, sigmask); + LDBG (3, "LDP<%d>: epfd %d (0x%x): calling %s(): libc_epfd %d " + "(0x%x), events %p, maxevents %d, sigmask %p", getpid (), + epfd, epfd, func_str, libc_epfd, libc_epfd, events, + maxevents, sigmask); rv = libc_epoll_pwait (libc_epfd, events, maxevents, 1, sigmask); if (rv != 0) @@ -3277,65 +3324,61 @@ int poll (struct pollfd *fds, nfds_t nfds, int timeout) { const char *func_str = __func__; - int rv, i, n_libc_fds, n_revents; + int rv, i, n_revents = 0; u32 sid; vcl_poll_t *vp; double wait_for_time; - if (LDP_DEBUG > 3) - clib_warning ("LDP<%d>: fds %p, nfds %d, timeout %d", - getpid (), fds, nfds, timeout); + LDBG (3, "LDP<%d>: fds %p, nfds %d, timeout %d", getpid (), fds, nfds, + timeout); if (timeout >= 0) wait_for_time = (f64) timeout / 1000; else wait_for_time = -1; - n_libc_fds = 0; for (i = 0; i < nfds; i++) { - if (fds[i].fd >= 0) - { - if (LDP_DEBUG > 3) - clib_warning ("LDP<%d>: fds[%d].fd %d (0x%0x), .events = 0x%x, " - ".revents = 0x%x", getpid (), i, fds[i].fd, - fds[i].fd, fds[i].events, fds[i].revents); + if (fds[i].fd < 0) + continue; - sid = ldp_sid_from_fd (fds[i].fd); - if (sid != INVALID_SESSION_ID) - { - fds[i].fd = -fds[i].fd; - vec_add2 (ldp->vcl_poll, vp, 1); - vp->fds_ndx = i; - vp->sid = sid; - vp->events = fds[i].events; + LDBG (3, "LDP<%d>: fds[%d] fd %d (0x%0x) events = 0x%x revents = 0x%x", + getpid (), i, fds[i].fd, fds[i].fd, fds[i].events, + fds[i].revents); + + sid = ldp_sid_from_fd (fds[i].fd); + if (sid != INVALID_SESSION_ID) + { + fds[i].fd = -fds[i].fd; + vec_add2 (ldp->vcl_poll, vp, 1); + vp->fds_ndx = i; + vp->sid = sid; + vp->events = fds[i].events; #ifdef __USE_XOPEN2K - if (fds[i].events & POLLRDNORM) - vp->events |= POLLIN; - if (fds[i].events & POLLWRNORM) - vp->events |= POLLOUT; + if (fds[i].events & POLLRDNORM) + vp->events |= POLLIN; + if (fds[i].events & POLLWRNORM) + vp->events |= POLLOUT; #endif - vp->revents = &fds[i].revents; - } - else - n_libc_fds++; + vp->revents = fds[i].revents; + } + else + { + vec_add1 (ldp->libc_poll, fds[i]); + vec_add1 (ldp->libc_poll_idxs, i); } } - n_revents = 0; do { if (vec_len (ldp->vcl_poll)) { func_str = "vppcom_poll"; - if (LDP_DEBUG > 3) - clib_warning ("LDP<%d>: calling %s(): " - "vcl_poll %p, n_sids %u (0x%x): " - "n_libc_fds %u", - getpid (), func_str, ldp->vcl_poll, - vec_len (ldp->vcl_poll), vec_len (ldp->vcl_poll), - n_libc_fds); + LDBG (3, "LDP<%d>: calling %s(): vcl_poll %p, n_sids %u (0x%x): " + "n_libc_fds %u", getpid (), func_str, ldp->vcl_poll, + vec_len (ldp->vcl_poll), vec_len (ldp->vcl_poll), + vec_len (ldp->libc_poll)); rv = vppcom_poll (ldp->vcl_poll, vec_len (ldp->vcl_poll), 0); if (rv < 0) @@ -3348,15 +3391,14 @@ poll (struct pollfd *fds, nfds_t nfds, int timeout) n_revents += rv; } - if (n_libc_fds) + if (vec_len (ldp->libc_poll)) { func_str = "libc_poll"; - if (LDP_DEBUG > 3) - clib_warning ("LDP<%d>: calling %s(): fds %p, nfds %u: n_sids %u", - getpid (), fds, nfds, vec_len (ldp->vcl_poll)); + LDBG (3, "LDP<%d>: calling %s(): fds %p, nfds %u: n_sids %u", + getpid (), fds, nfds, vec_len (ldp->vcl_poll)); - rv = libc_poll (fds, nfds, 0); + rv = libc_poll (ldp->libc_poll, vec_len (ldp->libc_poll), 0); if (rv < 0) goto done; else @@ -3377,6 +3419,7 @@ done: vec_foreach (vp, ldp->vcl_poll) { fds[vp->fds_ndx].fd = -fds[vp->fds_ndx].fd; + fds[vp->fds_ndx].revents = vp->revents; #ifdef __USE_XOPEN2K if ((fds[vp->fds_ndx].revents & POLLIN) && (fds[vp->fds_ndx].events & POLLRDNORM)) @@ -3388,6 +3431,13 @@ done: } vec_reset_length (ldp->vcl_poll); + for (i = 0; i < vec_len (ldp->libc_poll); i++) + { + fds[ldp->libc_poll_idxs[i]].revents = ldp->libc_poll[i].revents; + } + vec_reset_length (ldp->libc_poll_idxs); + vec_reset_length (ldp->libc_poll); + if (LDP_DEBUG > 3) { if (rv < 0) @@ -3403,7 +3453,7 @@ done: { clib_warning ("LDP<%d>: returning %d (0x%x): n_sids %u, " "n_libc_fds %d", getpid (), rv, rv, - vec_len (ldp->vcl_poll), n_libc_fds); + vec_len (ldp->vcl_poll), vec_len (ldp->libc_poll)); for (i = 0; i < nfds; i++) {