apr-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From pque...@apache.org
Subject svn commit: r390326 - in /apr/apr/branches/pollcb-dev: include/apr_poll.h poll/unix/epoll.c test/testpoll.c
Date Fri, 31 Mar 2006 05:07:06 GMT
Author: pquerna
Date: Thu Mar 30 21:07:04 2006
New Revision: 390326

URL: http://svn.apache.org/viewcvs?rev=390326&view=rev
Log:
Add a first revision of the Pollset Callback API.

Currently it only has an EPoll implementation, and the most basic test case possible.

Modified:
    apr/apr/branches/pollcb-dev/include/apr_poll.h
    apr/apr/branches/pollcb-dev/poll/unix/epoll.c
    apr/apr/branches/pollcb-dev/test/testpoll.c

Modified: apr/apr/branches/pollcb-dev/include/apr_poll.h
URL: http://svn.apache.org/viewcvs/apr/apr/branches/pollcb-dev/include/apr_poll.h?rev=390326&r1=390325&r2=390326&view=diff
==============================================================================
--- apr/apr/branches/pollcb-dev/include/apr_poll.h (original)
+++ apr/apr/branches/pollcb-dev/include/apr_poll.h Thu Mar 30 21:07:04 2006
@@ -188,7 +188,27 @@
 
 /** @} */
 
+/** Opaque structure used for pollset API */
+typedef struct apr_pollcb_t apr_pollcb_t;
 
+APR_DECLARE(apr_status_t) apr_pollcb_create(apr_pollcb_t **pollcb,
+                                            apr_uint32_t size,
+                                            apr_pool_t *pool,
+                                            apr_uint32_t flags);
+
+
+APR_DECLARE(apr_status_t) apr_pollcb_add(apr_pollcb_t *pollcb,
+                                         apr_pollfd_t *descriptor);
+
+APR_DECLARE(apr_status_t) apr_pollcb_remove(apr_pollcb_t *pollcb,
+                                            apr_pollfd_t *descriptor);
+
+typedef apr_status_t(*apr_pollcb_cb_t)(void* baton, apr_pollfd_t *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); 
 #ifdef __cplusplus
 }
 #endif

Modified: apr/apr/branches/pollcb-dev/poll/unix/epoll.c
URL: http://svn.apache.org/viewcvs/apr/apr/branches/pollcb-dev/poll/unix/epoll.c?rev=390326&r1=390325&r2=390326&view=diff
==============================================================================
--- apr/apr/branches/pollcb-dev/poll/unix/epoll.c (original)
+++ apr/apr/branches/pollcb-dev/poll/unix/epoll.c Thu Mar 30 21:07:04 2006
@@ -296,4 +296,128 @@
     return rv;
 }
 
+struct apr_pollcb_t {
+    apr_pool_t *pool;
+    apr_uint32_t nalloc;
+    struct epoll_event *pollset;
+    int epoll_fd;
+};
+
+static apr_status_t cb_cleanup(void *p_)
+{
+    apr_pollcb_t *pollcb = (apr_pollcb_t *) p_;
+    close(pollcb->epoll_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)
+{
+    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);
+
+    return APR_SUCCESS;
+}
+
+APR_DECLARE(apr_status_t) apr_pollcb_add(apr_pollcb_t *pollcb,
+                                         apr_pollfd_t *descriptor)
+{
+    struct epoll_event ev;
+    int ret;
+    
+    ev.events = get_epoll_event(descriptor->reqevents);
+    ev.data.ptr = (void *)descriptor;
+
+    if (descriptor->desc_type == APR_POLL_SOCKET) {
+        ret = epoll_ctl(pollcb->epoll_fd, EPOLL_CTL_ADD,
+                        descriptor->desc.s->socketdes, &ev);
+    }
+    else {
+        ret = epoll_ctl(pollcb->epoll_fd, EPOLL_CTL_ADD,
+                        descriptor->desc.f->filedes, &ev);
+    }
+    
+    if (ret == -1) {
+        return apr_get_netos_error();
+    }
+    
+    return APR_SUCCESS;
+}
+
+APR_DECLARE(apr_status_t) apr_pollcb_remove(apr_pollcb_t *pollcb,
+                                            apr_pollfd_t *descriptor)
+{
+    apr_status_t rv = APR_SUCCESS;
+    struct epoll_event ev;
+    int ret = -1;
+    
+    ev.events = get_epoll_event(descriptor->reqevents);
+    
+    if (descriptor->desc_type == APR_POLL_SOCKET) {
+        ret = epoll_ctl(pollcb->epoll_fd, EPOLL_CTL_DEL,
+                        descriptor->desc.s->socketdes, &ev);
+    }
+    else {
+        ret = epoll_ctl(pollcb->epoll_fd, EPOLL_CTL_DEL,
+                        descriptor->desc.f->filedes, &ev);
+    }
+    
+    if (ret < 0) {
+        rv = APR_NOTFOUND;
+    }
+    
+    return rv;
+}
+
+
+APR_DECLARE(apr_status_t) apr_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;
+    
+    if (timeout > 0) {
+        timeout /= 1000;
+    }
+    
+    ret = epoll_wait(pollcb->epoll_fd, pollcb->pollset, pollcb->nalloc,
+                     timeout);
+    if (ret < 0) {
+        rv = apr_get_netos_error();
+    }
+    else if (ret == 0) {
+        rv = APR_TIMEUP;
+    }
+    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);
+
+            rv = func(baton, pollfd);
+            if (rv) {
+                return rv;
+            }
+        }
+    }
+    
+    return rv;
+}
+
 #endif /* POLLSET_USES_EPOLL */

Modified: apr/apr/branches/pollcb-dev/test/testpoll.c
URL: http://svn.apache.org/viewcvs/apr/apr/branches/pollcb-dev/test/testpoll.c?rev=390326&r1=390325&r2=390326&view=diff
==============================================================================
--- apr/apr/branches/pollcb-dev/test/testpoll.c (original)
+++ apr/apr/branches/pollcb-dev/test/testpoll.c Thu Mar 30 21:07:04 2006
@@ -32,6 +32,7 @@
 static apr_socket_t *s[LARGE_NUM_SOCKETS];
 static apr_sockaddr_t *sa[LARGE_NUM_SOCKETS];
 static apr_pollset_t *pollset;
+static apr_pollcb_t *pollcb;
 
 /* ###: tests surrounded by ifdef OLD_POLL_INTERFACE either need to be
  * converted to use the pollset interface or removed. */
@@ -552,6 +553,14 @@
              (hot_files[1].client_data == (void *)1)));
 }
 
+static void setup_pollcb(abts_case *tc, void *data)
+{
+    apr_status_t rv;
+    rv = apr_pollcb_create(&pollcb, LARGE_NUM_SOCKETS, p, 0);
+    ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
+}
+
+
 abts_suite *testpoll(abts_suite *suite)
 {
     suite = ADD_SUITE(suite)
@@ -585,6 +594,8 @@
     abts_run_test(suite, pollset_remove, NULL);
     
     abts_run_test(suite, close_all_sockets, NULL);
+
+    abts_run_test(suite, setup_pollcb, NULL);
 
     return suite;
 }



Mime
View raw message