To continue the recent discussions on the problems in the current
apr_poll API, here's a patch for apr_poll.h that illustrates my
proposed fix.

What I'm proposing here is to split the API into two parts:

 - A lightweight, single-function poll API for use (only!)
   with very small sets of descriptors.  This is basically
   the current implementation, but with a limit on the number
   of descriptors that it will accept.  With this limit, we
   can put the temporary pollfd array on the stack in apr_poll()
   to eliminate the memory leak.

 - A general-purpose poll API for larger sets of descriptors.
   This one is an abstract data type, accessible only through
   functions, so that we can do internal optimizations in the
   future (like replacing poll with /dev/poll on supported
   platforms).

Comments welcome...

Thanks,
Brian


Index: include/apr_poll.h
===================================================================
RCS file: /home/cvs/apr/include/apr_poll.h,v
retrieving revision 1.2
diff -u -r1.2 apr_poll.h
--- include/apr_poll.h  11 Jul 2002 14:39:04 -0000      1.2
+++ include/apr_poll.h  27 Jul 2002 02:42:12 -0000
@@ -55,7 +55,7 @@
 #ifndef APR_POLL_H
 #define APR_POLL_H
 /**
- * @file apr_network_io.h
+ * @file apr_poll.h
  * @brief APR Network library
  */
 /**
@@ -124,6 +124,9 @@
                                          apr_int32_t num,
                                          apr_pool_t *cont);
 
+/* Maximum number of descriptors that apr_poll() will accept */
+#define APR_SMALL_POLL_MAX 16
+
 /**
  * Poll the sockets in the poll structure
  * @param aprset The poll structure we will be using. 
@@ -135,6 +138,9 @@
  *                wait until a socket is signalled.
  * @remark
  * <PRE>
+ * The number of descriptors may not exceed APR_SMALL_POLL_MAX.  For
+ * larger numbers of descriptors, please see the apr_pollset_* functions.
+ *
  * The number of sockets signalled is returned in the second argument. 
  *
  *        This is a blocking call, and it will not return until either a 
@@ -218,6 +224,65 @@
 APR_DECLARE(apr_status_t) apr_poll_revents_get(apr_int16_t *event, 
                                           apr_socket_t *sock,
                                           apr_pollfd_t *aprset);
+
+
+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 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_create(apr_pollset_t **pollset,
+                                             const apr_pollfd_t *descriptors,
+                                             apr_uint32_t num,
+                                             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 one or more descriptors to a pollset
+ * @param pollset The pollset to which to add the descriptors
+ * @param descriptors The vector of descriptors to add
+ * @param num The number of elements in the descriptors array
+ */
+APR_DECLARE(apr_status_t) apr_pollset_add(apr_pollset_t *pollset,
+                                          const apr_pollfd_t *descriptors,
+                                          apr_uint32_t num);
+
+/**
+ * Remove one or more descriptors from a pollset
+ * @param pollset The pollset from which to remove the descriptors
+ * @param descriptors The vector of descriptors to remove
+ * @param num The number of elements in the descriptors array
+ */
+APR_DECLARE(apr_status_t) apr_pollset_remove(apr_pollset_t *pollset,
+                                             const apr_pollfd_t *descriptors,
+                                             apr_uint32_t num);
+
+/**
+ * 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_uint32_t *num,
+                                           const apr_pollfd_t **descriptors);
+
 
 #ifdef __cplusplus
 }

Reply via email to