apr-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From mt...@apache.org
Subject svn commit: r744096 - in /apr/apr/trunk/poll/unix: pollcb.c pollset.c
Date Fri, 13 Feb 2009 12:25:00 GMT
Author: mturk
Date: Fri Feb 13 12:25:00 2009
New Revision: 744096

URL: http://svn.apache.org/viewvc?rev=744096&view=rev
Log:
Implement providers for apr_pollset and apr_pollcb.
Add common files

Added:
    apr/apr/trunk/poll/unix/pollcb.c   (with props)
    apr/apr/trunk/poll/unix/pollset.c   (with props)

Added: apr/apr/trunk/poll/unix/pollcb.c
URL: http://svn.apache.org/viewvc/apr/apr/trunk/poll/unix/pollcb.c?rev=744096&view=auto
==============================================================================
--- apr/apr/trunk/poll/unix/pollcb.c (added)
+++ apr/apr/trunk/poll/unix/pollcb.c Fri Feb 13 12:25:00 2009
@@ -0,0 +1,165 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifdef WIN32
+/* POSIX defines 1024 for the FD_SETSIZE */
+#define FD_SETSIZE 1024
+#endif
+
+#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"
+
+static apr_pollset_method_e pollset_default_method = POLLSET_DEFAULT_METHOD;
+#if defined(HAVE_KQUEUE)
+extern apr_pollcb_provider_t *apr_pollcb_provider_kqueue;
+#endif
+#if defined(HAVE_PORT_CREATE)
+extern apr_pollcb_provider_t *apr_pollcb_provider_port;
+#endif
+#if defined(HAVE_EPOLL)
+extern apr_pollcb_provider_t *apr_pollcb_provider_epoll;
+#endif
+#if defined(HAVE_POLL)
+extern apr_pollcb_provider_t *apr_pollcb_provider_poll;
+#endif
+
+
+APR_DECLARE(apr_status_t) apr_pollcb_create_ex(apr_pollcb_t **pollcb,
+                                               apr_uint32_t size,
+                                               apr_pool_t *p,
+                                               apr_uint32_t flags,
+                                               apr_pollset_method_e method)
+{
+    apr_status_t rv;
+    apr_pollcb_provider_t *provider = NULL;
+
+    if (method == APR_POLLSET_DEFAULT)
+        method = pollset_default_method;
+    while (provider == NULL) {
+        switch (method) {
+            case APR_POLLSET_KQUEUE:
+#if defined(HAVE_KQUEUE)
+                provider = apr_pollcb_provider_kqueue;
+#endif
+            break;
+            case APR_POLLSET_PORT:
+#if defined(HAVE_PORT_CREATE)
+                provider = apr_pollcb_provider_port;
+#endif
+            break;
+            case APR_POLLSET_EPOLL:
+#if defined(HAVE_EPOLL)
+                provider = apr_pollcb_provider_epoll;
+#endif
+            break;
+            case APR_POLLSET_POLL:
+#if defined(HAVE_POLL)
+                provider = apr_pollcb_provider_poll;
+#endif
+            break;
+        }
+        if (!provider) {
+            *pollcb = NULL;
+            if ((flags & APR_POLLSET_NODEFAULT) == APR_POLLSET_NODEFAULT)
+                return APR_ENOTIMPL;
+            if (method == pollset_default_method)
+                return APR_ENOTIMPL;
+            method = pollset_default_method;
+        }
+    }
+
+    *pollcb = apr_palloc(p, sizeof(**pollcb));
+    (*pollcb)->nalloc = size;
+    (*pollcb)->pool = p;
+    (*pollcb)->provider = provider;
+
+    rv = (*provider->create)(*pollcb, size, p, flags);
+    if (rv != APR_SUCCESS) {
+        if (method == pollset_default_method) {
+            *pollcb = NULL;
+            return rv;
+        }
+        provider = NULL;
+        /* Try with default provider */
+        switch (pollset_default_method) {
+            case APR_POLLSET_KQUEUE:
+#if defined(HAVE_KQUEUE)
+                provider = apr_pollcb_provider_kqueue;
+#endif
+            break;
+            case APR_POLLSET_PORT:
+#if defined(HAVE_PORT_CREATE)
+                provider = apr_pollcb_provider_port;
+#endif
+            break;
+            case APR_POLLSET_EPOLL:
+#if defined(HAVE_EPOLL)
+                provider = apr_pollcb_provider_epoll;
+#endif
+            break;
+            case APR_POLLSET_POLL:
+#if defined(HAVE_POLL)
+                provider = apr_pollcb_provider_poll;
+#endif
+            break;
+        }
+        if (!provider)
+            return APR_ENOTIMPL;
+        rv = (*provider->create)(*pollcb, size, p, flags);
+        if (rv != APR_SUCCESS) {
+            *pollcb = NULL;
+            return rv;
+        }
+        (*pollcb)->provider = provider;
+    }
+
+    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)
+{
+    return apr_pollcb_create_ex(pollcb, size, p, flags,
+                                APR_POLLSET_DEFAULT);
+}
+
+APR_DECLARE(apr_status_t) apr_pollcb_add(apr_pollcb_t *pollcb,
+                                         apr_pollfd_t *descriptor)
+{
+    return (*pollcb->provider->add)(pollcb, descriptor);
+}
+
+APR_DECLARE(apr_status_t) apr_pollcb_remove(apr_pollcb_t *pollcb,
+                                            apr_pollfd_t *descriptor)
+{
+    return (*pollcb->provider->remove)(pollcb, descriptor);
+}
+
+
+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 (*pollcb->provider->poll)(pollcb, timeout, func, baton);
+}

