summaryrefslogtreecommitdiff
path: root/poll/unix/pollcb.c
diff options
context:
space:
mode:
Diffstat (limited to 'poll/unix/pollcb.c')
-rw-r--r--poll/unix/pollcb.c63
1 files changed, 56 insertions, 7 deletions
diff --git a/poll/unix/pollcb.c b/poll/unix/pollcb.c
index da12f015a74f7..a63ad5c9cad25 100644
--- a/poll/unix/pollcb.c
+++ b/poll/unix/pollcb.c
@@ -29,21 +29,21 @@
static apr_pollset_method_e pollset_default_method = POLLSET_DEFAULT_METHOD;
#if defined(HAVE_KQUEUE)
-extern apr_pollcb_provider_t *apr_pollcb_provider_kqueue;
+extern const apr_pollcb_provider_t *apr_pollcb_provider_kqueue;
#endif
#if defined(HAVE_PORT_CREATE)
-extern apr_pollcb_provider_t *apr_pollcb_provider_port;
+extern const apr_pollcb_provider_t *apr_pollcb_provider_port;
#endif
#if defined(HAVE_EPOLL)
-extern apr_pollcb_provider_t *apr_pollcb_provider_epoll;
+extern const apr_pollcb_provider_t *apr_pollcb_provider_epoll;
#endif
#if defined(HAVE_POLL)
-extern apr_pollcb_provider_t *apr_pollcb_provider_poll;
+extern const apr_pollcb_provider_t *apr_pollcb_provider_poll;
#endif
-static apr_pollcb_provider_t *pollcb_provider(apr_pollset_method_e method)
+static const apr_pollcb_provider_t *pollcb_provider(apr_pollset_method_e method)
{
- apr_pollcb_provider_t *provider = NULL;
+ const apr_pollcb_provider_t *provider = NULL;
switch (method) {
case APR_POLLSET_KQUEUE:
#if defined(HAVE_KQUEUE)
@@ -73,6 +73,20 @@ static apr_pollcb_provider_t *pollcb_provider(apr_pollset_method_e method)
return provider;
}
+static apr_status_t pollcb_cleanup(void *p)
+{
+ apr_pollcb_t *pollcb = (apr_pollcb_t *) p;
+
+ if (pollcb->provider->cleanup) {
+ (*pollcb->provider->cleanup)(pollcb);
+ }
+ if (pollcb->flags & APR_POLLSET_WAKEABLE) {
+ apr_poll_close_wakeup_pipe(pollcb->wakeup_pipe);
+ }
+
+ return APR_SUCCESS;
+}
+
APR_DECLARE(apr_status_t) apr_pollcb_create_ex(apr_pollcb_t **ret_pollcb,
apr_uint32_t size,
apr_pool_t *p,
@@ -81,7 +95,7 @@ APR_DECLARE(apr_status_t) apr_pollcb_create_ex(apr_pollcb_t **ret_pollcb,
{
apr_status_t rv;
apr_pollcb_t *pollcb;
- apr_pollcb_provider_t *provider = NULL;
+ const apr_pollcb_provider_t *provider = NULL;
*ret_pollcb = NULL;
@@ -109,9 +123,15 @@ APR_DECLARE(apr_status_t) apr_pollcb_create_ex(apr_pollcb_t **ret_pollcb,
}
}
+ if (flags & APR_POLLSET_WAKEABLE) {
+ /* Add room for wakeup descriptor */
+ size++;
+ }
+
pollcb = apr_palloc(p, sizeof(*pollcb));
pollcb->nelts = 0;
pollcb->nalloc = size;
+ pollcb->flags = flags;
pollcb->pool = p;
pollcb->provider = provider;
@@ -140,6 +160,22 @@ APR_DECLARE(apr_status_t) apr_pollcb_create_ex(apr_pollcb_t **ret_pollcb,
return rv;
}
+ if (flags & APR_POLLSET_WAKEABLE) {
+ /* Create wakeup pipe */
+ if ((rv = apr_poll_create_wakeup_pipe(pollcb->pool, &pollcb->wakeup_pfd,
+ pollcb->wakeup_pipe))
+ != APR_SUCCESS) {
+ return rv;
+ }
+
+ if ((rv = apr_pollcb_add(pollcb, &pollcb->wakeup_pfd)) != APR_SUCCESS) {
+ return rv;
+ }
+ }
+ if ((flags & APR_POLLSET_WAKEABLE) || provider->cleanup)
+ apr_pool_cleanup_register(p, pollcb, pollcb_cleanup,
+ apr_pool_cleanup_null);
+
*ret_pollcb = pollcb;
return APR_SUCCESS;
}
@@ -173,3 +209,16 @@ APR_DECLARE(apr_status_t) apr_pollcb_poll(apr_pollcb_t *pollcb,
{
return (*pollcb->provider->poll)(pollcb, timeout, func, baton);
}
+
+APR_DECLARE(apr_status_t) apr_pollcb_wakeup(apr_pollcb_t *pollcb)
+{
+ if (pollcb->flags & APR_POLLSET_WAKEABLE)
+ return apr_file_putc(1, pollcb->wakeup_pipe[1]);
+ else
+ return APR_EINIT;
+}
+
+APR_DECLARE(const char *) apr_pollcb_method_name(apr_pollcb_t *pollcb)
+{
+ return pollcb->provider->name;
+}