diff options
author | Mladen Turk <mturk@apache.org> | 2009-02-13 12:24:00 +0000 |
---|---|---|
committer | Mladen Turk <mturk@apache.org> | 2009-02-13 12:24:00 +0000 |
commit | a91a88b0176b17d428750f1fed1bb9762c822a0d (patch) | |
tree | 0bf339d6ff7de73471f87ade59429834e45b2282 | |
parent | e231dd398a6e40088649d59a9a4fd6120a876b82 (diff) | |
download | apr-a91a88b0176b17d428750f1fed1bb9762c822a0d.tar.gz |
Implement providers for apr_pollset and apr_pollcb
git-svn-id: https://svn.apache.org/repos/asf/apr/apr/trunk@744095 13f79535-47bb-0310-9956-ffa450edef68
-rw-r--r-- | CHANGES | 5 | ||||
-rw-r--r-- | NWGNUmakefile | 2 | ||||
-rw-r--r-- | apr.dsp | 8 | ||||
-rw-r--r-- | include/apr_poll.h | 69 | ||||
-rw-r--r-- | include/arch/unix/apr_arch_poll_private.h | 77 | ||||
-rw-r--r-- | libapr.dsp | 8 | ||||
-rw-r--r-- | poll/os2/pollset.c | 9 | ||||
-rw-r--r-- | poll/unix/epoll.c | 260 | ||||
-rw-r--r-- | poll/unix/kqueue.c | 280 | ||||
-rw-r--r-- | poll/unix/poll.c | 310 | ||||
-rw-r--r-- | poll/unix/port.c | 281 | ||||
-rw-r--r-- | poll/unix/select.c | 311 |
12 files changed, 701 insertions, 919 deletions
@@ -1,6 +1,11 @@ -*- coding: utf-8 -*- Changes for APR 2.0.0 + *) Make apr_pollset and apr_pollcb implementations using providers. + Added apr_pollset_create_ex and apr_pollcb_create_ex that allows + choosing non-default providers. + [Mladen Turk] + *) Intruduce APR_PERMS_SET macros for setting the owner/group on objects. Currently only implemented for shm, proc and global mutexes on posix platforms. diff --git a/NWGNUmakefile b/NWGNUmakefile index c4a0dcf7e..5a565637d 100644 --- a/NWGNUmakefile +++ b/NWGNUmakefile @@ -311,6 +311,8 @@ FILES_lib_objs = \ $(OBJDIR)/rand.o \ $(OBJDIR)/readwrite.o \ $(OBJDIR)/seek.o \ + $(OBJDIR)/pollcb.o \ + $(OBJDIR)/pollset.o \ $(OBJDIR)/select.o \ $(OBJDIR)/sendrecv.o \ $(OBJDIR)/sha2.o \ @@ -412,6 +412,14 @@ SOURCE=.\passwd\apr_getpass.c # PROP Default_Filter "" # Begin Source File +SOURCE=.\poll\unix\pollcb.c +# End Source File +# Begin Source File + +SOURCE=.\poll\unix\pollset.c +# End Source File +# Begin Source File + SOURCE=.\poll\unix\select.c # End Source File # End Group diff --git a/include/apr_poll.h b/include/apr_poll.h index 3e5d8f96d..ec3cc1c56 100644 --- a/include/apr_poll.h +++ b/include/apr_poll.h @@ -57,6 +57,19 @@ extern "C" { #define APR_POLLSET_THREADSAFE 0x001 /**< Adding or Removing a Descriptor is thread safe */ #define APR_POLLSET_NOCOPY 0x002 /**< Descriptors passed to apr_pollset_create() are not copied */ #define APR_POLLSET_WAKEABLE 0x004 /**< Pollset poll operation is interruptable */ +#define APR_POLLSET_NODEFAULT 0x010 /**< Do not try default method if non default fails */ + +/** + * Pollset Methods + */ +typedef enum { + APR_POLLSET_DEFAULT, /**< Platform default poll method */ + APR_POLLSET_SELECT, /**< Poll uses select method */ + APR_POLLSET_KQUEUE, + APR_POLLSET_PORT, + APR_POLLSET_EPOLL, + APR_POLLSET_POLL +} apr_pollset_method_e; /** Used in apr_pollfd_t to determine what the apr_descriptor is */ typedef enum { @@ -119,6 +132,33 @@ APR_DECLARE(apr_status_t) apr_pollset_create(apr_pollset_t **pollset, apr_uint32_t flags); /** + * Setup a pollset object + * @param pollset The pointer in which to return the newly created object + * @param size The maximum number of descriptors that this pollset can hold + * @param p The pool from which to allocate the pollset + * @param flags Optional flags to modify the operation of the pollset. + * @param method Poll method to use. See @apr_pollset_method_e. + * + * @remark If flags equals APR_POLLSET_THREADSAFE, then a pollset is + * created on which it is safe to make concurrent calls to + * apr_pollset_add(), apr_pollset_remove() and apr_pollset_poll() + * from separate threads. This feature is only supported on some + * platforms; the apr_pollset_create() call will fail with + * APR_ENOTIMPL on platforms where it is not supported. + * @remark If flags contain APR_POLLSET_WAKEABLE, then a pollset is + * created with additional internal pipe object used for + * apr_pollset_wakeup() call. The actual size of pollset is + * in that case size + 1. This feature is only supported on some + * platforms; the apr_pollset_create() call will fail with + * APR_ENOTIMPL on platforms where it is not supported. + */ +APR_DECLARE(apr_status_t) apr_pollset_create_ex(apr_pollset_t **pollset, + apr_uint32_t size, + apr_pool_t *p, + apr_uint32_t flags, + apr_pollset_method_e method); + +/** * Destroy a pollset object * @param pollset The pollset to destroy */ @@ -207,6 +247,18 @@ APR_DECLARE(apr_status_t) apr_poll(apr_pollfd_t *aprset, apr_int32_t numsock, apr_int32_t *nsds, apr_interval_time_t timeout); +/** + * Display the name of the pollset method, as it relates to the actual + * method used. + * @param pollset the name of the pollset. + */ +APR_DECLARE(const char *) apr_pollset_method_name(apr_pollset_t *pollset); + +/** + * Display the name of the default poll method: APR_POLLSET_DEFAULT + */ +APR_DECLARE(const char *) apr_poll_method_defname(void); + /** Opaque structure used for pollset API */ typedef struct apr_pollcb_t apr_pollcb_t; @@ -226,6 +278,23 @@ APR_DECLARE(apr_status_t) apr_pollcb_create(apr_pollcb_t **pollcb, apr_uint32_t flags); /** + * Setup a pollcb object + * @param pollcb The pointer in which to return the newly created object + * @param size The maximum number of descriptors that a single _poll can return. + * @param p The pool from which to allocate the pollcb + * @param flags Optional flags to modify the operation of the pollcb. + * @param method Poll method to use. See @apr_pollset_method_e. + * + * @remark Pollcb is only supported on some platforms; the apr_pollcb_create() + * call will fail with APR_ENOTIMPL on platforms where it is not supported. + */ +APR_DECLARE(apr_status_t) apr_pollcb_create_ex(apr_pollcb_t **pollcb, + apr_uint32_t size, + apr_pool_t *pool, + apr_uint32_t flags, + apr_pollset_method_e method); + +/** * Add a socket or file descriptor to a pollcb * @param pollcb The pollcb to which to add the descriptor * @param descriptor The descriptor to add diff --git a/include/arch/unix/apr_arch_poll_private.h b/include/arch/unix/apr_arch_poll_private.h index f176eac0e..c2e646b46 100644 --- a/include/arch/unix/apr_arch_poll_private.h +++ b/include/arch/unix/apr_arch_poll_private.h @@ -17,13 +17,6 @@ #ifndef APR_ARCH_POLL_PRIVATE_H #define APR_ARCH_POLL_PRIVATE_H -#include "apr.h" -#include "apr_poll.h" -#include "apr_time.h" -#include "apr_portable.h" -#include "apr_arch_networkio.h" -#include "apr_arch_file_io.h" - #if HAVE_POLL_H #include <poll.h> #endif @@ -55,14 +48,19 @@ /* Choose the best method platform specific to use in apr_pollset */ #ifdef HAVE_KQUEUE #define POLLSET_USES_KQUEUE +#define POLLSET_DEFAULT_METHOD APR_POLLSET_KQUEUE #elif defined(HAVE_PORT_CREATE) #define POLLSET_USES_PORT +#define POLLSET_DEFAULT_METHOD APR_POLLSET_PORT #elif defined(HAVE_EPOLL) #define POLLSET_USES_EPOLL +#define POLLSET_DEFAULT_METHOD APR_POLLSET_EPOLL #elif defined(HAVE_POLL) #define POLLSET_USES_POLL +#define POLLSET_DEFAULT_METHOD APR_POLLSET_POLL #else #define POLLSET_USES_SELECT +#define POLLSET_DEFAULT_METHOD APR_POLLSET_SELECT #endif #ifdef HAVE_POLL @@ -79,10 +77,10 @@ #include "apr_thread_mutex.h" #define pollset_lock_rings() \ if (pollset->flags & APR_POLLSET_THREADSAFE) \ - apr_thread_mutex_lock(pollset->ring_lock); + apr_thread_mutex_lock(pollset->p->ring_lock); #define pollset_unlock_rings() \ if (pollset->flags & APR_POLLSET_THREADSAFE) \ - apr_thread_mutex_unlock(pollset->ring_lock); + apr_thread_mutex_unlock(pollset->p->ring_lock); #else #define pollset_lock_rings() #define pollset_unlock_rings() @@ -97,4 +95,65 @@ struct pfd_elem_t { #endif +typedef struct apr_pollset_private_t apr_pollset_private_t; +typedef struct apr_pollset_provider_t apr_pollset_provider_t; +typedef struct apr_pollcb_provider_t apr_pollcb_provider_t; +struct apr_pollset_t +{ + apr_pool_t *pool; + apr_uint32_t nelts; + apr_uint32_t nalloc; + apr_uint32_t flags; + /* Pipe descriptors used for wakeup */ + apr_file_t *wakeup_pipe[2]; + apr_pollset_private_t *p; + apr_pollset_provider_t *provider; +}; + +typedef union { +#if defined(HAVE_EPOLL) + struct epoll_event *epoll; +#endif +#if defined(HAVE_PORT_CREATE) + port_event_t *port; +#endif +#if defined(HAVE_KQUEUE) + struct kevent *ke; +#endif +#if defined(HAVE_POLL) + struct pollfd *ps; +#endif + void *undef; +} apr_pollcb_pset; + +struct apr_pollcb_t { + apr_pool_t *pool; + apr_uint32_t nelts; + apr_uint32_t nalloc; + int fd; + apr_pollcb_pset pollset; + apr_pollfd_t **copyset; + apr_pollcb_provider_t *provider; +}; + +struct apr_pollset_provider_t { + apr_status_t (*create)(apr_pollset_t *, apr_uint32_t, apr_pool_t *, apr_uint32_t); + apr_status_t (*add)(apr_pollset_t *, const apr_pollfd_t *); + apr_status_t (*remove)(apr_pollset_t *, const apr_pollfd_t *); + apr_status_t (*poll)(apr_pollset_t *, apr_interval_time_t, apr_int32_t *, const apr_pollfd_t **); + apr_status_t (*cleanup)(apr_pollset_t *); + const char *name; +}; + +struct apr_pollcb_provider_t { + apr_status_t (*create)(apr_pollcb_t *, apr_uint32_t, apr_pool_t *, apr_uint32_t); + apr_status_t (*add)(apr_pollcb_t *, apr_pollfd_t *); + apr_status_t (*remove)(apr_pollcb_t *, apr_pollfd_t *); + apr_status_t (*poll)(apr_pollcb_t *, apr_interval_time_t, apr_pollcb_cb_t, void *); + const char *name; +}; + +/* Private functions */ +void apr_pollset_drain_wakeup_pipe(apr_pollset_t *pollset); + #endif /* APR_ARCH_POLL_PRIVATE_H */ diff --git a/libapr.dsp b/libapr.dsp index 1210013a6..485f1c761 100644 --- a/libapr.dsp +++ b/libapr.dsp @@ -464,6 +464,14 @@ SOURCE=.\passwd\apr_getpass.c # PROP Default_Filter "" # Begin Source File +SOURCE=.\poll\unix\pollcb.c +# End Source File +# Begin Source File + +SOURCE=.\poll\unix\pollset.c +# End Source File +# Begin Source File + SOURCE=.\poll\unix\select.c # End Source File # End Group diff --git a/poll/os2/pollset.c b/poll/os2/pollset.c index 0680c29c0..a358fafb2 100644 --- a/poll/os2/pollset.c +++ b/poll/os2/pollset.c @@ -51,7 +51,14 @@ APR_DECLARE(apr_status_t) apr_pollset_create(apr_pollset_t **pollset, return APR_SUCCESS; } - +APR_DECLARE(apr_status_t) apr_pollset_create_ex(apr_pollset_t **pollset, + apr_uint32_t size, + apr_pool_t *p, + apr_uint32_t flags, + apr_pollset_method_e method); +{ + return apr_pollset_create(pollset, size, p, flags); +} APR_DECLARE(apr_status_t) apr_pollset_destroy(apr_pollset_t *pollset) { diff --git a/poll/unix/epoll.c b/poll/unix/epoll.c index c8ab6d63a..befa73cf6 100644 --- a/poll/unix/epoll.c +++ b/poll/unix/epoll.c @@ -14,9 +14,15 @@ * limitations under the License. */ +#include "apr.h" +#include "apr_poll.h" +#include "apr_time.h" +#include "apr_portable.h" +#include "apr_arch_file_io.h" +#include "apr_arch_networkio.h" #include "apr_arch_poll_private.h" -#ifdef POLLSET_USES_EPOLL +#if defined(HAVE_EPOLL) static apr_int16_t get_epoll_event(apr_int16_t event) { @@ -56,17 +62,11 @@ static apr_int16_t get_epoll_revent(apr_int16_t event) return rv; } -struct apr_pollset_t +struct apr_pollset_private_t { - apr_pool_t *pool; - apr_uint32_t nelts; - apr_uint32_t nalloc; int epoll_fd; struct epoll_event *pollset; apr_pollfd_t *result_set; - apr_uint32_t flags; - /* Pipe descriptors used for wakeup */ - apr_file_t *wakeup_pipe[2]; #if APR_HAS_THREADS /* A thread mutex to protect operations on the rings */ apr_thread_mutex_t *ring_lock; @@ -80,65 +80,17 @@ struct apr_pollset_t APR_RING_HEAD(pfd_dead_ring_t, pfd_elem_t) dead_ring; }; -static apr_status_t backend_cleanup(void *p_) +static apr_status_t impl_pollset_cleanup(apr_pollset_t *pollset) { - apr_pollset_t *pollset = (apr_pollset_t *) p_; - close(pollset->epoll_fd); - if (pollset->flags & APR_POLLSET_WAKEABLE) { - /* Close both sides of the wakeup pipe */ - if (pollset->wakeup_pipe[0]) { - apr_file_close(pollset->wakeup_pipe[0]); - pollset->wakeup_pipe[0] = NULL; - } - if (pollset->wakeup_pipe[1]) { - apr_file_close(pollset->wakeup_pipe[1]); - pollset->wakeup_pipe[1] = NULL; - } - } + close(pollset->p->epoll_fd); return APR_SUCCESS; } -/* Create a dummy wakeup pipe for interrupting the poller - */ -static apr_status_t create_wakeup_pipe(apr_pollset_t *pollset) -{ - apr_status_t rv; - apr_pollfd_t fd; - - if ((rv = apr_file_pipe_create(&pollset->wakeup_pipe[0], - &pollset->wakeup_pipe[1], - pollset->pool)) != APR_SUCCESS) - return rv; - fd.reqevents = APR_POLLIN; - fd.desc_type = APR_POLL_FILE; - fd.desc.f = pollset->wakeup_pipe[0]; - /* Add the pipe to the pollset - */ - return apr_pollset_add(pollset, &fd); -} - -/* Read and discard what's ever in the wakeup pipe. - */ -static void drain_wakeup_pipe(apr_pollset_t *pollset) -{ - char rb[512]; - apr_size_t nr = sizeof(rb); - - while (apr_file_read(pollset->wakeup_pipe[0], rb, &nr) == APR_SUCCESS) { - /* Although we write just one byte to the other end of the pipe - * during wakeup, multiple treads could call the wakeup. - * So simply drain out from the input side of the pipe all - * the data. - */ - if (nr != sizeof(rb)) - break; - } -} -APR_DECLARE(apr_status_t) apr_pollset_create(apr_pollset_t **pollset, - apr_uint32_t size, - apr_pool_t *p, - apr_uint32_t flags) +static apr_status_t impl_pollset_create(apr_pollset_t *pollset, + apr_uint32_t size, + apr_pool_t *p, + apr_uint32_t flags) { apr_status_t rv; int fd; @@ -149,58 +101,40 @@ APR_DECLARE(apr_status_t) apr_pollset_create(apr_pollset_t **pollset, } fd = epoll_create(size); if (fd < 0) { - *pollset = NULL; + pollset->p = NULL; return errno; } - *pollset = apr_palloc(p, sizeof(**pollset)); + pollset->p = apr_palloc(p, sizeof(apr_pollset_private_t)); #if APR_HAS_THREADS if ((flags & APR_POLLSET_THREADSAFE) && !(flags & APR_POLLSET_NOCOPY) && - ((rv = apr_thread_mutex_create(&(*pollset)->ring_lock, + ((rv = apr_thread_mutex_create(&pollset->p->ring_lock, APR_THREAD_MUTEX_DEFAULT, p)) != APR_SUCCESS)) { - *pollset = NULL; + pollset->p = NULL; return rv; } #else if (flags & APR_POLLSET_THREADSAFE) { - *pollset = NULL; + pollset->p = NULL; return APR_ENOTIMPL; } #endif - (*pollset)->nelts = 0; - (*pollset)->nalloc = size; - (*pollset)->flags = flags; - (*pollset)->pool = p; - (*pollset)->epoll_fd = fd; - (*pollset)->pollset = apr_palloc(p, size * sizeof(struct epoll_event)); - (*pollset)->result_set = apr_palloc(p, size * sizeof(apr_pollfd_t)); + pollset->p->epoll_fd = fd; + pollset->p->pollset = apr_palloc(p, size * sizeof(struct epoll_event)); + pollset->p->result_set = apr_palloc(p, size * sizeof(apr_pollfd_t)); if (!(flags & APR_POLLSET_NOCOPY)) { - APR_RING_INIT(&(*pollset)->query_ring, pfd_elem_t, link); - APR_RING_INIT(&(*pollset)->free_ring, pfd_elem_t, link); - APR_RING_INIT(&(*pollset)->dead_ring, pfd_elem_t, link); + APR_RING_INIT(&pollset->p->query_ring, pfd_elem_t, link); + APR_RING_INIT(&pollset->p->free_ring, pfd_elem_t, link); + APR_RING_INIT(&pollset->p->dead_ring, pfd_elem_t, link); } - if (flags & APR_POLLSET_WAKEABLE) { - /* Create wakeup pipe */ - if ((rv = create_wakeup_pipe(*pollset)) != APR_SUCCESS) { - close(fd); - *pollset = NULL; - return rv; - } - } - apr_pool_cleanup_register(p, *pollset, backend_cleanup, backend_cleanup); return APR_SUCCESS; } -APR_DECLARE(apr_status_t) apr_pollset_destroy(apr_pollset_t *pollset) -{ - return apr_pool_cleanup_run(pollset->pool, pollset, backend_cleanup); -} - -APR_DECLARE(apr_status_t) apr_pollset_add(apr_pollset_t *pollset, - const apr_pollfd_t *descriptor) +static apr_status_t impl_pollset_add(apr_pollset_t *pollset, + const apr_pollfd_t *descriptor) { struct epoll_event ev = {0}; int ret = -1; @@ -215,8 +149,8 @@ APR_DECLARE(apr_status_t) apr_pollset_add(apr_pollset_t *pollset, else { pollset_lock_rings(); - if (!APR_RING_EMPTY(&(pollset->free_ring), pfd_elem_t, link)) { - elem = APR_RING_FIRST(&(pollset->free_ring)); + if (!APR_RING_EMPTY(&(pollset->p->free_ring), pfd_elem_t, link)) { + elem = APR_RING_FIRST(&(pollset->p->free_ring)); APR_RING_REMOVE(elem, link); } else { @@ -227,11 +161,11 @@ APR_DECLARE(apr_status_t) apr_pollset_add(apr_pollset_t *pollset, ev.data.ptr = elem; } if (descriptor->desc_type == APR_POLL_SOCKET) { - ret = epoll_ctl(pollset->epoll_fd, EPOLL_CTL_ADD, + ret = epoll_ctl(pollset->p->epoll_fd, EPOLL_CTL_ADD, descriptor->desc.s->socketdes, &ev); } else { - ret = epoll_ctl(pollset->epoll_fd, EPOLL_CTL_ADD, + ret = epoll_ctl(pollset->p->epoll_fd, EPOLL_CTL_ADD, descriptor->desc.f->filedes, &ev); } @@ -243,11 +177,11 @@ APR_DECLARE(apr_status_t) apr_pollset_add(apr_pollset_t *pollset, else { if (0 != ret) { rv = APR_EBADF; - APR_RING_INSERT_TAIL(&(pollset->free_ring), elem, pfd_elem_t, link); + APR_RING_INSERT_TAIL(&(pollset->p->free_ring), elem, pfd_elem_t, link); } else { pollset->nelts++; - APR_RING_INSERT_TAIL(&(pollset->query_ring), elem, pfd_elem_t, link); + APR_RING_INSERT_TAIL(&(pollset->p->query_ring), elem, pfd_elem_t, link); } pollset_unlock_rings(); } @@ -255,8 +189,8 @@ APR_DECLARE(apr_status_t) apr_pollset_add(apr_pollset_t *pollset, return rv; } -APR_DECLARE(apr_status_t) apr_pollset_remove(apr_pollset_t *pollset, - const apr_pollfd_t *descriptor) +static apr_status_t impl_pollset_remove(apr_pollset_t *pollset, + const apr_pollfd_t *descriptor) { pfd_elem_t *ep; apr_status_t rv = APR_SUCCESS; @@ -266,11 +200,11 @@ APR_DECLARE(apr_status_t) apr_pollset_remove(apr_pollset_t *pollset, ev.events = get_epoll_event(descriptor->reqevents); if (descriptor->desc_type == APR_POLL_SOCKET) { - ret = epoll_ctl(pollset->epoll_fd, EPOLL_CTL_DEL, + ret = epoll_ctl(pollset->p->epoll_fd, EPOLL_CTL_DEL, descriptor->desc.s->socketdes, &ev); } else { - ret = epoll_ctl(pollset->epoll_fd, EPOLL_CTL_DEL, + ret = epoll_ctl(pollset->p->epoll_fd, EPOLL_CTL_DEL, descriptor->desc.f->filedes, &ev); } if (ret < 0) { @@ -280,15 +214,15 @@ APR_DECLARE(apr_status_t) apr_pollset_remove(apr_pollset_t *pollset, if (!(pollset->flags & APR_POLLSET_NOCOPY)) { pollset_lock_rings(); - if (!APR_RING_EMPTY(&(pollset->query_ring), pfd_elem_t, link)) { - for (ep = APR_RING_FIRST(&(pollset->query_ring)); - ep != APR_RING_SENTINEL(&(pollset->query_ring), + if (!APR_RING_EMPTY(&(pollset->p->query_ring), pfd_elem_t, link)) { + for (ep = APR_RING_FIRST(&(pollset->p->query_ring)); + ep != APR_RING_SENTINEL(&(pollset->p->query_ring), pfd_elem_t, link); ep = APR_RING_NEXT(ep, link)) { if (descriptor->desc.s == ep->pfd.desc.s) { APR_RING_REMOVE(ep, link); - APR_RING_INSERT_TAIL(&(pollset->dead_ring), + APR_RING_INSERT_TAIL(&(pollset->p->dead_ring), ep, pfd_elem_t, link); break; } @@ -301,7 +235,7 @@ APR_DECLARE(apr_status_t) apr_pollset_remove(apr_pollset_t *pollset, return rv; } -APR_DECLARE(apr_status_t) apr_pollset_poll(apr_pollset_t *pollset, +static apr_status_t impl_pollset_poll(apr_pollset_t *pollset, apr_interval_time_t timeout, apr_int32_t *num, const apr_pollfd_t **descriptors) @@ -314,7 +248,7 @@ APR_DECLARE(apr_status_t) apr_pollset_poll(apr_pollset_t *pollset, timeout /= 1000; } - ret = epoll_wait(pollset->epoll_fd, pollset->pollset, pollset->nalloc, + ret = epoll_wait(pollset->p->epoll_fd, pollset->p->pollset, pollset->nalloc, timeout); (*num) = ret; @@ -327,20 +261,20 @@ APR_DECLARE(apr_status_t) apr_pollset_poll(apr_pollset_t *pollset, else { if (pollset->flags & APR_POLLSET_NOCOPY) { for (i = 0, j = 0; i < ret; i++) { - fd = *((apr_pollfd_t *) (pollset->pollset[i].data.ptr)); + fd = *((apr_pollfd_t *)(pollset->p->pollset[i].data.ptr)); /* Check if the polled descriptor is our * wakeup pipe. In that case do not put it result set. */ if ((pollset->flags & APR_POLLSET_WAKEABLE) && fd.desc_type == APR_POLL_FILE && fd.desc.f == pollset->wakeup_pipe[0]) { - drain_wakeup_pipe(pollset); + apr_pollset_drain_wakeup_pipe(pollset); rv = APR_EINTR; } else { - pollset->result_set[j] = fd; - pollset->result_set[j].rtnevents = - get_epoll_revent(pollset->pollset[i].events); + pollset->p->result_set[j] = fd; + pollset->p->result_set[j].rtnevents = + get_epoll_revent(pollset->p->pollset[i].events); j++; } } @@ -349,17 +283,17 @@ APR_DECLARE(apr_status_t) apr_pollset_poll(apr_pollset_t *pollset, } else { for (i = 0, j = 0; i < ret; i++) { - fd = (((pfd_elem_t *) (pollset->pollset[i].data.ptr))->pfd); + fd = (((pfd_elem_t *) (pollset->p->pollset[i].data.ptr))->pfd); if ((pollset->flags & APR_POLLSET_WAKEABLE) && fd.desc_type == APR_POLL_FILE && fd.desc.f == pollset->wakeup_pipe[0]) { - drain_wakeup_pipe(pollset); + apr_pollset_drain_wakeup_pipe(pollset); rv = APR_EINTR; } else { - pollset->result_set[j] = fd; - pollset->result_set[j].rtnevents = - get_epoll_revent(pollset->pollset[i].events); + pollset->p->result_set[j] = fd; + pollset->p->result_set[j].rtnevents = + get_epoll_revent(pollset->p->pollset[i].events); j++; } } @@ -368,7 +302,7 @@ APR_DECLARE(apr_status_t) apr_pollset_poll(apr_pollset_t *pollset, } if (descriptors) { - *descriptors = pollset->result_set; + *descriptors = pollset->p->result_set; } } @@ -376,7 +310,7 @@ APR_DECLARE(apr_status_t) apr_pollset_poll(apr_pollset_t *pollset, pollset_lock_rings(); /* Shift all PFDs in the Dead Ring to be Free Ring */ - APR_RING_CONCAT(&(pollset->free_ring), &(pollset->dead_ring), pfd_elem_t, link); + APR_RING_CONCAT(&(pollset->p->free_ring), &(pollset->p->dead_ring), pfd_elem_t, link); pollset_unlock_rings(); } @@ -384,54 +318,46 @@ APR_DECLARE(apr_status_t) apr_pollset_poll(apr_pollset_t *pollset, return rv; } -APR_DECLARE(apr_status_t) apr_pollset_wakeup(apr_pollset_t *pollset) -{ - if (pollset->flags & APR_POLLSET_WAKEABLE) - return apr_file_putc(1, pollset->wakeup_pipe[1]); - else - return APR_EINIT; -} - -struct apr_pollcb_t { - apr_pool_t *pool; - apr_uint32_t nalloc; - struct epoll_event *pollset; - int epoll_fd; +static apr_pollset_provider_t impl = { + impl_pollset_create, + impl_pollset_add, + impl_pollset_remove, + impl_pollset_poll, + impl_pollset_cleanup, + "epool" }; +apr_pollset_provider_t *apr_pollset_provider_epoll = &impl; + static apr_status_t cb_cleanup(void *p_) { apr_pollcb_t *pollcb = (apr_pollcb_t *) p_; - close(pollcb->epoll_fd); + close(pollcb->fd); return APR_SUCCESS; } -APR_DECLARE(apr_status_t) apr_pollcb_create(apr_pollcb_t **pollcb, - apr_uint32_t size, - apr_pool_t *p, - apr_uint32_t flags) +static apr_status_t impl_pollcb_create(apr_pollcb_t *pollcb, + apr_uint32_t size, + apr_pool_t *p, + apr_uint32_t flags) { int fd; fd = epoll_create(size); if (fd < 0) { - *pollcb = NULL; return apr_get_netos_error(); } - *pollcb = apr_palloc(p, sizeof(**pollcb)); - (*pollcb)->nalloc = size; - (*pollcb)->pool = p; - (*pollcb)->epoll_fd = fd; - (*pollcb)->pollset = apr_palloc(p, size * sizeof(struct epoll_event)); - apr_pool_cleanup_register(p, *pollcb, cb_cleanup, cb_cleanup); + pollcb->fd = fd; + pollcb->pollset.epoll = apr_palloc(p, size * sizeof(struct epoll_event)); + apr_pool_cleanup_register(p, pollcb, cb_cleanup, cb_cleanup); return APR_SUCCESS; } -APR_DECLARE(apr_status_t) apr_pollcb_add(apr_pollcb_t *pollcb, - apr_pollfd_t *descriptor) +static apr_status_t impl_pollcb_add(apr_pollcb_t *pollcb, + apr_pollfd_t *descriptor) { struct epoll_event ev; int ret; @@ -440,11 +366,11 @@ APR_DECLARE(apr_status_t) apr_pollcb_add(apr_pollcb_t *pollcb, ev.data.ptr = (void *)descriptor; if (descriptor->desc_type == APR_POLL_SOCKET) { - ret = epoll_ctl(pollcb->epoll_fd, EPOLL_CTL_ADD, + ret = epoll_ctl(pollcb->fd, EPOLL_CTL_ADD, descriptor->desc.s->socketdes, &ev); } else { - ret = epoll_ctl(pollcb->epoll_fd, EPOLL_CTL_ADD, + ret = epoll_ctl(pollcb->fd, EPOLL_CTL_ADD, descriptor->desc.f->filedes, &ev); } @@ -455,8 +381,8 @@ APR_DECLARE(apr_status_t) apr_pollcb_add(apr_pollcb_t *pollcb, return APR_SUCCESS; } -APR_DECLARE(apr_status_t) apr_pollcb_remove(apr_pollcb_t *pollcb, - apr_pollfd_t *descriptor) +static apr_status_t impl_pollcb_remove(apr_pollcb_t *pollcb, + apr_pollfd_t *descriptor) { apr_status_t rv = APR_SUCCESS; struct epoll_event ev; @@ -465,11 +391,11 @@ APR_DECLARE(apr_status_t) apr_pollcb_remove(apr_pollcb_t *pollcb, ev.events = get_epoll_event(descriptor->reqevents); if (descriptor->desc_type == APR_POLL_SOCKET) { - ret = epoll_ctl(pollcb->epoll_fd, EPOLL_CTL_DEL, + ret = epoll_ctl(pollcb->fd, EPOLL_CTL_DEL, descriptor->desc.s->socketdes, &ev); } else { - ret = epoll_ctl(pollcb->epoll_fd, EPOLL_CTL_DEL, + ret = epoll_ctl(pollcb->fd, EPOLL_CTL_DEL, descriptor->desc.f->filedes, &ev); } @@ -481,10 +407,10 @@ APR_DECLARE(apr_status_t) apr_pollcb_remove(apr_pollcb_t *pollcb, } -APR_DECLARE(apr_status_t) apr_pollcb_poll(apr_pollcb_t *pollcb, - apr_interval_time_t timeout, - apr_pollcb_cb_t func, - void *baton) +static apr_status_t impl_pollcb_poll(apr_pollcb_t *pollcb, + apr_interval_time_t timeout, + apr_pollcb_cb_t func, + void *baton) { int ret, i; apr_status_t rv = APR_SUCCESS; @@ -493,7 +419,7 @@ APR_DECLARE(apr_status_t) apr_pollcb_poll(apr_pollcb_t *pollcb, timeout /= 1000; } - ret = epoll_wait(pollcb->epoll_fd, pollcb->pollset, pollcb->nalloc, + ret = epoll_wait(pollcb->fd, pollcb->pollset.epoll, pollcb->nalloc, timeout); if (ret < 0) { rv = apr_get_netos_error(); @@ -503,8 +429,8 @@ APR_DECLARE(apr_status_t) apr_pollcb_poll(apr_pollcb_t *pollcb, } else { for (i = 0; i < ret; i++) { - apr_pollfd_t *pollfd = (apr_pollfd_t *)(pollcb->pollset[i].data.ptr); - pollfd->rtnevents = get_epoll_revent(pollcb->pollset[i].events); + apr_pollfd_t *pollfd = (apr_pollfd_t *)(pollcb->pollset.epoll[i].data.ptr); + pollfd->rtnevents = get_epoll_revent(pollcb->pollset.epoll[i].events); rv = func(baton, pollfd); if (rv) { @@ -516,4 +442,14 @@ APR_DECLARE(apr_status_t) apr_pollcb_poll(apr_pollcb_t *pollcb, return rv; } -#endif /* POLLSET_USES_EPOLL */ +static apr_pollcb_provider_t impl_cb = { + impl_pollcb_create, + impl_pollcb_add, + impl_pollcb_remove, + impl_pollcb_poll, + "epoll" +}; + +apr_pollcb_provider_t *apr_pollcb_provider_epoll = &impl_cb; + +#endif /* HAVE_EPOLL */ diff --git a/poll/unix/kqueue.c b/poll/unix/kqueue.c index 406eba6e9..d7b678030 100644 --- a/poll/unix/kqueue.c +++ b/poll/unix/kqueue.c @@ -14,9 +14,15 @@ * limitations under the License. */ +#include "apr.h" +#include "apr_poll.h" +#include "apr_time.h" +#include "apr_portable.h" +#include "apr_arch_file_io.h" +#include "apr_arch_networkio.h" #include "apr_arch_poll_private.h" -#ifdef POLLSET_USES_KQUEUE +#ifdef HAVE_KQUEUE static apr_int16_t get_kqueue_revent(apr_int16_t event, apr_int16_t flags) { @@ -34,18 +40,12 @@ static apr_int16_t get_kqueue_revent(apr_int16_t event, apr_int16_t flags) return rv; } -struct apr_pollset_t +struct apr_pollset_private_t { - apr_pool_t *pool; - apr_uint32_t nelts; - apr_uint32_t nalloc; int kqueue_fd; struct kevent kevent; struct kevent *ke_set; apr_pollfd_t *result_set; - apr_uint32_t flags; - /* Pipe descriptors used for wakeup */ - apr_file_t *wakeup_pipe[2]; #if APR_HAS_THREADS /* A thread mutex to protect operations on the rings */ apr_thread_mutex_t *ring_lock; @@ -59,129 +59,56 @@ struct apr_pollset_t APR_RING_HEAD(pfd_dead_ring_t, pfd_elem_t) dead_ring; }; -static apr_status_t backend_cleanup(void *p_) +static apr_status_t impl_pollset_cleanup(apr_pollset_t *pollset) { - apr_pollset_t *pollset = (apr_pollset_t *) p_; - close(pollset->kqueue_fd); - if (pollset->flags & APR_POLLSET_WAKEABLE) { - /* Close both sides of the wakeup pipe */ - if (pollset->wakeup_pipe[0]) { - apr_file_close(pollset->wakeup_pipe[0]); - pollset->wakeup_pipe[0] = NULL; - } - if (pollset->wakeup_pipe[1]) { - apr_file_close(pollset->wakeup_pipe[1]); - pollset->wakeup_pipe[1] = NULL; - } - } + close(pollset->p->kqueue_fd); return APR_SUCCESS; } -/* Create a dummy wakeup pipe for interrupting the poller - */ -static apr_status_t create_wakeup_pipe(apr_pollset_t *pollset) -{ - apr_status_t rv; - apr_pollfd_t fd; - - if ((rv = apr_file_pipe_create(&pollset->wakeup_pipe[0], - &pollset->wakeup_pipe[1], - pollset->pool)) != APR_SUCCESS) - return rv; - fd.reqevents = APR_POLLIN; - fd.desc_type = APR_POLL_FILE; - fd.desc.f = pollset->wakeup_pipe[0]; - /* Add the pipe to the pollset - */ - return apr_pollset_add(pollset, &fd); -} - -/* Read and discard what's ever in the wakeup pipe. - */ -static void drain_wakeup_pipe(apr_pollset_t *pollset) -{ - char rb[512]; - apr_size_t nr = sizeof(rb); - - while (apr_file_read(pollset->wakeup_pipe[0], rb, &nr) == APR_SUCCESS) { - /* Although we write just one byte to the other end of the pipe - * during wakeup, multiple treads could call the wakeup. - * So simply drain out from the input side of the pipe all - * the data. - */ - if (nr != sizeof(rb)) - break; - } -} - -APR_DECLARE(apr_status_t) apr_pollset_create(apr_pollset_t **pollset, - apr_uint32_t size, - apr_pool_t *p, - apr_uint32_t flags) +static apr_status_t impl_pollset_create(apr_pollset_t *pollset, + apr_uint32_t size, + apr_pool_t *p, + apr_uint32_t flags) { apr_status_t rv = APR_SUCCESS; - *pollset = apr_palloc(p, sizeof(**pollset)); + pollset->p = apr_palloc(p, sizeof(apr_pollset_private_t)); #if APR_HAS_THREADS if (flags & APR_POLLSET_THREADSAFE && - ((rv = apr_thread_mutex_create(&(*pollset)->ring_lock, + ((rv = apr_thread_mutex_create(&pollset->p->ring_lock, APR_THREAD_MUTEX_DEFAULT, p)) != APR_SUCCESS)) { - *pollset = NULL; + pollset->p = NULL; return rv; } #else if (flags & APR_POLLSET_THREADSAFE) { - *pollset = NULL; + pollset->p = NULL; return APR_ENOTIMPL; } #endif - if (flags & APR_POLLSET_WAKEABLE) { - /* Add room for wakeup descriptor */ - size++; - } - (*pollset)->nelts = 0; - (*pollset)->nalloc = size; - (*pollset)->flags = flags; - (*pollset)->pool = p; - - (*pollset)->ke_set = + pollset->p->ke_set = (struct kevent *) apr_palloc(p, size * sizeof(struct kevent)); - memset((*pollset)->ke_set, 0, size * sizeof(struct kevent)); + memset(pollset->p->ke_set, 0, size * sizeof(struct kevent)); - (*pollset)->kqueue_fd = kqueue(); + pollset->p->kqueue_fd = kqueue(); - if ((*pollset)->kqueue_fd == -1) { + if (pollset->p->kqueue_fd == -1) { return apr_get_netos_error(); } - (*pollset)->result_set = apr_palloc(p, size * sizeof(apr_pollfd_t)); + pollset->p->result_set = apr_palloc(p, size * sizeof(apr_pollfd_t)); - APR_RING_INIT(&(*pollset)->query_ring, pfd_elem_t, link); - APR_RING_INIT(&(*pollset)->free_ring, pfd_elem_t, link); - APR_RING_INIT(&(*pollset)->dead_ring, pfd_elem_t, link); - if (flags & APR_POLLSET_WAKEABLE) { - /* Create wakeup pipe */ - if ((rv = create_wakeup_pipe(*pollset)) != APR_SUCCESS) { - close((*pollset)->kqueue_fd); - *pollset = NULL; - return rv; - } - } - apr_pool_cleanup_register(p, (void *) (*pollset), backend_cleanup, - apr_pool_cleanup_null); + APR_RING_INIT(&pollset->p->query_ring, pfd_elem_t, link); + APR_RING_INIT(&pollset->p->free_ring, pfd_elem_t, link); + APR_RING_INIT(&pollset->p->dead_ring, pfd_elem_t, link); return rv; } -APR_DECLARE(apr_status_t) apr_pollset_destroy(apr_pollset_t * pollset) -{ - return apr_pool_cleanup_run(pollset->pool, pollset, backend_cleanup); -} - -APR_DECLARE(apr_status_t) apr_pollset_add(apr_pollset_t *pollset, - const apr_pollfd_t *descriptor) +static apr_status_t impl_pollset_add(apr_pollset_t *pollset, + const apr_pollfd_t *descriptor) { apr_os_sock_t fd; pfd_elem_t *elem; @@ -189,8 +116,8 @@ APR_DECLARE(apr_status_t) apr_pollset_add(apr_pollset_t *pollset, pollset_lock_rings(); - if (!APR_RING_EMPTY(&(pollset->free_ring), pfd_elem_t, link)) { - elem = APR_RING_FIRST(&(pollset->free_ring)); + if (!APR_RING_EMPTY(&(pollset->p->free_ring), pfd_elem_t, link)) { + elem = APR_RING_FIRST(&(pollset->p->free_ring)); APR_RING_REMOVE(elem, link); } else { @@ -207,18 +134,18 @@ APR_DECLARE(apr_status_t) apr_pollset_add(apr_pollset_t *pollset, } if (descriptor->reqevents & APR_POLLIN) { - EV_SET(&pollset->kevent, fd, EVFILT_READ, EV_ADD, 0, 0, elem); + EV_SET(&pollset->p->kevent, fd, EVFILT_READ, EV_ADD, 0, 0, elem); - if (kevent(pollset->kqueue_fd, &pollset->kevent, 1, NULL, 0, + if (kevent(pollset->p->kqueue_fd, &pollset->p->kevent, 1, NULL, 0, NULL) == -1) { rv = apr_get_netos_error(); } } if (descriptor->reqevents & APR_POLLOUT && rv == APR_SUCCESS) { - EV_SET(&pollset->kevent, fd, EVFILT_WRITE, EV_ADD, 0, 0, elem); + EV_SET(&pollset->p->kevent, fd, EVFILT_WRITE, EV_ADD, 0, 0, elem); - if (kevent(pollset->kqueue_fd, &pollset->kevent, 1, NULL, 0, + if (kevent(pollset->p->kqueue_fd, &pollset->p->kevent, 1, NULL, 0, NULL) == -1) { rv = apr_get_netos_error(); } @@ -226,10 +153,10 @@ APR_DECLARE(apr_status_t) apr_pollset_add(apr_pollset_t *pollset, if (rv == APR_SUCCESS) { pollset->nelts++; - APR_RING_INSERT_TAIL(&(pollset->query_ring), elem, pfd_elem_t, link); + APR_RING_INSERT_TAIL(&(pollset->p->query_ring), elem, pfd_elem_t, link); } else { - APR_RING_INSERT_TAIL(&(pollset->free_ring), elem, pfd_elem_t, link); + APR_RING_INSERT_TAIL(&(pollset->p->free_ring), elem, pfd_elem_t, link); } pollset_unlock_rings(); @@ -237,8 +164,8 @@ APR_DECLARE(apr_status_t) apr_pollset_add(apr_pollset_t *pollset, return rv; } -APR_DECLARE(apr_status_t) apr_pollset_remove(apr_pollset_t *pollset, - const apr_pollfd_t *descriptor) +static apr_status_t impl_pollset_remove(apr_pollset_t *pollset, + const apr_pollfd_t *descriptor) { pfd_elem_t *ep; apr_status_t rv = APR_SUCCESS; @@ -254,32 +181,32 @@ APR_DECLARE(apr_status_t) apr_pollset_remove(apr_pollset_t *pollset, } if (descriptor->reqevents & APR_POLLIN) { - EV_SET(&pollset->kevent, fd, EVFILT_READ, EV_DELETE, 0, 0, NULL); + EV_SET(&pollset->p->kevent, fd, EVFILT_READ, EV_DELETE, 0, 0, NULL); - if (kevent(pollset->kqueue_fd, &pollset->kevent, 1, NULL, 0, + if (kevent(pollset->p->kqueue_fd, &pollset->p->kevent, 1, NULL, 0, NULL) == -1) { rv = APR_NOTFOUND; } } if (descriptor->reqevents & APR_POLLOUT && rv == APR_SUCCESS) { - EV_SET(&pollset->kevent, fd, EVFILT_WRITE, EV_DELETE, 0, 0, NULL); + EV_SET(&pollset->p->kevent, fd, EVFILT_WRITE, EV_DELETE, 0, 0, NULL); - if (kevent(pollset->kqueue_fd, &pollset->kevent, 1, NULL, 0, + if (kevent(pollset->p->kqueue_fd, &pollset->p->kevent, 1, NULL, 0, NULL) == -1) { rv = APR_NOTFOUND; } } - if (!APR_RING_EMPTY(&(pollset->query_ring), pfd_elem_t, link)) { - for (ep = APR_RING_FIRST(&(pollset->query_ring)); - ep != APR_RING_SENTINEL(&(pollset->query_ring), + if (!APR_RING_EMPTY(&(pollset->p->query_ring), pfd_elem_t, link)) { + for (ep = APR_RING_FIRST(&(pollset->p->query_ring)); + ep != APR_RING_SENTINEL(&(pollset->p->query_ring), pfd_elem_t, link); ep = APR_RING_NEXT(ep, link)) { if (descriptor->desc.s == ep->pfd.desc.s) { APR_RING_REMOVE(ep, link); - APR_RING_INSERT_TAIL(&(pollset->dead_ring), + APR_RING_INSERT_TAIL(&(pollset->p->dead_ring), ep, pfd_elem_t, link); break; } @@ -291,10 +218,10 @@ APR_DECLARE(apr_status_t) apr_pollset_remove(apr_pollset_t *pollset, return rv; } -APR_DECLARE(apr_status_t) apr_pollset_poll(apr_pollset_t *pollset, - apr_interval_time_t timeout, - apr_int32_t *num, - const apr_pollfd_t **descriptors) +static apr_status_t impl_pollset_poll(apr_pollset_t *pollset, + apr_interval_time_t timeout, + apr_int32_t *num, + const apr_pollfd_t **descriptors) { int ret, i, j; struct timespec tv, *tvptr; @@ -310,8 +237,8 @@ APR_DECLARE(apr_status_t) apr_pollset_poll(apr_pollset_t *pollset, tvptr = &tv; } - ret = kevent(pollset->kqueue_fd, NULL, 0, pollset->ke_set, pollset->nalloc, - tvptr); + ret = kevent(pollset->p->kqueue_fd, NULL, 0, pollset->p->ke_set, + pollset->nalloc, tvptr); (*num) = ret; if (ret < 0) { rv = apr_get_netos_error(); @@ -321,25 +248,25 @@ APR_DECLARE(apr_status_t) apr_pollset_poll(apr_pollset_t *pollset, } else { for (i = 0, j = 0; i < ret; i++) { - fd = (((pfd_elem_t*)(pollset->ke_set[i].udata))->pfd); + fd = (((pfd_elem_t*)(pollset->p->ke_set[i].udata))->pfd); if ((pollset->flags & APR_POLLSET_WAKEABLE) && fd.desc_type == APR_POLL_FILE && fd.desc.f == pollset->wakeup_pipe[0]) { - drain_wakeup_pipe(pollset); + apr_pollset_drain_wakeup_pipe(pollset); rv = APR_EINTR; } else { - pollset->result_set[j] = fd; - pollset->result_set[j].rtnevents = - get_kqueue_revent(pollset->ke_set[i].filter, - pollset->ke_set[i].flags); + pollset->p->result_set[j] = fd; + pollset->p->result_set[j].rtnevents = + get_kqueue_revent(pollset->p->ke_set[i].filter, + pollset->p->ke_set[i].flags); j++; } } if ((*num = j)) rv = APR_SUCCESS; if (descriptors) { - *descriptors = pollset->result_set; + *descriptors = pollset->p->result_set; } } @@ -347,61 +274,54 @@ APR_DECLARE(apr_status_t) apr_pollset_poll(apr_pollset_t *pollset, pollset_lock_rings(); /* Shift all PFDs in the Dead Ring to be Free Ring */ - APR_RING_CONCAT(&(pollset->free_ring), &(pollset->dead_ring), pfd_elem_t, link); + APR_RING_CONCAT(&(pollset->p->free_ring), &(pollset->p->dead_ring), + pfd_elem_t, link); pollset_unlock_rings(); return rv; } -APR_DECLARE(apr_status_t) apr_pollset_wakeup(apr_pollset_t *pollset) -{ - if (pollset->flags & APR_POLLSET_WAKEABLE) - return apr_file_putc(1, pollset->wakeup_pipe[1]); - else - return APR_EINIT; -} - -struct apr_pollcb_t { - apr_pool_t *pool; - apr_uint32_t nalloc; - struct kevent *pollset; - int kqfd; +static apr_pollset_provider_t impl = { + impl_pollset_create, + impl_pollset_add, + impl_pollset_remove, + impl_pollset_poll, + impl_pollset_cleanup, + "kqueue" }; +apr_pollset_provider_t *apr_pollset_provider_kqueue = &impl; + static apr_status_t cb_cleanup(void *b_) { apr_pollcb_t *pollcb = (apr_pollcb_t *) b_; - close(pollcb->kqfd); + close(pollcb->fd); return APR_SUCCESS; } -APR_DECLARE(apr_status_t) apr_pollcb_create(apr_pollcb_t **pollcb, - apr_uint32_t size, - apr_pool_t *p, - apr_uint32_t flags) +static apr_status_t impl_pollcb_create(apr_pollcb_t *pollcb, + apr_uint32_t size, + apr_pool_t *p, + apr_uint32_t flags) { int fd; fd = kqueue(); if (fd < 0) { - *pollcb = NULL; return apr_get_netos_error(); } - *pollcb = apr_palloc(p, sizeof(**pollcb)); - (*pollcb)->nalloc = size; - (*pollcb)->pool = p; - (*pollcb)->kqfd = fd; - (*pollcb)->pollset = (struct kevent *)apr_pcalloc(p, size * sizeof(struct kevent)); - apr_pool_cleanup_register(p, *pollcb, cb_cleanup, cb_cleanup); + pollcb->fd = fd; + pollcb->pollset.ke = (struct kevent *)apr_pcalloc(p, size * sizeof(struct kevent)); + apr_pool_cleanup_register(p, pollcb, cb_cleanup, cb_cleanup); return APR_SUCCESS; } -APR_DECLARE(apr_status_t) apr_pollcb_add(apr_pollcb_t *pollcb, - apr_pollfd_t *descriptor) +static apr_status_t impl_pollcb_add(apr_pollcb_t *pollcb, + apr_pollfd_t *descriptor) { apr_os_sock_t fd; struct kevent ev; @@ -417,7 +337,7 @@ APR_DECLARE(apr_status_t) apr_pollcb_add(apr_pollcb_t *pollcb, if (descriptor->reqevents & APR_POLLIN) { EV_SET(&ev, fd, EVFILT_READ, EV_ADD, 0, 0, descriptor); - if (kevent(pollcb->kqfd, &ev, 1, NULL, 0, NULL) == -1) { + if (kevent(pollcb->fd, &ev, 1, NULL, 0, NULL) == -1) { rv = apr_get_netos_error(); } } @@ -425,7 +345,7 @@ APR_DECLARE(apr_status_t) apr_pollcb_add(apr_pollcb_t *pollcb, if (descriptor->reqevents & APR_POLLOUT && rv == APR_SUCCESS) { EV_SET(&ev, fd, EVFILT_WRITE, EV_ADD, 0, 0, descriptor); - if (kevent(pollcb->kqfd, &ev, 1, NULL, 0, NULL) == -1) { + if (kevent(pollcb->fd, &ev, 1, NULL, 0, NULL) == -1) { rv = apr_get_netos_error(); } } @@ -433,8 +353,8 @@ APR_DECLARE(apr_status_t) apr_pollcb_add(apr_pollcb_t *pollcb, return rv; } -APR_DECLARE(apr_status_t) apr_pollcb_remove(apr_pollcb_t *pollcb, - apr_pollfd_t *descriptor) +static apr_status_t impl_pollcb_remove(apr_pollcb_t *pollcb, + apr_pollfd_t *descriptor) { apr_status_t rv = APR_SUCCESS; struct kevent ev; @@ -450,7 +370,7 @@ APR_DECLARE(apr_status_t) apr_pollcb_remove(apr_pollcb_t *pollcb, if (descriptor->reqevents & APR_POLLIN) { EV_SET(&ev, fd, EVFILT_READ, EV_DELETE, 0, 0, NULL); - if (kevent(pollcb->kqfd, &ev, 1, NULL, 0, NULL) == -1) { + if (kevent(pollcb->fd, &ev, 1, NULL, 0, NULL) == -1) { rv = APR_NOTFOUND; } } @@ -461,7 +381,7 @@ APR_DECLARE(apr_status_t) apr_pollcb_remove(apr_pollcb_t *pollcb, */ EV_SET(&ev, fd, EVFILT_WRITE, EV_DELETE, 0, 0, NULL); - if (kevent(pollcb->kqfd, &ev, 1, NULL, 0, NULL) == -1) { + if (kevent(pollcb->fd, &ev, 1, NULL, 0, NULL) == -1) { rv = APR_NOTFOUND; } } @@ -470,10 +390,10 @@ APR_DECLARE(apr_status_t) apr_pollcb_remove(apr_pollcb_t *pollcb, } -APR_DECLARE(apr_status_t) apr_pollcb_poll(apr_pollcb_t *pollcb, - apr_interval_time_t timeout, - apr_pollcb_cb_t func, - void *baton) +static apr_status_t impl_pollcb_poll(apr_pollcb_t *pollcb, + apr_interval_time_t timeout, + apr_pollcb_cb_t func, + void *baton) { int ret, i; struct timespec tv, *tvptr; @@ -488,7 +408,7 @@ APR_DECLARE(apr_status_t) apr_pollcb_poll(apr_pollcb_t *pollcb, tvptr = &tv; } - ret = kevent(pollcb->kqfd, NULL, 0, pollcb->pollset, pollcb->nalloc, + ret = kevent(pollcb->fd, NULL, 0, pollcb->pollset.ke, pollcb->nalloc, tvptr); if (ret < 0) { @@ -499,10 +419,10 @@ APR_DECLARE(apr_status_t) apr_pollcb_poll(apr_pollcb_t *pollcb, } else { for (i = 0; i < ret; i++) { - apr_pollfd_t *pollfd = (apr_pollfd_t *)(pollcb->pollset[i].udata); + apr_pollfd_t *pollfd = (apr_pollfd_t *)(pollcb->pollset.ke[i].udata); - pollfd->rtnevents = get_kqueue_revent(pollcb->pollset[i].filter, - pollcb->pollset[i].flags); + pollfd->rtnevents = get_kqueue_revent(pollcb->pollset.ke[i].filter, + pollcb->pollset.ke[i].flags); rv = func(baton, pollfd); @@ -515,4 +435,14 @@ APR_DECLARE(apr_status_t) apr_pollcb_poll(apr_pollcb_t *pollcb, return rv; } -#endif /* POLLSET_USES_KQUEUE */ +static apr_pollcb_provider_t impl_cb = { + impl_pollcb_create, + impl_pollcb_add, + impl_pollcb_remove, + impl_pollcb_poll, + "kqueue" +}; + +apr_pollcb_provider_t *apr_pollcb_provider_kqueue = &impl_cb; + +#endif /* HAVE_KQUEUE */ diff --git a/poll/unix/poll.c b/poll/unix/poll.c index 29a5f6655..ed0173f59 100644 --- a/poll/unix/poll.c +++ b/poll/unix/poll.c @@ -14,9 +14,16 @@ * limitations under the License. */ +#include "apr.h" +#include "apr_poll.h" +#include "apr_time.h" +#include "apr_portable.h" +#include "apr_arch_file_io.h" +#include "apr_arch_networkio.h" +#include "apr_arch_misc.h" #include "apr_arch_poll_private.h" -#if defined(POLL_USES_POLL) || defined(POLLSET_USES_POLL) +#if defined(HAVE_POLL) #ifdef HAVE_ALLOCA_H #include <alloca.h> @@ -62,9 +69,6 @@ static apr_int16_t get_revent(apr_int16_t event) return rv; } -#endif /* POLL_USES_POLL || POLLSET_USES_POLL */ - - #ifdef POLL_USES_POLL #define SMALL_POLLSET_LIMIT 8 @@ -148,163 +152,70 @@ APR_DECLARE(apr_status_t) apr_poll(apr_pollfd_t *aprset, apr_int32_t num, #endif /* POLL_USES_POLL */ - -#ifdef POLLSET_USES_POLL - -struct apr_pollset_t +struct apr_pollset_private_t { - apr_pool_t *pool; - apr_uint32_t nelts; - apr_uint32_t nalloc; - apr_uint32_t flags; - /* Pipe descriptors used for wakeup */ - apr_file_t *wakeup_pipe[2]; struct pollfd *pollset; apr_pollfd_t *query_set; apr_pollfd_t *result_set; }; -/* Create a dummy wakeup pipe for interrupting the poller - */ -static apr_status_t create_wakeup_pipe(apr_pollset_t *pollset) -{ - apr_status_t rv; - apr_pollfd_t fd; - - if ((rv = apr_file_pipe_create(&pollset->wakeup_pipe[0], - &pollset->wakeup_pipe[1], - pollset->pool)) != APR_SUCCESS) - return rv; - fd.reqevents = APR_POLLIN; - fd.desc_type = APR_POLL_FILE; - fd.desc.f = pollset->wakeup_pipe[0]; - /* Add the pipe to the pollset - */ - return apr_pollset_add(pollset, &fd); -} - -/* Read and discard what's ever in the wakeup pipe. - */ -static void drain_wakeup_pipe(apr_pollset_t *pollset) -{ - char rb[512]; - apr_size_t nr = sizeof(rb); - - while (apr_file_read(pollset->wakeup_pipe[0], rb, &nr) == APR_SUCCESS) { - /* Although we write just one byte to the other end of the pipe - * during wakeup, multiple treads could call the wakeup. - * So simply drain out from the input side of the pipe all - * the data. - */ - if (nr != sizeof(rb)) - break; - } -} - -static apr_status_t wakeup_pipe_cleanup(void *p) -{ - apr_pollset_t *pollset = (apr_pollset_t *) p; - if (pollset->flags & APR_POLLSET_WAKEABLE) { - /* Close both sides of the wakeup pipe */ - if (pollset->wakeup_pipe[0]) { - apr_file_close(pollset->wakeup_pipe[0]); - pollset->wakeup_pipe[0] = NULL; - } - if (pollset->wakeup_pipe[1]) { - apr_file_close(pollset->wakeup_pipe[1]); - pollset->wakeup_pipe[1] = NULL; - } - } - - return APR_SUCCESS; -} - -APR_DECLARE(apr_status_t) apr_pollset_create(apr_pollset_t **pollset, - apr_uint32_t size, - apr_pool_t *p, - apr_uint32_t flags) +static apr_status_t impl_pollset_create(apr_pollset_t *pollset, + apr_uint32_t size, + apr_pool_t *p, + apr_uint32_t flags) { if (flags & APR_POLLSET_THREADSAFE) { - *pollset = NULL; return APR_ENOTIMPL; } - if (flags & APR_POLLSET_WAKEABLE) { - /* Add room for wakeup descriptor */ - size++; - } + pollset->p = apr_palloc(p, sizeof(apr_pollset_private_t)); + pollset->p->pollset = apr_palloc(p, size * sizeof(struct pollfd)); + pollset->p->query_set = apr_palloc(p, size * sizeof(apr_pollfd_t)); + pollset->p->result_set = apr_palloc(p, size * sizeof(apr_pollfd_t)); - *pollset = apr_palloc(p, sizeof(**pollset)); - (*pollset)->nelts = 0; - (*pollset)->nalloc = size; - (*pollset)->pool = p; - (*pollset)->flags = flags; - (*pollset)->pollset = apr_palloc(p, size * sizeof(struct pollfd)); - (*pollset)->query_set = apr_palloc(p, size * sizeof(apr_pollfd_t)); - (*pollset)->result_set = apr_palloc(p, size * sizeof(apr_pollfd_t)); - - if (flags & APR_POLLSET_WAKEABLE) { - apr_status_t rv; - /* Create wakeup pipe */ - if ((rv = create_wakeup_pipe(*pollset)) != APR_SUCCESS) { - *pollset = NULL; - return rv; - } - apr_pool_cleanup_register(p, *pollset, wakeup_pipe_cleanup, - apr_pool_cleanup_null); - } return APR_SUCCESS; } -APR_DECLARE(apr_status_t) apr_pollset_destroy(apr_pollset_t *pollset) -{ - if (pollset->flags & APR_POLLSET_WAKEABLE) - return apr_pool_cleanup_run(pollset->pool, pollset, - wakeup_pipe_cleanup); - else - return APR_SUCCESS; -} - -APR_DECLARE(apr_status_t) apr_pollset_add(apr_pollset_t *pollset, - const apr_pollfd_t *descriptor) +static apr_status_t impl_pollset_add(apr_pollset_t *pollset, + const apr_pollfd_t *descriptor) { if (pollset->nelts == pollset->nalloc) { return APR_ENOMEM; } - pollset->query_set[pollset->nelts] = *descriptor; + pollset->p->query_set[pollset->nelts] = *descriptor; if (descriptor->desc_type == APR_POLL_SOCKET) { - pollset->pollset[pollset->nelts].fd = descriptor->desc.s->socketdes; + pollset->p->pollset[pollset->nelts].fd = descriptor->desc.s->socketdes; } else { - pollset->pollset[pollset->nelts].fd = descriptor->desc.f->filedes; + pollset->p->pollset[pollset->nelts].fd = descriptor->desc.f->filedes; } - pollset->pollset[pollset->nelts].events = + pollset->p->pollset[pollset->nelts].events = get_event(descriptor->reqevents); pollset->nelts++; return APR_SUCCESS; } -APR_DECLARE(apr_status_t) apr_pollset_remove(apr_pollset_t *pollset, - const apr_pollfd_t *descriptor) +static apr_status_t impl_pollset_remove(apr_pollset_t *pollset, + const apr_pollfd_t *descriptor) { apr_uint32_t i; for (i = 0; i < pollset->nelts; i++) { - if (descriptor->desc.s == pollset->query_set[i].desc.s) { + if (descriptor->desc.s == pollset->p->query_set[i].desc.s) { /* Found an instance of the fd: remove this and any other copies */ apr_uint32_t dst = i; apr_uint32_t old_nelts = pollset->nelts; pollset->nelts--; for (i++; i < old_nelts; i++) { - if (descriptor->desc.s == pollset->query_set[i].desc.s) { + if (descriptor->desc.s == pollset->p->query_set[i].desc.s) { pollset->nelts--; } else { - pollset->pollset[dst] = pollset->pollset[i]; - pollset->query_set[dst] = pollset->query_set[i]; + pollset->p->pollset[dst] = pollset->p->pollset[i]; + pollset->p->query_set[dst] = pollset->p->query_set[i]; dst++; } } @@ -315,10 +226,10 @@ APR_DECLARE(apr_status_t) apr_pollset_remove(apr_pollset_t *pollset, return APR_NOTFOUND; } -APR_DECLARE(apr_status_t) apr_pollset_poll(apr_pollset_t *pollset, - apr_interval_time_t timeout, - apr_int32_t *num, - const apr_pollfd_t **descriptors) +static apr_status_t impl_pollset_poll(apr_pollset_t *pollset, + apr_interval_time_t timeout, + apr_int32_t *num, + const apr_pollfd_t **descriptors) { int ret; apr_status_t rv = APR_SUCCESS; @@ -327,7 +238,7 @@ APR_DECLARE(apr_status_t) apr_pollset_poll(apr_pollset_t *pollset, if (timeout > 0) { timeout /= 1000; } - ret = poll(pollset->pollset, pollset->nelts, timeout); + ret = poll(pollset->p->pollset, pollset->nelts, timeout); (*num) = ret; if (ret < 0) { return apr_get_netos_error(); @@ -337,20 +248,20 @@ APR_DECLARE(apr_status_t) apr_pollset_poll(apr_pollset_t *pollset, } else { for (i = 0, j = 0; i < pollset->nelts; i++) { - if (pollset->pollset[i].revents != 0) { + if (pollset->p->pollset[i].revents != 0) { /* Check if the polled descriptor is our * wakeup pipe. In that case do not put it result set. */ if ((pollset->flags & APR_POLLSET_WAKEABLE) && - pollset->query_set[i].desc_type == APR_POLL_FILE && - pollset->query_set[i].desc.f == pollset->wakeup_pipe[0]) { - drain_wakeup_pipe(pollset); + pollset->p->query_set[i].desc_type == APR_POLL_FILE && + pollset->p->query_set[i].desc.f == pollset->wakeup_pipe[0]) { + apr_pollset_drain_wakeup_pipe(pollset); rv = APR_EINTR; } else { - pollset->result_set[j] = pollset->query_set[i]; - pollset->result_set[j].rtnevents = - get_revent(pollset->pollset[i].revents); + pollset->p->result_set[j] = pollset->p->query_set[i]; + pollset->p->result_set[j].rtnevents = + get_revent(pollset->p->pollset[i].revents); j++; } } @@ -359,45 +270,134 @@ APR_DECLARE(apr_status_t) apr_pollset_poll(apr_pollset_t *pollset, rv = APR_SUCCESS; } if (descriptors && (*num)) - *descriptors = pollset->result_set; + *descriptors = pollset->p->result_set; return rv; } -APR_DECLARE(apr_status_t) apr_pollset_wakeup(apr_pollset_t *pollset) +static apr_pollset_provider_t impl = { + impl_pollset_create, + impl_pollset_add, + impl_pollset_remove, + impl_pollset_poll, + NULL, + "pool" +}; + +apr_pollset_provider_t *apr_pollset_provider_poll = &impl; + +/* Poll method pollcb. + * This is probably usable only for WIN32 having WSAPoll + */ +static apr_status_t impl_pollcb_create(apr_pollcb_t *pollcb, + apr_uint32_t size, + apr_pool_t *p, + apr_uint32_t flags) { - if (pollset->flags & APR_POLLSET_WAKEABLE) - return apr_file_putc(1, pollset->wakeup_pipe[1]); - else - return APR_EINIT; + pollcb->fd = -1; + pollcb->pollset.ps = apr_palloc(p, size * sizeof(struct pollfd)); + pollcb->copyset = apr_palloc(p, size * sizeof(apr_pollfd_t *)); + + return APR_SUCCESS; } -APR_DECLARE(apr_status_t) apr_pollcb_create(apr_pollcb_t **pollcb, - apr_uint32_t size, - apr_pool_t *p, - apr_uint32_t flags) +static apr_status_t impl_pollcb_add(apr_pollcb_t *pollcb, + apr_pollfd_t *descriptor) { - return APR_ENOTIMPL; + if (pollcb->nelts == pollcb->nalloc) { + return APR_ENOMEM; + } + + if (descriptor->desc_type == APR_POLL_SOCKET) { + pollcb->pollset.ps[pollcb->nelts].fd = descriptor->desc.s->socketdes; + } + else { + pollcb->pollset.ps[pollcb->nelts].fd = descriptor->desc.f->filedes; + } + + pollcb->pollset.ps[pollcb->nelts].events = + get_event(descriptor->reqevents); + pollcb->copyset[pollcb->nelts] = descriptor; + pollcb->nelts++; + + return APR_SUCCESS; } -APR_DECLARE(apr_status_t) apr_pollcb_add(apr_pollcb_t *pollcb, - apr_pollfd_t *descriptor) +static apr_status_t impl_pollcb_remove(apr_pollcb_t *pollcb, + apr_pollfd_t *descriptor) { - return APR_ENOTIMPL; + int fd; + apr_uint32_t i; + + if (descriptor->desc_type == APR_POLL_SOCKET) + fd = descriptor->desc.s->socketdes; + else + fd = descriptor->desc.f->filedes; + + for (i = 0; i < pollcb->nelts; i++) { + if (descriptor->desc.s == pollcb->copyset[i]->desc.s) { + /* Found an instance of the fd: remove this and any other copies */ + apr_uint32_t dst = i; + apr_uint32_t old_nelts = pollcb->nelts; + pollcb->nelts--; + for (i++; i < old_nelts; i++) { + if (descriptor->desc.s == pollcb->copyset[i]->desc.s) { + pollcb->nelts--; + } + else { + pollcb->pollset.ps[dst] = pollcb->pollset.ps[i]; + pollcb->copyset[dst] = pollcb->copyset[i]; + dst++; + } + } + return APR_SUCCESS; + } + } + + return APR_NOTFOUND; } -APR_DECLARE(apr_status_t) apr_pollcb_remove(apr_pollcb_t *pollcb, - apr_pollfd_t *descriptor) +static apr_status_t impl_pollcb_poll(apr_pollcb_t *pollcb, + apr_interval_time_t timeout, + apr_pollcb_cb_t func, + void *baton) { - return APR_ENOTIMPL; + int ret; + apr_status_t rv = APR_SUCCESS; + apr_uint32_t i, j; + + if (timeout > 0) { + timeout /= 1000; + } + ret = poll(pollcb->pollset.ps, pollcb->nelts, timeout); + if (ret < 0) { + return apr_get_netos_error(); + } + else if (ret == 0) { + return APR_TIMEUP; + } + else { + for (i = 0; i < pollcb->nelts; i++) { + if (pollcb->pollset.ps[i].revents != 0) { + apr_pollfd_t *pollfd = pollcb->copyset[i]; + pollfd->rtnevents = get_revent(pollcb->pollset.ps[i].revents); + rv = func(baton, pollfd); + if (rv) { + return rv; + } + } + } + } + return rv; } +static apr_pollcb_provider_t impl_cb = { + impl_pollcb_create, + impl_pollcb_add, + impl_pollcb_remove, + impl_pollcb_poll, + "poll" +}; -APR_DECLARE(apr_status_t) apr_pollcb_poll(apr_pollcb_t *pollcb, - apr_interval_time_t timeout, - apr_pollcb_cb_t func, - void *baton) -{ - return APR_ENOTIMPL; -} +apr_pollcb_provider_t *apr_pollcb_provider_poll = &impl_cb; -#endif /* POLLSET_USES_POLL */ +#endif /* HAVE_POLL */ diff --git a/poll/unix/port.c b/poll/unix/port.c index 73d852511..b1149f216 100644 --- a/poll/unix/port.c +++ b/poll/unix/port.c @@ -14,10 +14,16 @@ * limitations under the License. */ -#include "apr_arch_poll_private.h" +#include "apr.h" +#include "apr_poll.h" +#include "apr_time.h" +#include "apr_portable.h" #include "apr_atomic.h" +#include "apr_arch_file_io.h" +#include "apr_arch_networkio.h" +#include "apr_arch_poll_private.h" -#ifdef POLLSET_USES_PORT +#if defined(HAVE_PORT_CREATE) static apr_int16_t get_event(apr_int16_t event) { @@ -60,17 +66,11 @@ static apr_int16_t get_revent(apr_int16_t event) } -struct apr_pollset_t +struct apr_pollset_private_t { - apr_pool_t *pool; - apr_uint32_t nelts; - apr_uint32_t nalloc; int port_fd; port_event_t *port_set; apr_pollfd_t *result_set; - apr_uint32_t flags; - /* Pipe descriptors used for wakeup */ - apr_file_t *wakeup_pipe[2]; #if APR_HAS_THREADS /* A thread mutex to protect operations on the rings */ apr_thread_mutex_t *ring_lock; @@ -87,79 +87,30 @@ struct apr_pollset_t volatile apr_uint32_t waiting; }; -static apr_status_t backend_cleanup(void *p_) +static apr_status_t impl_pollset_cleanup(apr_pollset_t *pollset) { - apr_pollset_t *pollset = (apr_pollset_t *) p_; - close(pollset->port_fd); - if (pollset->flags & APR_POLLSET_WAKEABLE) { - /* Close both sides of the wakeup pipe */ - if (pollset->wakeup_pipe[0]) { - apr_file_close(pollset->wakeup_pipe[0]); - pollset->wakeup_pipe[0] = NULL; - } - if (pollset->wakeup_pipe[1]) { - apr_file_close(pollset->wakeup_pipe[1]); - pollset->wakeup_pipe[1] = NULL; - } - } + close(pollset->p->port_fd); return APR_SUCCESS; } -/* Create a dummy wakeup pipe for interrupting the poller - */ -static apr_status_t create_wakeup_pipe(apr_pollset_t *pollset) -{ - apr_status_t rv; - apr_pollfd_t fd; - - if ((rv = apr_file_pipe_create(&pollset->wakeup_pipe[0], - &pollset->wakeup_pipe[1], - pollset->pool)) != APR_SUCCESS) - return rv; - fd.reqevents = APR_POLLIN; - fd.desc_type = APR_POLL_FILE; - fd.desc.f = pollset->wakeup_pipe[0]; - /* Add the pipe to the pollset - */ - return apr_pollset_add(pollset, &fd); -} - -/* Read and discard what's ever in the wakeup pipe. - */ -static void drain_wakeup_pipe(apr_pollset_t *pollset) -{ - char rb[512]; - apr_size_t nr = sizeof(rb); - - while (apr_file_read(pollset->wakeup_pipe[0], rb, &nr) == APR_SUCCESS) { - /* Although we write just one byte to the other end of the pipe - * during wakeup, multiple treads could call the wakeup. - * So simply drain out from the input side of the pipe all - * the data. - */ - if (nr != sizeof(rb)) - break; - } -} - -APR_DECLARE(apr_status_t) apr_pollset_create(apr_pollset_t **pollset, +static apr_status_t impl_pollset_create(apr_pollset_t **pollset, apr_uint32_t size, apr_pool_t *p, apr_uint32_t flags) { apr_status_t rv = APR_SUCCESS; - *pollset = apr_palloc(p, sizeof(**pollset)); + pollset->p = apr_palloc(p, sizeof(apr_pollset_private_t)); #if APR_HAS_THREADS if (flags & APR_POLLSET_THREADSAFE && - ((rv = apr_thread_mutex_create(&(*pollset)->ring_lock, + ((rv = apr_thread_mutex_create(&pollset->p->ring_lock, APR_THREAD_MUTEX_DEFAULT, p)) != APR_SUCCESS)) { - *pollset = NULL; + pollset->p = NULL; return rv; } #else if (flags & APR_POLLSET_THREADSAFE) { - *pollset = NULL; + pollset->p = NULL; return APR_ENOTIMPL; } #endif @@ -167,48 +118,29 @@ APR_DECLARE(apr_status_t) apr_pollset_create(apr_pollset_t **pollset, /* Add room for wakeup descriptor */ size++; } - (*pollset)->waiting = 0; - (*pollset)->nelts = 0; - (*pollset)->nalloc = size; - (*pollset)->flags = flags; - (*pollset)->pool = p; + pollset->p->waiting = 0; - (*pollset)->port_set = apr_palloc(p, size * sizeof(port_event_t)); + pollset->p->port_set = apr_palloc(p, size * sizeof(port_event_t)); - (*pollset)->port_fd = port_create(); + pollset->p->port_fd = port_create(); - if ((*pollset)->port_fd < 0) { + if (pollset->p->port_fd < 0) { + pollset->p = NULL; return APR_ENOMEM; } - (*pollset)->result_set = apr_palloc(p, size * sizeof(apr_pollfd_t)); + pollset->p->result_set = apr_palloc(p, size * sizeof(apr_pollfd_t)); - APR_RING_INIT(&(*pollset)->query_ring, pfd_elem_t, link); - APR_RING_INIT(&(*pollset)->add_ring, pfd_elem_t, link); - APR_RING_INIT(&(*pollset)->free_ring, pfd_elem_t, link); - APR_RING_INIT(&(*pollset)->dead_ring, pfd_elem_t, link); - - if (flags & APR_POLLSET_WAKEABLE) { - /* Create wakeup pipe */ - if ((rv = create_wakeup_pipe(*pollset)) != APR_SUCCESS) { - close((*pollset)->port_fd); - *pollset = NULL; - return rv; - } - } - apr_pool_cleanup_register(p, (void *) (*pollset), backend_cleanup, - apr_pool_cleanup_null); + APR_RING_INIT(&pollset->p->query_ring, pfd_elem_t, link); + APR_RING_INIT(&pollset->p->add_ring, pfd_elem_t, link); + APR_RING_INIT(&pollset->p->free_ring, pfd_elem_t, link); + APR_RING_INIT(&pollset->p->dead_ring, pfd_elem_t, link); return rv; } -APR_DECLARE(apr_status_t) apr_pollset_destroy(apr_pollset_t *pollset) -{ - return apr_pool_cleanup_run(pollset->pool, pollset, backend_cleanup); -} - -APR_DECLARE(apr_status_t) apr_pollset_add(apr_pollset_t *pollset, - const apr_pollfd_t *descriptor) +static apr_status_t impl_pollset_add(apr_pollset_t *pollset, + const apr_pollfd_t *descriptor) { apr_os_sock_t fd; pfd_elem_t *elem; @@ -217,8 +149,8 @@ APR_DECLARE(apr_status_t) apr_pollset_add(apr_pollset_t *pollset, pollset_lock_rings(); - if (!APR_RING_EMPTY(&(pollset->free_ring), pfd_elem_t, link)) { - elem = APR_RING_FIRST(&(pollset->free_ring)); + if (!APR_RING_EMPTY(&(pollset->p->free_ring), pfd_elem_t, link)) { + elem = APR_RING_FIRST(&(pollset->p->free_ring)); APR_RING_REMOVE(elem, link); } else { @@ -234,22 +166,22 @@ APR_DECLARE(apr_status_t) apr_pollset_add(apr_pollset_t *pollset, fd = descriptor->desc.f->filedes; } - if (apr_atomic_read32(&pollset->waiting)) { - res = port_associate(pollset->port_fd, PORT_SOURCE_FD, fd, + if (apr_atomic_read32(&pollset->p->waiting)) { + res = port_associate(pollset->p->port_fd, PORT_SOURCE_FD, fd, get_event(descriptor->reqevents), (void *)elem); if (res < 0) { rv = APR_ENOMEM; - APR_RING_INSERT_TAIL(&(pollset->free_ring), elem, pfd_elem_t, link); + APR_RING_INSERT_TAIL(&(pollset->p->free_ring), elem, pfd_elem_t, link); } else { pollset->nelts++; - APR_RING_INSERT_TAIL(&(pollset->query_ring), elem, pfd_elem_t, link); + APR_RING_INSERT_TAIL(&(pollset->p->query_ring), elem, pfd_elem_t, link); } } else { pollset->nelts++; - APR_RING_INSERT_TAIL(&(pollset->add_ring), elem, pfd_elem_t, link); + APR_RING_INSERT_TAIL(&(pollset->p->add_ring), elem, pfd_elem_t, link); } pollset_unlock_rings(); @@ -257,8 +189,8 @@ APR_DECLARE(apr_status_t) apr_pollset_add(apr_pollset_t *pollset, return rv; } -APR_DECLARE(apr_status_t) apr_pollset_remove(apr_pollset_t *pollset, - const apr_pollfd_t *descriptor) +static apr_status_t impl_pollset_remove(apr_pollset_t *pollset, + const apr_pollfd_t *descriptor) { apr_os_sock_t fd; pfd_elem_t *ep; @@ -275,22 +207,22 @@ APR_DECLARE(apr_status_t) apr_pollset_remove(apr_pollset_t *pollset, fd = descriptor->desc.f->filedes; } - res = port_dissociate(pollset->port_fd, PORT_SOURCE_FD, fd); + res = port_dissociate(pollset->p->port_fd, PORT_SOURCE_FD, fd); if (res < 0) { err = errno; rv = APR_NOTFOUND; } - if (!APR_RING_EMPTY(&(pollset->query_ring), pfd_elem_t, link)) { - for (ep = APR_RING_FIRST(&(pollset->query_ring)); - ep != APR_RING_SENTINEL(&(pollset->query_ring), + if (!APR_RING_EMPTY(&(pollset->p->query_ring), pfd_elem_t, link)) { + for (ep = APR_RING_FIRST(&(pollset->p->query_ring)); + ep != APR_RING_SENTINEL(&(pollset->p->query_ring), pfd_elem_t, link); ep = APR_RING_NEXT(ep, link)) { if (descriptor->desc.s == ep->pfd.desc.s) { APR_RING_REMOVE(ep, link); - APR_RING_INSERT_TAIL(&(pollset->dead_ring), + APR_RING_INSERT_TAIL(&(pollset->p->dead_ring), ep, pfd_elem_t, link); if (ENOENT == err) { rv = APR_SUCCESS; @@ -300,15 +232,15 @@ APR_DECLARE(apr_status_t) apr_pollset_remove(apr_pollset_t *pollset, } } - if (!APR_RING_EMPTY(&(pollset->add_ring), pfd_elem_t, link)) { - for (ep = APR_RING_FIRST(&(pollset->add_ring)); - ep != APR_RING_SENTINEL(&(pollset->add_ring), + if (!APR_RING_EMPTY(&(pollset->p->add_ring), pfd_elem_t, link)) { + for (ep = APR_RING_FIRST(&(pollset->p->add_ring)); + ep != APR_RING_SENTINEL(&(pollset->p->add_ring), pfd_elem_t, link); ep = APR_RING_NEXT(ep, link)) { if (descriptor->desc.s == ep->pfd.desc.s) { APR_RING_REMOVE(ep, link); - APR_RING_INSERT_TAIL(&(pollset->dead_ring), + APR_RING_INSERT_TAIL(&(pollset->p->dead_ring), ep, pfd_elem_t, link); if (ENOENT == err) { rv = APR_SUCCESS; @@ -323,10 +255,10 @@ APR_DECLARE(apr_status_t) apr_pollset_remove(apr_pollset_t *pollset, return rv; } -APR_DECLARE(apr_status_t) apr_pollset_poll(apr_pollset_t *pollset, - apr_interval_time_t timeout, - apr_int32_t *num, - const apr_pollfd_t **descriptors) +static apr_status_t impl_pollset_poll(apr_pollset_t *pollset, + apr_interval_time_t timeout, + apr_int32_t *num, + const apr_pollfd_t **descriptors) { apr_os_sock_t fd; int ret, i, j; @@ -349,10 +281,10 @@ APR_DECLARE(apr_status_t) apr_pollset_poll(apr_pollset_t *pollset, pollset_lock_rings(); - apr_atomic_inc32(&pollset->waiting); + apr_atomic_inc32(&pollset->p->waiting); - while (!APR_RING_EMPTY(&(pollset->add_ring), pfd_elem_t, link)) { - ep = APR_RING_FIRST(&(pollset->add_ring)); + while (!APR_RING_EMPTY(&(pollset->p->add_ring), pfd_elem_t, link)) { + ep = APR_RING_FIRST(&(pollset->p->add_ring)); APR_RING_REMOVE(ep, link); if (ep->pfd.desc_type == APR_POLL_SOCKET) { @@ -362,21 +294,21 @@ APR_DECLARE(apr_status_t) apr_pollset_poll(apr_pollset_t *pollset, fd = ep->pfd.desc.f->filedes; } - port_associate(pollset->port_fd, PORT_SOURCE_FD, + port_associate(pollset->p->port_fd, PORT_SOURCE_FD, fd, get_event(ep->pfd.reqevents), ep); - APR_RING_INSERT_TAIL(&(pollset->query_ring), ep, pfd_elem_t, link); + APR_RING_INSERT_TAIL(&(pollset->p->query_ring), ep, pfd_elem_t, link); } pollset_unlock_rings(); - ret = port_getn(pollset->port_fd, pollset->port_set, pollset->nalloc, + ret = port_getn(pollset->p->port_fd, pollset->p->port_set, pollset->nalloc, &nget, tvptr); /* decrease the waiting ASAP to reduce the window for calling port_associate within apr_pollset_add() */ - apr_atomic_dec32(&pollset->waiting); + apr_atomic_dec32(&pollset->p->waiting); (*num) = nget; if (ret == -1) { @@ -399,22 +331,22 @@ APR_DECLARE(apr_status_t) apr_pollset_poll(apr_pollset_t *pollset, pollset_lock_rings(); for (i = 0, j = 0; i < nget; i++) { - fp = (((pfd_elem_t*)(pollset->port_set[i].portev_user))->pfd); + fp = (((pfd_elem_t*)(pollset->p->port_set[i].portev_user))->pfd); if ((pollset->flags & APR_POLLSET_WAKEABLE) && fp.desc_type == APR_POLL_FILE && fp.desc.f == pollset->wakeup_pipe[0]) { - drain_wakeup_pipe(pollset); + apr_pollset_drain_wakeup_pipe(pollset); rv = APR_EINTR; } else { - pollset->result_set[j] = fp; - pollset->result_set[j].rtnevents = - get_revent(pollset->port_set[i].portev_events); + pollset->p->result_set[j] = fp; + pollset->p->result_set[j].rtnevents = + get_revent(pollset->p->port_set[i].portev_events); - APR_RING_REMOVE((pfd_elem_t*)pollset->port_set[i].portev_user, + APR_RING_REMOVE((pfd_elem_t*)pollset->p->port_set[i].portev_user, link); - APR_RING_INSERT_TAIL(&(pollset->add_ring), - (pfd_elem_t*)pollset->port_set[i].portev_user, + APR_RING_INSERT_TAIL(&(pollset->p->add_ring), + (pfd_elem_t*)pollset->p->port_set[i].portev_user, pfd_elem_t, link); j++; } @@ -423,7 +355,7 @@ APR_DECLARE(apr_status_t) apr_pollset_poll(apr_pollset_t *pollset, if ((*num) = j) rv = APR_SUCCESS; if (descriptors) { - *descriptors = pollset->result_set; + *descriptors = pollset->p->result_set; } } @@ -431,61 +363,52 @@ APR_DECLARE(apr_status_t) apr_pollset_poll(apr_pollset_t *pollset, pollset_lock_rings(); /* Shift all PFDs in the Dead Ring to be Free Ring */ - APR_RING_CONCAT(&(pollset->free_ring), &(pollset->dead_ring), pfd_elem_t, link); + APR_RING_CONCAT(&(pollset->p->free_ring), &(pollset->p->dead_ring), pfd_elem_t, link); pollset_unlock_rings(); return rv; } -APR_DECLARE(apr_status_t) apr_pollset_wakeup(apr_pollset_t *pollset) -{ - if (pollset->flags & APR_POLLSET_WAKEABLE) - return apr_file_putc(1, pollset->wakeup_pipe[1]); - else - return APR_EINIT; -} - -struct apr_pollcb_t { - apr_pool_t *pool; - apr_uint32_t nalloc; - port_event_t *port_set; - int port_fd; +static apr_pollset_provider_t impl = { + impl_pollset_create, + impl_pollset_add, + impl_pollset_remove, + impl_pollset_poll, + impl_pollset_cleanup, + "port" }; +apr_pollset_provider_t *apr_pollset_provider_port = &impl; + static apr_status_t cb_cleanup(void *p_) { apr_pollcb_t *pollcb = (apr_pollcb_t *) p_; - close(pollcb->port_fd); + close(pollcb->fd); return APR_SUCCESS; } -APR_DECLARE(apr_status_t) apr_pollcb_create(apr_pollcb_t **pollcb, - apr_uint32_t size, - apr_pool_t *p, - apr_uint32_t flags) +static apr_status_t impl_pollcb_create(apr_pollcb_t *pollcb, + apr_uint32_t size, + apr_pool_t *p, + apr_uint32_t flags) { int fd; fd = port_create(); if (fd < 0) { - *pollcb = NULL; return apr_get_netos_error(); } - *pollcb = apr_palloc(p, sizeof(**pollcb)); - (*pollcb)->nalloc = size; - (*pollcb)->pool = p; - (*pollcb)->port_fd = fd; - (*pollcb)->port_set = apr_palloc(p, size * sizeof(port_event_t)); - apr_pool_cleanup_register(p, *pollcb, cb_cleanup, cb_cleanup); + pollcb->pollset.port = apr_palloc(p, size * sizeof(port_event_t)); + apr_pool_cleanup_register(p, pollcb, cb_cleanup, cb_cleanup); return APR_SUCCESS; } -APR_DECLARE(apr_status_t) apr_pollcb_add(apr_pollcb_t *pollcb, - apr_pollfd_t *descriptor) +static apr_status_t impl_pollcb_add(apr_pollcb_t *pollcb, + apr_pollfd_t *descriptor) { int ret, fd; @@ -496,7 +419,7 @@ APR_DECLARE(apr_status_t) apr_pollcb_add(apr_pollcb_t *pollcb, fd = descriptor->desc.f->filedes; } - ret = port_associate(pollcb->port_fd, PORT_SOURCE_FD, fd, + ret = port_associate(pollcb->fd, PORT_SOURCE_FD, fd, get_event(descriptor->reqevents), descriptor); if (ret == -1) { @@ -506,8 +429,8 @@ APR_DECLARE(apr_status_t) apr_pollcb_add(apr_pollcb_t *pollcb, return APR_SUCCESS; } -APR_DECLARE(apr_status_t) apr_pollcb_remove(apr_pollcb_t *pollcb, - apr_pollfd_t *descriptor) +static apr_status_t impl_pollcb_remove(apr_pollcb_t *pollcb, + apr_pollfd_t *descriptor) { int fd, ret; @@ -518,7 +441,7 @@ APR_DECLARE(apr_status_t) apr_pollcb_remove(apr_pollcb_t *pollcb, fd = descriptor->desc.f->filedes; } - ret = port_dissociate(pollcb->port_fd, PORT_SOURCE_FD, fd); + ret = port_dissociate(pollcb->fd, PORT_SOURCE_FD, fd); if (ret < 0) { return APR_NOTFOUND; @@ -527,10 +450,10 @@ APR_DECLARE(apr_status_t) apr_pollcb_remove(apr_pollcb_t *pollcb, return APR_SUCCESS; } -APR_DECLARE(apr_status_t) apr_pollcb_poll(apr_pollcb_t *pollcb, - apr_interval_time_t timeout, - apr_pollcb_cb_t func, - void *baton) +static apr_status_t impl_pollcb_poll(apr_pollcb_t *pollcb, + apr_interval_time_t timeout, + apr_pollcb_cb_t func, + void *baton) { int ret; apr_pollfd_t *pollfd; @@ -547,7 +470,7 @@ APR_DECLARE(apr_status_t) apr_pollcb_poll(apr_pollcb_t *pollcb, tvptr = &tv; } - ret = port_getn(pollcb->port_fd, pollcb->port_set, pollcb->nalloc, + ret = port_getn(pollcb->fd, pollcb->pollset.port, pollcb->nalloc, &nget, tvptr); if (ret == -1) { @@ -563,8 +486,8 @@ APR_DECLARE(apr_status_t) apr_pollcb_poll(apr_pollcb_t *pollcb, } else { for (i = 0; i < nget; i++) { - pollfd = (apr_pollfd_t *)(pollcb->port_set[i].portev_user); - pollfd->rtnevents = get_revent(pollcb->port_set[i].portev_events); + pollfd = (apr_pollfd_t *)(pollcb->pollset.port[i].portev_user); + pollfd->rtnevents = get_revent(pollcb->pollset.port[i].portev_events); rv = func(baton, pollfd); if (rv) { @@ -577,4 +500,14 @@ APR_DECLARE(apr_status_t) apr_pollcb_poll(apr_pollcb_t *pollcb, return rv; } -#endif /* POLLSET_USES_PORT */ +static apr_pollcb_provider_t impl_cb = { + impl_pollcb_create, + impl_pollcb_add, + impl_pollcb_remove, + impl_pollcb_poll, + "port" +}; + +apr_pollcb_provider_t *apr_pollcb_provider_port = &impl_cb; + +#endif /* HAVE_PORT_CREATE */ diff --git a/poll/unix/select.c b/poll/unix/select.c index c3ad8cd7b..736388bb6 100644 --- a/poll/unix/select.c +++ b/poll/unix/select.c @@ -23,8 +23,8 @@ #include "apr_poll.h" #include "apr_time.h" #include "apr_portable.h" -#include "apr_arch_networkio.h" #include "apr_arch_file_io.h" +#include "apr_arch_networkio.h" #include "apr_arch_poll_private.h" #ifdef POLL_USES_SELECT @@ -167,191 +167,49 @@ APR_DECLARE(apr_status_t) apr_poll(apr_pollfd_t *aprset, int num, #endif /* POLL_USES_SELECT */ -#ifdef POLLSET_USES_SELECT - -struct apr_pollset_t +struct apr_pollset_private_t { - apr_pool_t *pool; - - apr_uint32_t nelts; - apr_uint32_t nalloc; fd_set readset, writeset, exceptset; int maxfd; apr_pollfd_t *query_set; apr_pollfd_t *result_set; apr_uint32_t flags; - /* Pipe descriptors used for wakeup */ - apr_file_t *wakeup_pipe[2]; #ifdef NETWARE int set_type; #endif }; -#if !APR_FILES_AS_SOCKETS -#if defined (WIN32) - -extern apr_status_t -apr_file_socket_pipe_create(apr_file_t **in, - apr_file_t **out, - apr_pool_t *p); - -extern apr_status_t -apr_file_socket_pipe_close(apr_file_t *file); - -/* Create a dummy wakeup socket pipe for interrupting the poller - */ -static apr_status_t create_wakeup_pipe(apr_pollset_t *pollset) -{ - apr_status_t rv; - apr_pollfd_t fd; - - if ((rv = apr_file_socket_pipe_create(&pollset->wakeup_pipe[0], - &pollset->wakeup_pipe[1], - pollset->pool)) != APR_SUCCESS) - return rv; - fd.reqevents = APR_POLLIN; - fd.desc_type = APR_POLL_FILE; - fd.desc.f = pollset->wakeup_pipe[0]; - /* Add the pipe to the pollset - */ - return apr_pollset_add(pollset, &fd); -} -#else /* !WIN32 */ -static apr_status_t create_wakeup_pipe(apr_pollset_t *pollset) -{ - return APR_ENOTIMPL; -} - -static apr_status_t apr_file_socket_pipe_close(apr_file_t *file) -{ - return APR_ENOTIMPL; -} - -#endif /* WIN32 */ -#else /* APR_FILES_AS_SOCKETS */ - -/* Create a dummy wakeup pipe for interrupting the poller - */ -static apr_status_t create_wakeup_pipe(apr_pollset_t *pollset) -{ - apr_status_t rv; - apr_pollfd_t fd; - - if ((rv = apr_file_pipe_create(&pollset->wakeup_pipe[0], - &pollset->wakeup_pipe[1], - pollset->pool)) != APR_SUCCESS) - return rv; - fd.reqevents = APR_POLLIN; - fd.desc_type = APR_POLL_FILE; - fd.desc.f = pollset->wakeup_pipe[0]; - /* Add the pipe to the pollset - */ - return apr_pollset_add(pollset, &fd); -} -#endif /* !APR_FILES_AS_SOCKETS */ - -/* Read and discard what's ever in the wakeup pipe. - */ -static void drain_wakeup_pipe(apr_pollset_t *pollset) -{ - char rb[512]; - apr_size_t nr = sizeof(rb); - - while (apr_file_read(pollset->wakeup_pipe[0], rb, &nr) == APR_SUCCESS) { - /* Although we write just one byte to the other end of the pipe - * during wakeup, multiple treads could call the wakeup. - * So simply drain out from the input side of the pipe all - * the data. - */ - if (nr != sizeof(rb)) - break; - } -} - -static apr_status_t wakeup_pipe_cleanup(void *p) -{ - apr_pollset_t *pollset = (apr_pollset_t *) p; - if (pollset->flags & APR_POLLSET_WAKEABLE) { - /* Close both sides of the wakeup pipe */ - if (pollset->wakeup_pipe[0]) { -#if APR_FILES_AS_SOCKETS - apr_file_close(pollset->wakeup_pipe[0]); -#else - apr_file_socket_pipe_close(pollset->wakeup_pipe[0]); -#endif - pollset->wakeup_pipe[0] = NULL; - } - if (pollset->wakeup_pipe[1]) { -#if APR_FILES_AS_SOCKETS - apr_file_close(pollset->wakeup_pipe[1]); -#else - apr_file_socket_pipe_close(pollset->wakeup_pipe[1]); -#endif - pollset->wakeup_pipe[1] = NULL; - } - } - - return APR_SUCCESS; -} - -APR_DECLARE(apr_status_t) apr_pollset_create(apr_pollset_t **pollset, - apr_uint32_t size, - apr_pool_t *p, - apr_uint32_t flags) +static apr_status_t impl_pollset_create(apr_pollset_t *pollset, + apr_uint32_t size, + apr_pool_t *p, + apr_uint32_t flags) { if (flags & APR_POLLSET_THREADSAFE) { - *pollset = NULL; + pollset->p = NULL; return APR_ENOTIMPL; } - if (flags & APR_POLLSET_WAKEABLE) { - /* Add room for wakeup descriptor */ - size++; - } #ifdef FD_SETSIZE if (size > FD_SETSIZE) { - *pollset = NULL; + pollset->p = NULL; return APR_EINVAL; } #endif - *pollset = apr_palloc(p, sizeof(**pollset)); - (*pollset)->nelts = 0; - (*pollset)->nalloc = size; - (*pollset)->pool = p; - (*pollset)->flags = flags; - FD_ZERO(&((*pollset)->readset)); - FD_ZERO(&((*pollset)->writeset)); - FD_ZERO(&((*pollset)->exceptset)); - (*pollset)->maxfd = 0; + pollset->p = apr_palloc(p, sizeof(apr_pollset_private_t)); + FD_ZERO(&(pollset->p->readset)); + FD_ZERO(&(pollset->p->writeset)); + FD_ZERO(&(pollset->p->exceptset)); + pollset->p->maxfd = 0; #ifdef NETWARE - (*pollset)->set_type = APR_NO_DESC; + pollset->p->set_type = APR_NO_DESC; #endif - (*pollset)->query_set = apr_palloc(p, size * sizeof(apr_pollfd_t)); - (*pollset)->result_set = apr_palloc(p, size * sizeof(apr_pollfd_t)); - - if (flags & APR_POLLSET_WAKEABLE) { - apr_status_t rv; - /* Create wakeup pipe */ - if ((rv = create_wakeup_pipe(*pollset)) != APR_SUCCESS) { - *pollset = NULL; - return rv; - } - apr_pool_cleanup_register(p, *pollset, wakeup_pipe_cleanup, - apr_pool_cleanup_null); - } - return APR_SUCCESS; -} + pollset->p->query_set = apr_palloc(p, size * sizeof(apr_pollfd_t)); + pollset->p->result_set = apr_palloc(p, size * sizeof(apr_pollfd_t)); -APR_DECLARE(apr_status_t) apr_pollset_destroy(apr_pollset_t * pollset) -{ - if (pollset->flags & APR_POLLSET_WAKEABLE) - return apr_pool_cleanup_run(pollset->pool, pollset, - wakeup_pipe_cleanup); - else - return APR_SUCCESS; + return APR_SUCCESS; } -APR_DECLARE(apr_status_t) apr_pollset_add(apr_pollset_t *pollset, - const apr_pollfd_t *descriptor) +static apr_status_t impl_pollset_add(apr_pollset_t *pollset, + const apr_pollfd_t *descriptor) { apr_os_sock_t fd; @@ -359,28 +217,23 @@ APR_DECLARE(apr_status_t) apr_pollset_add(apr_pollset_t *pollset, return APR_ENOMEM; } - pollset->query_set[pollset->nelts] = *descriptor; + pollset->p->query_set[pollset->nelts] = *descriptor; if (descriptor->desc_type == APR_POLL_SOCKET) { #ifdef NETWARE /* NetWare can't handle mixed descriptor types in select() */ - if (HAS_PIPES(pollset->set_type)) { + if (HAS_PIPES(pollset->p->set_type)) { return APR_EBADF; } else { - pollset->set_type = APR_POLL_SOCKET; + pollset->p->set_type = APR_POLL_SOCKET; } #endif fd = descriptor->desc.s->socketdes; } else { #if !APR_FILES_AS_SOCKETS - if ((pollset->flags & APR_POLLSET_WAKEABLE) && - descriptor->desc.f == pollset->wakeup_pipe[0]) { - fd = (apr_os_sock_t)descriptor->desc.f->filedes; - } - else - return APR_EBADF; + return APR_EBADF; #else #ifdef NETWARE /* NetWare can't handle mixed descriptor types in select() */ @@ -403,24 +256,24 @@ APR_DECLARE(apr_status_t) apr_pollset_add(apr_pollset_t *pollset, } #endif if (descriptor->reqevents & APR_POLLIN) { - FD_SET(fd, &(pollset->readset)); + FD_SET(fd, &(pollset->p->readset)); } if (descriptor->reqevents & APR_POLLOUT) { - FD_SET(fd, &(pollset->writeset)); + FD_SET(fd, &(pollset->p->writeset)); } if (descriptor->reqevents & (APR_POLLPRI | APR_POLLERR | APR_POLLHUP | APR_POLLNVAL)) { - FD_SET(fd, &(pollset->exceptset)); + FD_SET(fd, &(pollset->p->exceptset)); } - if ((int) fd > pollset->maxfd) { - pollset->maxfd = (int) fd; + if ((int) fd > pollset->p->maxfd) { + pollset->p->maxfd = (int) fd; } pollset->nelts++; return APR_SUCCESS; } -APR_DECLARE(apr_status_t) apr_pollset_remove(apr_pollset_t * pollset, - const apr_pollfd_t * descriptor) +static apr_status_t impl_pollset_remove(apr_pollset_t * pollset, + const apr_pollfd_t * descriptor) { apr_uint32_t i; apr_os_sock_t fd; @@ -437,25 +290,25 @@ APR_DECLARE(apr_status_t) apr_pollset_remove(apr_pollset_t * pollset, } for (i = 0; i < pollset->nelts; i++) { - if (descriptor->desc.s == pollset->query_set[i].desc.s) { + if (descriptor->desc.s == pollset->p->query_set[i].desc.s) { /* Found an instance of the fd: remove this and any other copies */ apr_uint32_t dst = i; apr_uint32_t old_nelts = pollset->nelts; pollset->nelts--; for (i++; i < old_nelts; i++) { - if (descriptor->desc.s == pollset->query_set[i].desc.s) { + if (descriptor->desc.s == pollset->p->query_set[i].desc.s) { pollset->nelts--; } else { - pollset->query_set[dst] = pollset->query_set[i]; + pollset->p->query_set[dst] = pollset->p->query_set[i]; dst++; } } - FD_CLR(fd, &(pollset->readset)); - FD_CLR(fd, &(pollset->writeset)); - FD_CLR(fd, &(pollset->exceptset)); - if (((int) fd == pollset->maxfd) && (pollset->maxfd > 0)) { - pollset->maxfd--; + FD_CLR(fd, &(pollset->p->readset)); + FD_CLR(fd, &(pollset->p->writeset)); + FD_CLR(fd, &(pollset->p->exceptset)); + if (((int) fd == pollset->p->maxfd) && (pollset->p->maxfd > 0)) { + pollset->p->maxfd--; } return APR_SUCCESS; } @@ -464,10 +317,10 @@ APR_DECLARE(apr_status_t) apr_pollset_remove(apr_pollset_t * pollset, return APR_NOTFOUND; } -APR_DECLARE(apr_status_t) apr_pollset_poll(apr_pollset_t *pollset, - apr_interval_time_t timeout, - apr_int32_t *num, - const apr_pollfd_t **descriptors) +static apr_status_t impl_pollset_poll(apr_pollset_t *pollset, + apr_interval_time_t timeout, + apr_int32_t *num, + const apr_pollfd_t **descriptors) { int rs; apr_uint32_t i, j; @@ -495,18 +348,18 @@ APR_DECLARE(apr_status_t) apr_pollset_poll(apr_pollset_t *pollset, tvptr = &tv; } - memcpy(&readset, &(pollset->readset), sizeof(fd_set)); - memcpy(&writeset, &(pollset->writeset), sizeof(fd_set)); - memcpy(&exceptset, &(pollset->exceptset), sizeof(fd_set)); + memcpy(&readset, &(pollset->p->readset), sizeof(fd_set)); + memcpy(&writeset, &(pollset->p->writeset), sizeof(fd_set)); + memcpy(&exceptset, &(pollset->p->exceptset), sizeof(fd_set)); #ifdef NETWARE - if (HAS_PIPES(pollset->set_type)) { - rs = pipe_select(pollset->maxfd + 1, &readset, &writeset, &exceptset, + if (HAS_PIPES(ppollset->p->set_type)) { + rs = pipe_select(pollset->p->maxfd + 1, &readset, &writeset, &exceptset, tvptr); } else #endif - rs = select(pollset->maxfd + 1, &readset, &writeset, &exceptset, + rs = select(pollset->p->maxfd + 1, &readset, &writeset, &exceptset, tvptr); (*num) = rs; @@ -519,13 +372,13 @@ APR_DECLARE(apr_status_t) apr_pollset_poll(apr_pollset_t *pollset, j = 0; for (i = 0; i < pollset->nelts; i++) { apr_os_sock_t fd; - if (pollset->query_set[i].desc_type == APR_POLL_SOCKET) { - fd = pollset->query_set[i].desc.s->socketdes; + if (pollset->p->query_set[i].desc_type == APR_POLL_SOCKET) { + fd = pollset->p->query_set[i].desc.s->socketdes; } else { if ((pollset->flags & APR_POLLSET_WAKEABLE) && - pollset->query_set[i].desc.f == pollset->wakeup_pipe[0]) { - drain_wakeup_pipe(pollset); + pollset->p->query_set[i].desc.f == pollset->wakeup_pipe[0]) { + apr_pollset_drain_wakeup_pipe(pollset); rv = APR_EINTR; continue; } @@ -533,22 +386,22 @@ APR_DECLARE(apr_status_t) apr_pollset_poll(apr_pollset_t *pollset, #if !APR_FILES_AS_SOCKETS return APR_EBADF; #else - fd = pollset->query_set[i].desc.f->filedes; + fd = pollset->p->query_set[i].desc.f->filedes; #endif } } if (FD_ISSET(fd, &readset) || FD_ISSET(fd, &writeset) || FD_ISSET(fd, &exceptset)) { - pollset->result_set[j] = pollset->query_set[i]; - pollset->result_set[j].rtnevents = 0; + pollset->p->result_set[j] = pollset->p->query_set[i]; + pollset->p->result_set[j].rtnevents = 0; if (FD_ISSET(fd, &readset)) { - pollset->result_set[j].rtnevents |= APR_POLLIN; + pollset->p->result_set[j].rtnevents |= APR_POLLIN; } if (FD_ISSET(fd, &writeset)) { - pollset->result_set[j].rtnevents |= APR_POLLOUT; + pollset->p->result_set[j].rtnevents |= APR_POLLOUT; } if (FD_ISSET(fd, &exceptset)) { - pollset->result_set[j].rtnevents |= APR_POLLERR; + pollset->p->result_set[j].rtnevents |= APR_POLLERR; } j++; } @@ -557,45 +410,17 @@ APR_DECLARE(apr_status_t) apr_pollset_poll(apr_pollset_t *pollset, rv = APR_SUCCESS; if (descriptors) - *descriptors = pollset->result_set; + *descriptors = pollset->p->result_set; return rv; } -APR_DECLARE(apr_status_t) apr_pollset_wakeup(apr_pollset_t *pollset) -{ - if (pollset->flags & APR_POLLSET_WAKEABLE) - return apr_file_putc(1, pollset->wakeup_pipe[1]); - else - return APR_EINIT; -} - -APR_DECLARE(apr_status_t) apr_pollcb_create(apr_pollcb_t **pollcb, - apr_uint32_t size, - apr_pool_t *p, - apr_uint32_t flags) -{ - return APR_ENOTIMPL; -} - -APR_DECLARE(apr_status_t) apr_pollcb_add(apr_pollcb_t *pollcb, - apr_pollfd_t *descriptor) -{ - return APR_ENOTIMPL; -} - -APR_DECLARE(apr_status_t) apr_pollcb_remove(apr_pollcb_t *pollcb, - apr_pollfd_t *descriptor) -{ - return APR_ENOTIMPL; -} - - -APR_DECLARE(apr_status_t) apr_pollcb_poll(apr_pollcb_t *pollcb, - apr_interval_time_t timeout, - apr_pollcb_cb_t func, - void *baton) -{ - return APR_ENOTIMPL; -} +static apr_pollset_provider_t impl = { + impl_pollset_create, + impl_pollset_add, + impl_pollset_remove, + impl_pollset_poll, + NULL, + "select" +}; -#endif /* POLLSET_USES_SELECT */ +apr_pollset_provider_t *apr_pollset_provider_select = &impl; |