Propchange: apr/apr/trunk/poll/unix/pollcb.c
------------------------------------------------------------------------------
    svn:eol-style = native

Added: apr/apr/trunk/poll/unix/pollset.c
URL: http://svn.apache.org/viewvc/apr/apr/trunk/poll/unix/pollset.c?rev=744096&view=auto
==============================================================================
--- apr/apr/trunk/poll/unix/pollset.c (added)
+++ apr/apr/trunk/poll/unix/pollset.c Fri Feb 13 12:25:00 2009
@@ -0,0 +1,349 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifdef WIN32
+/* POSIX defines 1024 for the FD_SETSIZE */
+#define FD_SETSIZE 1024
+#endif
+
+#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"
+
+static apr_pollset_method_e pollset_default_method = POLLSET_DEFAULT_METHOD;
+
+#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.
+ */
+void apr_pollset_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 pollset_cleanup(void *p)
+{
+    apr_pollset_t *pollset = (apr_pollset_t *) p;
+    if (pollset->provider->cleanup) {
+        (*pollset->provider->cleanup)(pollset);
+    }
+    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;
+}
+
+#if defined(HAVE_KQUEUE)
+extern apr_pollset_provider_t *apr_pollset_provider_kqueue;
+#endif
+#if defined(HAVE_PORT_CREATE)
+extern apr_pollset_provider_t *apr_pollset_provider_port;
+#endif
+#if defined(HAVE_EPOLL)
+extern apr_pollset_provider_t *apr_pollset_provider_epoll;
+#endif
+#if defined(HAVE_POLL)
+extern apr_pollset_provider_t *apr_pollset_provider_poll;
+#endif
+extern apr_pollset_provider_t *apr_pollset_provider_select;
+
+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)
+{
+    apr_status_t rv;
+    apr_pollset_provider_t *provider = NULL;
+
+    if (method == APR_POLLSET_DEFAULT)
+        method = pollset_default_method;
+    while (provider == NULL) {
+        switch (method) {
+            case APR_POLLSET_KQUEUE:
+#if defined(HAVE_KQUEUE)
+                provider = apr_pollset_provider_kqueue;
+#endif
+            break;
+            case APR_POLLSET_PORT:
+#if defined(HAVE_PORT_CREATE)
+                provider = apr_pollset_provider_port;
+#endif
+            break;
+            case APR_POLLSET_EPOLL:
+#if defined(HAVE_EPOLL)
+                provider = apr_pollset_provider_epoll;
+#endif
+            break;
+            case APR_POLLSET_POLL:
+#if defined(HAVE_POLL)
+                provider = apr_pollset_provider_poll;
+#endif
+            break;
+            case APR_POLLSET_SELECT:
+                provider = apr_pollset_provider_select;
+            break;
+        }
+        if (!provider) {
+            if ((flags & APR_POLLSET_NODEFAULT) == APR_POLLSET_NODEFAULT)
+                return APR_ENOTIMPL;
+            if (method == pollset_default_method)
+                return APR_ENOTIMPL;
+            method = pollset_default_method;
+        }
+    }
+    if (flags & APR_POLLSET_WAKEABLE) {
+        /* Add room for wakeup descriptor */
+        size++;
+    }
+
+    *pollset = apr_palloc(p, sizeof(**pollset));
+    (*pollset)->nelts = 0;
+    (*pollset)->nalloc = size;
+    (*pollset)->pool = p;
+    (*pollset)->flags = flags;
+    (*pollset)->provider = provider;
+
+    rv = (*provider->create)(*pollset, size, p, flags);
+    if (rv != APR_SUCCESS) {
+        if (method == pollset_default_method) {
+            *pollset = NULL;
+            return rv;
+        }
+        provider = NULL;
+        /* Try with default provider */
+        switch (pollset_default_method) {
+            case APR_POLLSET_KQUEUE:
+#if defined(HAVE_KQUEUE)
+                provider = apr_pollset_provider_kqueue;
+#endif
+            break;
+            case APR_POLLSET_PORT:
+#if defined(HAVE_PORT_CREATE)
+                provider = apr_pollset_provider_port;
+#endif
+            break;
+            case APR_POLLSET_EPOLL:
+#if defined(HAVE_EPOLL)
+                provider = apr_pollset_provider_epoll;
+#endif
+            break;
+            case APR_POLLSET_POLL:
+#if defined(HAVE_POLL)
+                provider = apr_pollset_provider_poll;
+#endif
+            break;
+            case APR_POLLSET_SELECT:
+                provider = apr_pollset_provider_select;
+            break;
+        }
+        if (!provider)
+            return APR_ENOTIMPL;
+        rv = (*provider->create)(*pollset, size, p, flags);
+        if (rv != APR_SUCCESS) {
+            *pollset = NULL;
+            return rv;
+        }
+        (*pollset)->provider = provider;
+    }
+    if (flags & APR_POLLSET_WAKEABLE) {
+        /* Create wakeup pipe */
+        if ((rv = create_wakeup_pipe(*pollset)) != APR_SUCCESS) {
+            *pollset = NULL;
+            return rv;
+        }
+    }
+    if ((flags & APR_POLLSET_WAKEABLE) || provider->cleanup)
+        apr_pool_cleanup_register(p, *pollset, pollset_cleanup,
+                                  apr_pool_cleanup_null);
+    return APR_SUCCESS;
+}
+
+APR_DECLARE(const char *) apr_pollset_method_name(apr_pollset_t *pollset)
+{
+    return pollset->provider->name;
+}
+
+APR_DECLARE(const char *) apr_poll_method_defname()
+{
+    switch (pollset_default_method) {
+        case APR_POLLSET_KQUEUE:
+#if defined(HAVE_KQUEUE)
+            return apr_pollset_provider_kqueue->name;
+#endif
+        break;
+        case APR_POLLSET_PORT:
+#if defined(HAVE_PORT_CREATE)
+            return apr_pollset_provider_port->name;
+#endif
+        break;
+        case APR_POLLSET_EPOLL:
+#if defined(HAVE_EPOLL)
+            return apr_pollset_provider_epoll->name;
+#endif
+        break;
+        case APR_POLLSET_POLL:
+#if defined(HAVE_POLL)
+            return apr_pollset_provider_poll->name;
+#endif
+        break;
+        case APR_POLLSET_SELECT:
+            return apr_pollset_provider_select->name;
+        break;
+    }
+    return "unknown";
+}
+
+APR_DECLARE(apr_status_t) apr_pollset_create(apr_pollset_t **pollset,
+                                             apr_uint32_t size,
+                                             apr_pool_t *p,
+                                             apr_uint32_t flags)
+{
+    return apr_pollset_create_ex(pollset, size, p, flags,
+                                 APR_POLLSET_DEFAULT);
+}
+
+APR_DECLARE(apr_status_t) apr_pollset_destroy(apr_pollset_t * pollset)
+{
+    if (pollset->flags & APR_POLLSET_WAKEABLE ||
+        pollset->provider->cleanup)
+        return apr_pool_cleanup_run(pollset->pool, pollset,
+                                    pollset_cleanup);
+    else
+        return APR_SUCCESS;
+}
+
+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_pollset_add(apr_pollset_t *pollset,
+                                          const apr_pollfd_t *descriptor)
+{
+    return (*pollset->provider->add)(pollset, descriptor);
+}
+
+APR_DECLARE(apr_status_t) apr_pollset_remove(apr_pollset_t *pollset,
+                                             const apr_pollfd_t *descriptor)
+{
+    return (*pollset->provider->remove)(pollset, descriptor);
+}
+
+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)
+{
+    return (*pollset->provider->poll)(pollset, timeout, num, descriptors);
+}

Propchange: apr/apr/trunk/poll/unix/pollset.c
------------------------------------------------------------------------------
    svn:eol-style = native



Mime
View raw message