apr-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From bri...@apache.org
Subject cvs commit: apr/test testpoll.c
Date Thu, 01 Aug 2002 21:17:59 GMT
brianp      2002/08/01 14:17:59

  Modified:    include  apr_poll.h
               poll/unix poll.c
               test     testpoll.c
  Log:
  Added general-purpose pollset API to handle arbitrarily large
  numbers of file descriptors
  
  Revision  Changes    Path
  1.3       +54 -0     apr/include/apr_poll.h
  
  Index: apr_poll.h
  ===================================================================
  RCS file: /home/cvs/apr/include/apr_poll.h,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- apr_poll.h	11 Jul 2002 14:39:04 -0000	1.2
  +++ apr_poll.h	1 Aug 2002 21:17:58 -0000	1.3
  @@ -219,6 +219,60 @@
                                             apr_socket_t *sock,
                                             apr_pollfd_t *aprset);
   
  +/* General-purpose poll API for arbitrarily large numbers of
  + * file descriptors
  + */
  +
  +typedef struct apr_pollset_t apr_pollset_t;
  +
  +/**
  + * 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
  + */
  +APR_DECLARE(apr_status_t) apr_pollset_create(apr_pollset_t **pollset,
  +                                             apr_uint32_t size,
  +                                             apr_pool_t *p);
  +
  +/**
  + * Destroy a pollset object
  + * @param pollset The pollset to destroy
  + * @param descriptors An initial set of descriptors to add to the pollset
  + *                    (may be NULL)
  + * @param num The number of elements in the descriptors array
  + * @param p The pool from which to allocate the pollset
  + */
  +APR_DECLARE(apr_status_t) apr_pollset_destroy(apr_pollset_t *pollset);
  +
  +/**
  + * Add a socket or file descriptor to a pollset
  + * @param pollset The pollset to which to add the descriptor
  + * @param descriptor The descriptor to add
  + */
  +APR_DECLARE(apr_status_t) apr_pollset_add(apr_pollset_t *pollset,
  +                                          const apr_pollfd_t *descriptor);
  +
  +/**
  + * Remove a descriptor from a pollset
  + * @param pollset The pollset from which to remove the descriptor
  + * @param descriptor The descriptor to remove
  + */
  +APR_DECLARE(apr_status_t) apr_pollset_remove(apr_pollset_t *pollset,
  +                                             const apr_pollfd_t *descriptor);
  +
  +/**
  + * Block for activity on the descriptor(s) in a pollset
  + * @param pollset The pollset to use
  + * @param timeout Timeout in microseconds
  + * @param num Number of signalled descriptors (output parameter)
  + * @param descriptors Array of signalled descriptors (output parameter)
  + */
  +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);
  +
   #ifdef __cplusplus
   }
   #endif
  
  
  
  1.10      +113 -0    apr/poll/unix/poll.c
  
  Index: poll.c
  ===================================================================
  RCS file: /home/cvs/apr/poll/unix/poll.c,v
  retrieving revision 1.9
  retrieving revision 1.10
  diff -u -r1.9 -r1.10
  --- poll.c	31 Jul 2002 01:12:43 -0000	1.9
  +++ poll.c	1 Aug 2002 21:17:58 -0000	1.10
  @@ -259,3 +259,116 @@
   }
   
   #endif 
  +
  +
  +struct apr_pollset_t {
  +    apr_uint32_t nelts;
  +    apr_uint32_t nalloc;
  +    struct pollfd *pollset;
  +    apr_pollfd_t *query_set;
  +    apr_pollfd_t *result_set;
  +    apr_pool_t *pool;
  +};
  +
  +APR_DECLARE(apr_status_t) apr_pollset_create(apr_pollset_t **pollset,
  +                                             apr_uint32_t size,
  +                                             apr_pool_t *p)
  +{
  +    *pollset = apr_palloc(p, sizeof(**pollset));
  +    (*pollset)->nelts = 0;
  +    (*pollset)->nalloc = size;
  +    (*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));
  +    (*pollset)->pool = p;
  +    return APR_SUCCESS;
  +}
  +
  +APR_DECLARE(apr_status_t) apr_pollset_destroy(apr_pollset_t *pollset)
  +{
  +    /* A no-op function for now.  If we later implement /dev/poll
  +     * support, we'll need to close the /dev/poll fd here
  +     */
  +    return APR_SUCCESS;
  +}
  +
  +APR_DECLARE(apr_status_t) apr_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;
  +    if (descriptor->desc_type == APR_POLL_SOCKET) {
  +        pollset->pollset[pollset->nelts].fd = descriptor->desc.s->socketdes;
  +    }
  +    else {
  +        pollset->pollset[pollset->nelts].fd = descriptor->desc.f->filedes;
  +    }
  +    pollset->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)
  +{
  +    apr_uint32_t i;
  +    int fd;
  +
  +    if (descriptor->desc_type == APR_POLL_SOCKET) {
  +        fd = descriptor->desc.s->socketdes;
  +    }
  +    else {
  +        fd = descriptor->desc.f->filedes;
  +    }
  +
  +    for (i = 0; i < pollset->nelts; i++) {
  +        if (fd == pollset->pollset[i].fd) {
  +            /* 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 (fd == pollset->pollset[i].fd) {
  +                    pollset->nelts--;
  +                }
  +                else {
  +                    pollset->pollset[dst] = pollset->pollset[i];
  +                }
  +            }
  +            return APR_SUCCESS;
  +        }
  +    }
  +    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)
  +{
  +    int rv;
  +    apr_uint32_t i, j;
  +
  +    if (timeout > 0) {
  +        timeout /= 1000;
  +    }
  +    rv = poll(pollset->pollset, pollset->nelts, timeout);
  +    (*num) = rv;
  +    if (rv < 0) {
  +        return errno;
  +    }
  +    j = 0;
  +    for (i = 0; i < pollset->nelts; i++) {
  +        if (pollset->pollset[i].revents != 0) {
  +            pollset->result_set[j] = pollset->query_set[i];
  +            pollset->result_set[j].rtnevents =
  +                get_revent(pollset->pollset[i].revents);
  +            j++;
  +        }
  +    }
  +    *descriptors = pollset->result_set;
  +    return APR_SUCCESS;
  +}
  
  
  
  1.13      +61 -4     apr/test/testpoll.c
  
  Index: testpoll.c
  ===================================================================
  RCS file: /home/cvs/apr/test/testpoll.c,v
  retrieving revision 1.12
  retrieving revision 1.13
  diff -u -r1.12 -r1.13
  --- testpoll.c	1 Aug 2002 20:10:03 -0000	1.12
  +++ testpoll.c	1 Aug 2002 21:17:58 -0000	1.13
  @@ -149,7 +149,10 @@
       apr_socket_t *s[LARGE_NUM_SOCKETS];
       apr_sockaddr_t *sa[LARGE_NUM_SOCKETS];
       apr_pollfd_t *pollarray;
  +    apr_pollset_t *pollset;
       int i = 0, srv = SMALL_NUM_SOCKETS;
  +    apr_int32_t num;
  +    const apr_pollfd_t *descriptors_out;
       
       fprintf (stdout,"APR Poll Test\n*************\n\n");
       
  @@ -169,7 +172,7 @@
       printf("OK\n");
       
       printf("\tCreating the sockets I'll use..........");
  -    for (i = 0; i < SMALL_NUM_SOCKETS; i++){
  +    for (i = 0; i < LARGE_NUM_SOCKETS; i++){
           if (make_socket(&s[i], &sa[i], 7777 + i, context) != 0){
               exit(-1);
           }
  @@ -190,7 +193,7 @@
       printf("OK\n");
       printf("Starting Tests\n");
   
  -    apr_poll(pollarray, SMALL_NUM_SOCKETS, &srv, 10 * APR_USEC_PER_SEC);
  +    apr_poll(pollarray, SMALL_NUM_SOCKETS, &srv, 2 * APR_USEC_PER_SEC);
       check_sockets(pollarray, s);
       
       send_msg(s, sa, 2);
  @@ -214,15 +217,69 @@
       
       apr_poll(pollarray, SMALL_NUM_SOCKETS, &srv, 10 * APR_USEC_PER_SEC); 
       check_sockets(pollarray, s);
  -        
  +
  +    recv_msg(s, 0, context);
  +    recv_msg(s, 2, context);
  +
       printf("Tests completed.\n");
  +
  +    fprintf (stdout,"\nAPR Pollset Test\n****************\n\n");
  +
  +    printf ("\tSetting up pollset....................");
  +    if (apr_pollset_create(&pollset, LARGE_NUM_SOCKETS, context) != APR_SUCCESS){
  +        printf("Couldn't create a pollset!\n");
  +        exit (-1);
  +    }
  +    for (i = 0; i < LARGE_NUM_SOCKETS;i++){
  +        apr_pollfd_t socket_pollfd;
  +        socket_pollfd.desc_type = APR_POLL_SOCKET;
  +        socket_pollfd.reqevents = APR_POLLIN;
  +        socket_pollfd.desc.s = s[i];
  +        if (apr_pollset_add(pollset, &socket_pollfd) != APR_SUCCESS){
  +            printf("Failed to add socket %d\n", i);
  +            exit (-1);
  +        }
  +    }
  +    printf("OK\n");
  +
  +    printf("\nTest 1: No descriptors signalled.......");
  +    if ((apr_pollset_poll(pollset, 0, &num, &descriptors_out) != APR_SUCCESS) ||
  +        (num != 0)) {
  +        printf("FAILED\n");
  +        exit(-1);
  +    }
  +    printf("OK\n");
  +
  +    printf("\nTest 2: First descriptor signalled.....\n");
  +    send_msg(s, sa, 0);
  +    if ((apr_pollset_poll(pollset, 0, &num, &descriptors_out) != APR_SUCCESS) ||
  +        (num != 1)) {
  +        printf("Test 2: FAILED\n");
  +        exit(-1);
  +    }
  +    recv_msg(s, 0, context);
  +    printf("Test 2: OK\n");
  +
  +    printf("\nTest 3: Last descriptor signalled......\n");
  +    send_msg(s, sa, 99);
  +    if ((apr_pollset_poll(pollset, 0, &num, &descriptors_out) != APR_SUCCESS) ||
  +        (num != 1)) {
  +        printf("Test 3: FAILED\n");
  +        exit(-1);
  +    }
  +    recv_msg(s, 99, context);
  +    printf("Test 3: OK\n");
  +
  +    printf("\nTests completed.\n");
  +
       printf("\tClosing sockets........................");
  -    for (i = 0; i < SMALL_NUM_SOCKETS; i++){
  +    for (i = 0; i < LARGE_NUM_SOCKETS; i++){
           if (apr_socket_close(s[i]) != APR_SUCCESS){
               printf("Failed!\n");
               exit(-1);
           }
       }
       printf ("OK\n");
  +
       return 0;
   }
  
  
  

Mime
View raw message