diff --git a/src/include/switch_apr.h b/src/include/switch_apr.h index b1245ddf41..ac2367b9ec 100644 --- a/src/include/switch_apr.h +++ b/src/include/switch_apr.h @@ -1296,6 +1296,22 @@ SWITCH_DECLARE(switch_status_t) switch_pollset_create(switch_pollset_t ** pollse */ SWITCH_DECLARE(switch_status_t) switch_pollset_add(switch_pollset_t *pollset, const switch_pollfd_t *descriptor); +/** + * Remove a descriptor from a pollset + * @param pollset The pollset from which to remove the descriptor + * @param descriptor The descriptor to remove + * @remark If the pollset has been created with APR_POLLSET_THREADSAFE + * and thread T1 is blocked in a call to apr_pollset_poll() for + * this same pollset that is being modified via apr_pollset_remove() + * in thread T2, the currently executing apr_pollset_poll() call in + * T1 will either: (1) automatically exclude the newly added descriptor + * in the set of descriptors it is watching or (2) return immediately + * with APR_EINTR. Option (1) is recommended, but option (2) is + * allowed for implementations where option (1) is impossible + * or impractical. + */ +SWITCH_DECLARE(switch_status_t) switch_pollset_remove(switch_pollset_t *pollset, const switch_pollfd_t *descriptor); + /** * Poll the sockets in the poll structure * @param aprset The poll structure we will be using. @@ -1311,16 +1327,35 @@ SWITCH_DECLARE(switch_status_t) switch_pollset_add(switch_pollset_t *pollset, co */ SWITCH_DECLARE(switch_status_t) switch_poll(switch_pollfd_t *aprset, int32_t numsock, int32_t *nsds, switch_interval_time_t timeout); +/** + * Block for activity on the descriptor(s) in a pollset + * @param pollset The pollset to use + * @param timeout Timeout in microseconds + * @param num Number of signalled descriptors (output parameter) + * @param descriptors Array of signalled descriptors (output parameter) + */ +SWITCH_DECLARE(switch_status_t) switch_pollset_poll(switch_pollset_t *pollset, switch_interval_time_t timeout, int32_t *num, const switch_pollfd_t **descriptors); + /*! - \brief Create a set of file descriptors to poll + \brief Create a set of file descriptors to poll from a socket \param poll the polfd to create \param sock the socket to add \param flags the flags to modify the behaviour \param pool the memory pool to use \return SWITCH_STATUS_SUCCESS when successful */ -SWITCH_DECLARE(switch_status_t) switch_socket_create_pollfd(switch_pollfd_t ** poll, switch_socket_t *sock, int16_t flags, switch_memory_pool_t *pool); +SWITCH_DECLARE(switch_status_t) switch_socket_create_pollset(switch_pollfd_t ** poll, switch_socket_t *sock, int16_t flags, switch_memory_pool_t *pool); +/*! + \brief Create a pollfd out of a socket + \param poll the polfd to create + \param sock the socket to add + \param flags the flags to modify the behaviour + \param client_data custom user data + \param pool the memory pool to use + \return SWITCH_STATUS_SUCCESS when successful +*/ +SWITCH_DECLARE(switch_status_t) switch_socket_create_pollfd(switch_pollfd_t **pollfd, switch_socket_t *sock, int16_t flags, void *client_data, switch_memory_pool_t *pool); SWITCH_DECLARE(switch_status_t) switch_match_glob(const char *pattern, switch_array_header_t ** result, switch_memory_pool_t *p); SWITCH_DECLARE(switch_status_t) switch_socket_addr_get(switch_sockaddr_t ** sa, switch_bool_t remote, switch_socket_t *sock); diff --git a/src/switch_apr.c b/src/switch_apr.c index d69c4ebcad..a6687bf402 100644 --- a/src/switch_apr.c +++ b/src/switch_apr.c @@ -821,13 +821,58 @@ SWITCH_DECLARE(switch_status_t) switch_pollset_create(switch_pollset_t ** pollse SWITCH_DECLARE(switch_status_t) switch_pollset_add(switch_pollset_t *pollset, const switch_pollfd_t *descriptor) { - if (!pollset) { + if (!pollset || !descriptor) { return SWITCH_STATUS_FALSE; } return apr_pollset_add((apr_pollset_t *) pollset, (const apr_pollfd_t *) descriptor); } +SWITCH_DECLARE(switch_status_t) switch_pollset_remove(switch_pollset_t *pollset, const switch_pollfd_t *descriptor) +{ + if (!pollset || !descriptor) { + return SWITCH_STATUS_FALSE; + } + + return apr_pollset_remove((apr_pollset_t *) pollset, (const apr_pollfd_t *) descriptor); +} + +SWITCH_DECLARE(switch_status_t) switch_socket_create_pollfd(switch_pollfd_t **pollfd, switch_socket_t *sock, int16_t flags, void *client_data, switch_memory_pool_t *pool) +{ + if (!pollfd || !sock) { + return SWITCH_STATUS_FALSE; + } + + if ((*pollfd = (switch_pollfd_t*)apr_palloc(pool, sizeof(switch_pollfd_t))) == 0) { + return SWITCH_STATUS_MEMERR; + } + + memset(*pollfd, 0, sizeof(switch_pollfd_t)); + + (*pollfd)->desc_type = APR_POLL_SOCKET; + (*pollfd)->reqevents = flags; + (*pollfd)->desc.s = sock; + (*pollfd)->client_data = client_data; + + return SWITCH_STATUS_SUCCESS; +} + + +SWITCH_DECLARE(switch_status_t) switch_pollset_poll(switch_pollset_t *pollset, switch_interval_time_t timeout, int32_t *num, const switch_pollfd_t **descriptors) +{ + apr_status_t st = SWITCH_STATUS_FALSE; + + if (pollset) { + st = apr_pollset_poll((apr_pollset_t *) pollset, timeout, num, (const apr_pollfd_t **) descriptors); + + if (st == APR_TIMEUP) { + st = SWITCH_STATUS_TIMEOUT; + } + } + + return st; +} + SWITCH_DECLARE(switch_status_t) switch_poll(switch_pollfd_t *aprset, int32_t numsock, int32_t *nsds, switch_interval_time_t timeout) { apr_status_t st = SWITCH_STATUS_FALSE; @@ -843,27 +888,17 @@ SWITCH_DECLARE(switch_status_t) switch_poll(switch_pollfd_t *aprset, int32_t num return st; } -SWITCH_DECLARE(switch_status_t) switch_socket_create_pollfd(switch_pollfd_t ** poll, switch_socket_t *sock, int16_t flags, switch_memory_pool_t *pool) +SWITCH_DECLARE(switch_status_t) switch_socket_create_pollset(switch_pollfd_t ** poll, switch_socket_t *sock, int16_t flags, switch_memory_pool_t *pool) { switch_pollset_t *pollset; - void *ptr = NULL; - - if ((ptr = apr_palloc(pool, sizeof(switch_pollfd_t))) == 0) { - return SWITCH_STATUS_MEMERR; - } - if (switch_pollset_create(&pollset, 1, pool, 0) != SWITCH_STATUS_SUCCESS) { return SWITCH_STATUS_GENERR; } - memset(ptr, 0, sizeof(switch_pollfd_t)); - *poll = ptr; - - (*poll)->desc_type = APR_POLL_SOCKET; - (*poll)->reqevents = flags; - (*poll)->desc.s = sock; - (*poll)->client_data = sock; + if (switch_socket_create_pollfd(poll, sock, flags, sock, pool) != SWITCH_STATUS_SUCCESS) { + return SWITCH_STATUS_GENERR; + } if (switch_pollset_add(pollset, *poll) != SWITCH_STATUS_SUCCESS) { return SWITCH_STATUS_GENERR; diff --git a/src/switch_rtp.c b/src/switch_rtp.c index 669fbe5e5a..ed950fb6fb 100644 --- a/src/switch_rtp.c +++ b/src/switch_rtp.c @@ -837,7 +837,7 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_set_local_address(switch_rtp_t *rtp_s switch_set_flag_locked(rtp_session, SWITCH_RTP_FLAG_NOBLOCK); } - switch_socket_create_pollfd(&rtp_session->read_pollfd, rtp_session->sock_input, SWITCH_POLLIN | SWITCH_POLLERR, rtp_session->pool); + switch_socket_create_pollset(&rtp_session->read_pollfd, rtp_session->sock_input, SWITCH_POLLIN | SWITCH_POLLERR, rtp_session->pool); status = SWITCH_STATUS_SUCCESS; *err = "Success";