Folks,
Please review the attached delta of apr 1.3 to 1.4 changes and
chime in if you believe we are ready to tag 1.4. I suspect we are.
Thanks!
Bill
Index: apr_poll.h
===================================================================
--- apr_poll.h (.../1.3.x/include) (revision 885682)
+++ apr_poll.h (.../1.4.x/include) (revision 885682)
@@ -49,14 +49,37 @@
#define APR_POLLOUT 0x004 /**< Can write without blocking */
#define APR_POLLERR 0x010 /**< Pending error */
#define APR_POLLHUP 0x020 /**< Hangup occurred */
-#define APR_POLLNVAL 0x040 /**< Descriptior invalid */
+#define APR_POLLNVAL 0x040 /**< Descriptor invalid */
/**
* Pollset Flags
*/
-#define APR_POLLSET_THREADSAFE 0x001 /**< Adding or Removing a Descriptor is
thread safe */
-#define APR_POLLSET_NOCOPY 0x002 /**< Descriptors passed to
apr_pollset_create() are not copied */
+#define APR_POLLSET_THREADSAFE 0x001 /**< Adding or removing a descriptor is
+ * thread-safe
+ */
+#define APR_POLLSET_NOCOPY 0x002 /**< Descriptors passed to
apr_pollset_add()
+ * are not copied
+ */
+#define APR_POLLSET_WAKEABLE 0x004 /**< Poll operations are interruptable by
+ * apr_pollset_wakeup()
+ */
+#define APR_POLLSET_NODEFAULT 0x010 /**< Do not try to use the default method
if
+ * the specified non-default method
cannot be
+ * used
+ */
+/**
+ * Pollset Methods
+ */
+typedef enum {
+ APR_POLLSET_DEFAULT, /**< Platform default poll method */
+ APR_POLLSET_SELECT, /**< Poll uses select method */
+ APR_POLLSET_KQUEUE,
+ APR_POLLSET_PORT,
+ APR_POLLSET_EPOLL,
+ APR_POLLSET_POLL
+} apr_pollset_method_e;
+
/** Used in apr_pollfd_t to determine what the apr_descriptor is */
typedef enum {
APR_NO_DESC, /**< nothing here */
@@ -93,18 +116,27 @@
typedef struct apr_pollset_t apr_pollset_t;
/**
- * Setup a pollset object
+ * Set up 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
* @param flags Optional flags to modify the operation of the pollset.
*
- * @remark If flags equals APR_POLLSET_THREADSAFE, then a pollset is
- * created on which it is safe to make concurrent calls to
- * apr_pollset_add(), apr_pollset_remove() and apr_pollset_poll() from
- * separate threads. This feature is only supported on some
- * platforms; the apr_pollset_create() call will fail with
- * APR_ENOTIMPL on platforms where it is not supported.
+ * @remark If flags contains APR_POLLSET_THREADSAFE, then a pollset is
+ * created on which it is safe to make concurrent calls to
+ * apr_pollset_add(), apr_pollset_remove() and apr_pollset_poll()
+ * from separate threads. This feature is only supported on some
+ * platforms; the apr_pollset_create() call will fail with
+ * APR_ENOTIMPL on platforms where it is not supported.
+ * @remark If flags contains APR_POLLSET_WAKEABLE, then a pollset is
+ * created with an additional internal pipe object used for the
+ * apr_pollset_wakeup() call. The actual size of pollset is
+ * in that case size + 1. This feature is only supported on some
+ * platforms; the apr_pollset_create() call will fail with
+ * APR_ENOTIMPL on platforms where it is not supported.
+ * @remark If flags contains APR_POLLSET_NOCOPY, then the apr_pollfd_t
+ * structures passed to apr_pollset_add() are not copied and
+ * must have a lifetime at least as long as the pollset.
*/
APR_DECLARE(apr_status_t) apr_pollset_create(apr_pollset_t **pollset,
apr_uint32_t size,
@@ -112,6 +144,38 @@
apr_uint32_t flags);
/**
+ * Set up 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
+ * @param flags Optional flags to modify the operation of the pollset.
+ * @param method Poll method to use. See @apr_pollset_method_e. If this
+ * method cannot be used, the default method will be used unless the
+ * APR_POLLSET_NODEFAULT flag has been specified.
+ *
+ * @remark If flags contains APR_POLLSET_THREADSAFE, then a pollset is
+ * created on which it is safe to make concurrent calls to
+ * apr_pollset_add(), apr_pollset_remove() and apr_pollset_poll()
+ * from separate threads. This feature is only supported on some
+ * platforms; the apr_pollset_create_ex() call will fail with
+ * APR_ENOTIMPL on platforms where it is not supported.
+ * @remark If flags contains APR_POLLSET_WAKEABLE, then a pollset is
+ * created with additional internal pipe object used for the
+ * apr_pollset_wakeup() call. The actual size of pollset is
+ * in that case size + 1. This feature is only supported on some
+ * platforms; the apr_pollset_create_ex() call will fail with
+ * APR_ENOTIMPL on platforms where it is not supported.
+ * @remark If flags contains APR_POLLSET_NOCOPY, then the apr_pollfd_t
+ * structures passed to apr_pollset_add() are not copied and
+ * must have a lifetime at least as long as the pollset.
+ */
+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);
+
+/**
* Destroy a pollset object
* @param pollset The pollset to destroy
*/
@@ -133,6 +197,15 @@
* with APR_EINTR. Option (1) is recommended, but option (2) is
* allowed for implementations where option (1) is impossible
* or impractical.
+ * @remark If the pollset has been created with APR_POLLSET_NOCOPY, the
+ * apr_pollfd_t structure referenced by descriptor will not be copied
+ * and must have a lifetime at least as long as the pollset.
+ * @remark Do not add the same socket or file descriptor to the same pollset
+ * multiple times, even if the requested events differ for the
+ * different calls to apr_pollset_add(). If the events of interest
+ * for a descriptor change, you must first remove the descriptor
+ * from the pollset with apr_pollset_remove(), then add it again
+ * specifying all requested events.
*/
APR_DECLARE(apr_status_t) apr_pollset_add(apr_pollset_t *pollset,
const apr_pollfd_t *descriptor);
@@ -150,6 +223,9 @@
* with APR_EINTR. Option (1) is recommended, but option (2) is
* allowed for implementations where option (1) is impossible
* or impractical.
+ * @remark apr_pollset_remove() cannot be used to remove a subset of requested
+ * events for a descriptor. The reqevents field in the apr_pollfd_t
+ * parameter must contain the same value when removing as when adding.
*/
APR_DECLARE(apr_status_t) apr_pollset_remove(apr_pollset_t *pollset,
const apr_pollfd_t *descriptor);
@@ -157,31 +233,47 @@
/**
* Block for activity on the descriptor(s) in a pollset
* @param pollset The pollset to use
- * @param timeout The amount of time in microseconds to wait. This is
- * a maximum, not a minimum. If a descriptor is signalled, we
- * will wake up before this time. A negative number means
- * wait until a descriptor is signalled.
+ * @param timeout The amount of time in microseconds to wait. This is a
+ * maximum, not a minimum. If a descriptor is signalled, the
+ * function will return before this time. If timeout is
+ * negative, the function will block until a descriptor is
+ * signalled or until apr_pollset_wakeup() has been called.
* @param num Number of signalled descriptors (output parameter)
* @param descriptors Array of signalled descriptors (output parameter)
+ * @remark APR_EINTR will be returned if the pollset has been created with
+ * APR_POLLSET_WAKEABLE, apr_pollset_wakeup() has been called while
+ * waiting for activity, and there were no signalled descriptors at the
+ * time of the wakeup call.
+ * @remark Multiple signalled conditions for the same descriptor may be
reported
+ * in one or more returned apr_pollfd_t structures, depending on the
+ * implementation.
*/
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);
+/**
+ * Interrupt the blocked apr_pollset_poll() call.
+ * @param pollset The pollset to use
+ * @remark If the pollset was not created with APR_POLLSET_WAKEABLE the
+ * return value is APR_EINIT.
+ */
+APR_DECLARE(apr_status_t) apr_pollset_wakeup(apr_pollset_t *pollset);
/**
* Poll the descriptors in the poll structure
* @param aprset The poll structure we will be using.
* @param numsock The number of descriptors we are polling
* @param nsds The number of descriptors signalled (output parameter)
- * @param timeout The amount of time in microseconds to wait. This is
- * a maximum, not a minimum. If a descriptor is signalled, we
- * will wake up before this time. A negative number means
- * wait until a descriptor is signalled.
+ * @param timeout The amount of time in microseconds to wait. This is a
+ * maximum, not a minimum. If a descriptor is signalled, the
+ * function will return before this time. If timeout is
+ * negative, the function will block until a descriptor is
+ * signalled or until apr_pollset_wakeup() has been called.
* @remark The number of descriptors signalled is returned in the third
argument.
* This is a blocking call, and it will not return until either a
- * descriptor has been signalled, or the timeout has expired.
+ * descriptor has been signalled or the timeout has expired.
* @remark The rtnevents field in the apr_pollfd_t array will only be filled-
* in if the return value is APR_SUCCESS.
*/
@@ -189,11 +281,23 @@
apr_int32_t *nsds,
apr_interval_time_t timeout);
+/**
+ * Return a printable representation of the pollset method.
+ * @param pollset The pollset to use
+ */
+APR_DECLARE(const char *) apr_pollset_method_name(apr_pollset_t *pollset);
+
+/**
+ * Return a printable representation of the default pollset method
+ * (APR_POLLSET_DEFAULT).
+ */
+APR_DECLARE(const char *) apr_poll_method_defname(void);
+
/** Opaque structure used for pollset API */
typedef struct apr_pollcb_t apr_pollcb_t;
/**
- * Setup a pollcb object
+ * Set up a pollcb object
* @param pollcb The pointer in which to return the newly created object
* @param size The maximum number of descriptors that a single _poll can
return.
* @param p The pool from which to allocate the pollcb
@@ -208,15 +312,40 @@
apr_uint32_t flags);
/**
+ * Set up a pollcb object
+ * @param pollcb The pointer in which to return the newly created object
+ * @param size The maximum number of descriptors that a single _poll can
return.
+ * @param p The pool from which to allocate the pollcb
+ * @param flags Optional flags to modify the operation of the pollcb.
+ * @param method Poll method to use. See @apr_pollset_method_e. If this
+ * method cannot be used, the default method will be used unless the
+ * APR_POLLSET_NODEFAULT flag has been specified.
+ *
+ * @remark Pollcb is only supported on some platforms; the
apr_pollcb_create_ex()
+ * call will fail with APR_ENOTIMPL on platforms where it is not supported.
+ */
+APR_DECLARE(apr_status_t) apr_pollcb_create_ex(apr_pollcb_t **pollcb,
+ apr_uint32_t size,
+ apr_pool_t *pool,
+ apr_uint32_t flags,
+ apr_pollset_method_e method);
+
+/**
* Add a socket or file descriptor to a pollcb
* @param pollcb The pollcb to which to add the descriptor
* @param descriptor The descriptor to add
- * @remark If you set client_data in the descriptor, that value
- * will be returned in the client_data field whenever this
- * descriptor is signalled in apr_pollcb_poll().
+ * @remark If you set client_data in the descriptor, that value will be
+ * returned in the client_data field whenever this descriptor is
+ * signalled in apr_pollcb_poll().
* @remark Unlike the apr_pollset API, the descriptor is not copied, and users
- * must retain the memory used by descriptor, as the same pointer will
be
- * returned to them from apr_pollcb_poll.
+ * must retain the memory used by descriptor, as the same pointer will
+ * be returned to them from apr_pollcb_poll.
+ * @remark Do not add the same socket or file descriptor to the same pollcb
+ * multiple times, even if the requested events differ for the
+ * different calls to apr_pollcb_add(). If the events of interest
+ * for a descriptor change, you must first remove the descriptor
+ * from the pollcb with apr_pollcb_remove(), then add it again
+ * specifying all requested events.
*/
APR_DECLARE(apr_status_t) apr_pollcb_add(apr_pollcb_t *pollcb,
apr_pollfd_t *descriptor);
@@ -224,6 +353,9 @@
* Remove a descriptor from a pollcb
* @param pollcb The pollcb from which to remove the descriptor
* @param descriptor The descriptor to remove
+ * @remark apr_pollcb_remove() cannot be used to remove a subset of requested
+ * events for a descriptor. The reqevents field in the apr_pollfd_t
+ * parameter must contain the same value when removing as when adding.
*/
APR_DECLARE(apr_status_t) apr_pollcb_remove(apr_pollcb_t *pollcb,
apr_pollfd_t *descriptor);
@@ -239,12 +371,16 @@
/**
* Block for activity on the descriptor(s) in a pollcb
* @param pollcb The pollcb to use
- * @param timeout The amount of time in microseconds to wait. This is
- * a maximum, not a minimum. If a descriptor is signalled, we
- * will wake up before this time. A negative number means
- * wait until a descriptor is signalled.
- * @param func Callback function to call for each active socket
+ * @param timeout The amount of time in microseconds to wait. This is a
+ * maximum, not a minimum. If a descriptor is signalled, the
+ * function will return before this time. If timeout is
+ * negative, the function will block until a descriptor is
+ * signalled.
+ * @param func Callback function to call for each active descriptor.
* @param baton Opaque baton passed to the callback function.
+ * @remark Multiple signalled conditions for the same descriptor may be
reported
+ * in one or more calls to the callback function, depending on the
+ * implementation.
*/
APR_DECLARE(apr_status_t) apr_pollcb_poll(apr_pollcb_t *pollcb,
apr_interval_time_t timeout,
Index: apr_file_io.h
===================================================================
--- apr_file_io.h (.../1.3.x/include) (revision 885682)
+++ apr_file_io.h (.../1.4.x/include) (revision 885682)
@@ -265,6 +265,15 @@
apr_pool_t *pool);
/**
+ * Create a hard link to the specified file.
+ * @param from_path The full path to the original file (using / on all systems)
+ * @param to_path The full path to the new file (using / on all systems)
+ * @remark Both files must reside on the same device.
+ */
+APR_DECLARE(apr_status_t) apr_file_link(const char *from_path,
+ const char *to_path);
+
+/**
* Copy the specified file to another file.
* @param from_path The full path to the original file (using / on all systems)
* @param to_path The full path to the new file (using / on all systems)
@@ -556,6 +565,18 @@
APR_DECLARE(apr_status_t) apr_file_flush(apr_file_t *thefile);
/**
+ * Transfer all file modified data and metadata to disk.
+ * @param thefile The file descriptor to sync
+ */
+APR_DECLARE(apr_status_t) apr_file_sync(apr_file_t *thefile);
+
+/**
+ * Transfer all file modified data to disk.
+ * @param thefile The file descriptor to sync
+ */
+APR_DECLARE(apr_status_t) apr_file_datasync(apr_file_t *thefile);
+
+/**
* Duplicate the specified file descriptor.
* @param new_file The structure to duplicate into.
* @param old_file The file to duplicate.
Index: apr_global_mutex.h
===================================================================
--- apr_global_mutex.h (.../1.3.x/include) (revision 885682)
+++ apr_global_mutex.h (.../1.4.x/include) (revision 885682)
@@ -121,6 +121,20 @@
APR_DECLARE(apr_status_t) apr_global_mutex_destroy(apr_global_mutex_t *mutex);
/**
+ * Return the name of the lockfile for the mutex, or NULL
+ * if the mutex doesn't use a lock file
+ */
+APR_DECLARE(const char *) apr_global_mutex_lockfile(apr_global_mutex_t *mutex);
+
+/**
+ * Display the name of the mutex, as it relates to the actual method used
+ * for the underlying apr_proc_mutex_t, if any. NULL is returned if
+ * there is no underlying apr_proc_mutex_t.
+ * @param mutex the name of the mutex
+ */
+APR_DECLARE(const char *) apr_global_mutex_name(apr_global_mutex_t *mutex);
+
+/**
* Get the pool used by this global_mutex.
* @return apr_pool_t the pool
*/
@@ -140,6 +154,8 @@
#define apr_global_mutex_trylock apr_proc_mutex_trylock
#define apr_global_mutex_unlock apr_proc_mutex_unlock
#define apr_global_mutex_destroy apr_proc_mutex_destroy
+#define apr_global_mutex_lockfile apr_proc_mutex_lockfile
+#define apr_global_mutex_name apr_proc_mutex_name
#define apr_global_mutex_pool_get apr_proc_mutex_pool_get
#endif
Index: apr_hash.h
===================================================================
--- apr_hash.h (.../1.3.x/include) (revision 885682)
+++ apr_hash.h (.../1.4.x/include) (revision 885682)
@@ -220,6 +220,36 @@
const void *data);
/**
+ * Declaration prototype for the iterator callback function of apr_hash_do().
+ *
+ * @param rec The data passed as the first argument to apr_hash_[v]do()
+ * @param key The key from this iteration of the hash table
+ * @param klen The key length from this iteration of the hash table
+ * @param value The value from this iteration of the hash table
+ * @remark Iteration continues while this callback function returns non-zero.
+ * To export the callback function for apr_hash_do() it must be declared
+ * in the _NONSTD convention.
+ */
+typedef int (apr_hash_do_callback_fn_t)(void *rec, const void *key,
+ apr_ssize_t klen,
+ const void *value);
+
+/**
+ * Iterate over a hash table running the provided function once for every
+ * element in the hash table. The @param comp function will be invoked for
+ * every element in the hash table.
+ *
+ * @param comp The function to run
+ * @param rec The data to pass as the first argument to the function
+ * @param ht The hash table to iterate over
+ * @return FALSE if one of the comp() iterations returned zero; TRUE if all
+ * iterations returned non-zero
+ * @see apr_hash_do_callback_fn_t
+ */
+APR_DECLARE(int) apr_hash_do(apr_hash_do_callback_fn_t *comp,
+ void *rec, const apr_hash_t *ht);
+
+/**
* Get a pointer to the pool which the hash table was created in
*/
APR_POOL_DECLARE_ACCESSOR(hash);
Index: apr_strings.h
===================================================================
--- apr_strings.h (.../1.3.x/include) (revision 885682)
+++ apr_strings.h (.../1.4.x/include) (revision 885682)
@@ -136,7 +136,11 @@
* @param ... The strings to concatenate. The final string must be NULL
* @return The new string
*/
-APR_DECLARE_NONSTD(char *) apr_pstrcat(apr_pool_t *p, ...);
+APR_DECLARE_NONSTD(char *) apr_pstrcat(apr_pool_t *p, ...)
+#if defined(__GNUC__) && __GNUC__ >= 4
+ __attribute__((sentinel))
+#endif
+ ;
/**
* Concatenate multiple strings specified in a writev-style vector
@@ -330,7 +334,7 @@
* digits are prefixed with '0x', in which case it will be treated as
* base 16.
* @return The numeric value of the string. On overflow, errno is set
- * to ERANGE.
+ * to ERANGE. On success, errno is set to 0.
*/
APR_DECLARE(apr_int64_t) apr_strtoi64(const char *buf, char **end, int base);
@@ -338,7 +342,8 @@
* parse a base-10 numeric string into a 64-bit numeric value.
* Equivalent to apr_strtoi64(buf, (char**)NULL, 10).
* @param buf The string to parse
- * @return The numeric value of the string
+ * @return The numeric value of the string. On overflow, errno is set
+ * to ERANGE. On success, errno is set to 0.
*/
APR_DECLARE(apr_int64_t) apr_atoi64(const char *buf);
Index: apr_time.h
===================================================================
--- apr_time.h (.../1.3.x/include) (revision 885682)
+++ apr_time.h (.../1.4.x/include) (revision 885682)
@@ -72,7 +72,10 @@
/** @return apr_time_t as a msec */
#define apr_time_as_msec(time) ((time) / 1000)
-/** @return a second as an apr_time_t */
+/** @return milliseconds as an apr_time_t */
+#define apr_time_from_msec(msec) ((apr_time_t)(msec) * 1000)
+
+/** @return seconds as an apr_time_t */
#define apr_time_from_sec(sec) ((apr_time_t)(sec) * APR_USEC_PER_SEC)
/** @return a second and usec combination as an apr_time_t */
Index: apr_lib.h
===================================================================
--- apr_lib.h (.../1.3.x/include) (revision 885682)
+++ apr_lib.h (.../1.4.x/include) (revision 885682)
@@ -125,9 +125,10 @@
* %%pF same as above, but takes a apr_off_t *
* %%pS same as above, but takes a apr_size_t *
*
+ * %%pA, %%pI, %%pT, %%pp are available from APR 1.0.0 onwards (and in 0.9.x).
* %%pt is only available from APR 1.2.0 onwards.
* %%pm, %%pB, %%pF and %%pS are only available from APR 1.3.0 onwards.
- *
+ *
* The %%p hacks are to force gcc's printf warning code to skip
* over a pointer argument without complaining. This does
* mean that the ANSI-style %%p (output a void * in hex format) won't
Index: apr_want.h
===================================================================
--- apr_want.h (.../1.3.x/include) (revision 885682)
+++ apr_want.h (.../1.4.x/include) (revision 885682)
@@ -91,7 +91,7 @@
struct iovec
{
- char *iov_base;
+ void *iov_base;
size_t iov_len;
};
Index: apr_tables.h
===================================================================
--- apr_tables.h (.../1.3.x/include) (revision 885682)
+++ apr_tables.h (.../1.4.x/include) (revision 885682)
@@ -380,7 +380,11 @@
* @see apr_table_do_callback_fn_t
*/
APR_DECLARE_NONSTD(int) apr_table_do(apr_table_do_callback_fn_t *comp,
- void *rec, const apr_table_t *t, ...);
+ void *rec, const apr_table_t *t, ...)
+#if defined(__GNUC__) && __GNUC__ >= 4
+ __attribute__((sentinel))
+#endif
+ ;
/**
* Iterate over a table running the provided function once for every
Index: apr_network_io.h
===================================================================
--- apr_network_io.h (.../1.3.x/include) (revision 885682)
+++ apr_network_io.h (.../1.4.x/include) (revision 885682)
@@ -348,6 +348,21 @@
apr_sockaddr_t *sa);
/**
+ * Determine whether the receive part of the socket has been closed by
+ * the peer (such that a subsequent call to apr_socket_read would
+ * return APR_EOF), if the socket's receive buffer is empty. This
+ * function does not block waiting for I/O.
+ *
+ * @param socket The socket to check
+ * @param atreadeof If APR_SUCCESS is returned, *atreadeof is set to
+ * non-zero if a subsequent read would return APR_EOF
+ * @return an error is returned if it was not possible to determine the
+ * status, in which case *atreadeof is not changed.
+ */
+APR_DECLARE(apr_status_t) apr_socket_atreadeof(apr_socket_t *sock,
+ int *atreadeof);
+
+/**
* Create apr_sockaddr_t from hostname, address family, and port.
* @param sa The new apr_sockaddr_t.
* @param hostname The hostname or numeric address string to resolve/parse, or
Index: apr_version.h
===================================================================
--- apr_version.h (.../1.3.x/include) (revision 885682)
+++ apr_version.h (.../1.4.x/include) (revision 885682)
@@ -53,13 +53,13 @@
* Minor API changes that do not cause binary compatibility problems.
* Reset to 0 when upgrading APR_MAJOR_VERSION
*/
-#define APR_MINOR_VERSION 3
+#define APR_MINOR_VERSION 4
/** patch level
* The Patch Level never includes API changes, simply bug fixes.
* Reset to 0 when upgrading APR_MINOR_VERSION
*/
-#define APR_PATCH_VERSION 10
+#define APR_PATCH_VERSION 0
/**
* The symbol APR_IS_DEV_VERSION is only defined for internal,