Author: wrowe
Date: Sat Oct 13 23:00:00 2007
New Revision: 584487
URL: http://svn.apache.org/viewvc?rev=584487&view=rev
Log:
Enhance our file_io in APR 1.3 with apr_file_pipe_create_ex(),
which should replace apr_file_pipe_create() in apr 2.0. Trivial,
this sets up blocking and nonblocking flavors of either pipe end.
Obviously this code shrinks up threadproc/*/proc.c quite nicely.
This eliminates a major class of portability concerns. On Win32,
I take this one step further and fix the pipe creation logic so
that nonblock pipes are always set to timeout of 0, per Eric's
earlier proc.c patch.
Modified:
apr/apr/trunk/file_io/netware/pipe.c
apr/apr/trunk/file_io/os2/pipe.c
apr/apr/trunk/file_io/unix/pipe.c
apr/apr/trunk/file_io/win32/pipe.c
apr/apr/trunk/include/apr_file_io.h
apr/apr/trunk/include/apr_thread_proc.h
apr/apr/trunk/include/arch/win32/apr_arch_file_io.h
Modified: apr/apr/trunk/file_io/netware/pipe.c
URL: http://svn.apache.org/viewvc/apr/apr/trunk/file_io/netware/pipe.c?rev=584487&r1=584486&r2=584487&view=diff
==============================================================================
--- apr/apr/trunk/file_io/netware/pipe.c (original)
+++ apr/apr/trunk/file_io/netware/pipe.c Sat Oct 13 23:00:00 2007
@@ -177,6 +177,33 @@
return APR_SUCCESS;
}
+APR_DECLARE(apr_status_t) apr_file_pipe_create_ex(apr_file_t **in,
+ apr_file_t **out,
+ apr_int32_t blocking,
+ apr_pool_t *pool)
+{
+ apr_status_t status;
+
+ if ((status = apr_file_pipe_create(in, out, attr->pool))
+ != APR_SUCCESS) {
+ return status;
+ }
+
+ switch (blocking) {
+ case APR_FULL_BLOCK:
+ break;
+ case APR_READ_BLOCK:
+ apr_file_pipe_timeout_set(*in, 0);
+ break;
+ case APR_WRITE_BLOCK:
+ apr_file_pipe_timeout_set(*out, 0);
+ break;
+ default:
+ apr_file_pipe_timeout_set(*in, 0);
+ apr_file_pipe_timeout_set(*out, 0);
+ }
+}
+
APR_DECLARE(apr_status_t) apr_file_namedpipe_create(const char *filename,
apr_fileperms_t perm, apr_pool_t *pool)
{
Modified: apr/apr/trunk/file_io/os2/pipe.c
URL: http://svn.apache.org/viewvc/apr/apr/trunk/file_io/os2/pipe.c?rev=584487&r1=584486&r2=584487&view=diff
==============================================================================
--- apr/apr/trunk/file_io/os2/pipe.c (original)
+++ apr/apr/trunk/file_io/os2/pipe.c Sat Oct 13 23:00:00 2007
@@ -104,6 +104,35 @@
+APR_DECLARE(apr_status_t) apr_file_pipe_create_ex(apr_file_t **in,
+ apr_file_t **out,
+ apr_int32_t blocking,
+ apr_pool_t *pool)
+{
+ apr_status_t status;
+
+ if ((status = apr_file_pipe_create(in, out, attr->pool))
+ != APR_SUCCESS) {
+ return status;
+ }
+
+ switch (blocking) {
+ case APR_FULL_BLOCK:
+ break;
+ case APR_READ_BLOCK:
+ apr_file_pipe_timeout_set(*in, 0);
+ break;
+ case APR_WRITE_BLOCK:
+ apr_file_pipe_timeout_set(*out, 0);
+ break;
+ default:
+ apr_file_pipe_timeout_set(*in, 0);
+ apr_file_pipe_timeout_set(*out, 0);
+ }
+}
+
+
+
APR_DECLARE(apr_status_t) apr_file_namedpipe_create(const char *filename, apr_fileperms_t
perm, apr_pool_t *pool)
{
/* Not yet implemented, interface not suitable */
Modified: apr/apr/trunk/file_io/unix/pipe.c
URL: http://svn.apache.org/viewvc/apr/apr/trunk/file_io/unix/pipe.c?rev=584487&r1=584486&r2=584487&view=diff
==============================================================================
--- apr/apr/trunk/file_io/unix/pipe.c (original)
+++ apr/apr/trunk/file_io/unix/pipe.c Sat Oct 13 23:00:00 2007
@@ -222,6 +222,33 @@
return APR_SUCCESS;
}
+APR_DECLARE(apr_status_t) apr_file_pipe_create_ex(apr_file_t **in,
+ apr_file_t **out,
+ apr_int32_t blocking,
+ apr_pool_t *pool)
+{
+ apr_status_t status;
+
+ if ((status = apr_file_pipe_create(in, out, attr->pool))
+ != APR_SUCCESS) {
+ return status;
+ }
+
+ switch (blocking) {
+ case APR_FULL_BLOCK:
+ break;
+ case APR_READ_BLOCK:
+ apr_file_pipe_timeout_set(*in, 0);
+ break;
+ case APR_WRITE_BLOCK:
+ apr_file_pipe_timeout_set(*out, 0);
+ break;
+ default:
+ apr_file_pipe_timeout_set(*in, 0);
+ apr_file_pipe_timeout_set(*out, 0);
+ }
+}
+
APR_DECLARE(apr_status_t) apr_file_namedpipe_create(const char *filename,
apr_fileperms_t perm, apr_pool_t *pool)
{
Modified: apr/apr/trunk/file_io/win32/pipe.c
URL: http://svn.apache.org/viewvc/apr/apr/trunk/file_io/win32/pipe.c?rev=584487&r1=584486&r2=584487&view=diff
==============================================================================
--- apr/apr/trunk/file_io/win32/pipe.c (original)
+++ apr/apr/trunk/file_io/win32/pipe.c Sat Oct 13 23:00:00 2007
@@ -31,7 +31,8 @@
#endif
#include "apr_arch_misc.h"
-APR_DECLARE(apr_status_t) apr_file_pipe_timeout_set(apr_file_t *thepipe, apr_interval_time_t
timeout)
+APR_DECLARE(apr_status_t) apr_file_pipe_timeout_set(apr_file_t *thepipe,
+ apr_interval_time_t timeout)
{
/* Always OK to unset timeouts */
if (timeout == -1) {
@@ -50,40 +51,26 @@
return APR_SUCCESS;
}
-APR_DECLARE(apr_status_t) apr_file_pipe_timeout_get(apr_file_t *thepipe, apr_interval_time_t
*timeout)
+APR_DECLARE(apr_status_t) apr_file_pipe_timeout_get(apr_file_t *thepipe,
+ apr_interval_time_t *timeout)
{
/* Always OK to get the timeout (even if it's unset ... -1) */
*timeout = thepipe->timeout;
return APR_SUCCESS;
}
-APR_DECLARE(apr_status_t) apr_file_pipe_create(apr_file_t **in, apr_file_t **out, apr_pool_t
*p)
+APR_DECLARE(apr_status_t) apr_file_pipe_create(apr_file_t **in,
+ apr_file_t **out,
+ apr_pool_t *p)
{
/* Unix creates full blocking pipes. */
- return apr_create_nt_pipe(in, out, APR_FULL_BLOCK, p);
+ return apr_file_pipe_create_ex(in, out, APR_FULL_BLOCK, p);
}
-/* apr_create_nt_pipe()
- * An internal (for now) APR function used by apr_proc_create()
- * when setting up pipes to communicate with the child process.
- * apr_create_nt_pipe() allows setting the blocking mode of each end of
- * the pipe when the pipe is created (rather than after the pipe is created).
- * A pipe handle must be opened in full async i/o mode in order to
- * emulate Unix non-blocking pipes with timeouts.
- *
- * In general, we don't want to enable child side pipe handles for async i/o.
- * This prevents us from enabling both ends of the pipe for async i/o in
- * apr_file_pipe_create.
- *
- * Why not use NamedPipes on NT which support setting pipe state to
- * non-blocking? On NT, even though you can set a pipe non-blocking,
- * there is no clean way to set event driven non-zero timeouts (e.g select(),
- * WaitForSingleObject, et. al. will not detect pipe i/o). On NT, you
- * have to poll the pipe to detect i/o on a non-blocking pipe.
- */
-apr_status_t apr_create_nt_pipe(apr_file_t **in, apr_file_t **out,
- apr_int32_t blocking_mode,
- apr_pool_t *p)
+APR_DECLARE(apr_status_t) apr_file_pipe_create_ex(apr_file_t **in,
+ apr_file_t **out,
+ apr_int32_t blocking,
+ apr_pool_t *p)
{
#ifdef _WIN32_WCE
return APR_ENOTIMPL;
@@ -137,11 +124,12 @@
if (apr_os_level >= APR_WIN_NT) {
/* Create the read end of the pipe */
dwOpenMode = PIPE_ACCESS_INBOUND;
- if (blocking_mode == APR_WRITE_BLOCK /* READ_NONBLOCK */
- || blocking_mode == APR_FULL_NONBLOCK) {
+ if (blocking == APR_WRITE_BLOCK /* READ_NONBLOCK */
+ || blocking == APR_FULL_NONBLOCK) {
dwOpenMode |= FILE_FLAG_OVERLAPPED;
(*in)->pOverlapped = (OVERLAPPED*) apr_pcalloc(p, sizeof(OVERLAPPED));
(*in)->pOverlapped->hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
+ (*in)->timeout = 0;
}
dwPipeMode = 0;
@@ -159,11 +147,12 @@
/* Create the write end of the pipe */
dwOpenMode = FILE_ATTRIBUTE_NORMAL;
- if (blocking_mode == APR_READ_BLOCK /* WRITE_NONBLOCK */
- || blocking_mode == APR_FULL_NONBLOCK) {
+ if (blocking == APR_READ_BLOCK /* WRITE_NONBLOCK */
+ || blocking == APR_FULL_NONBLOCK) {
dwOpenMode |= FILE_FLAG_OVERLAPPED;
(*out)->pOverlapped = (OVERLAPPED*) apr_pcalloc(p, sizeof(OVERLAPPED));
(*out)->pOverlapped->hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
+ (*out)->timeout = 0;
}
(*out)->filehand = CreateFile(name,
Modified: apr/apr/trunk/include/apr_file_io.h
URL: http://svn.apache.org/viewvc/apr/apr/trunk/include/apr_file_io.h?rev=584487&r1=584486&r2=584487&view=diff
==============================================================================
--- apr/apr/trunk/include/apr_file_io.h (original)
+++ apr/apr/trunk/include/apr_file_io.h Sat Oct 13 23:00:00 2007
@@ -633,16 +633,45 @@
/**
* Create an anonymous pipe.
- * @param in The file descriptor to use as input to the pipe.
- * @param out The file descriptor to use as output from the pipe.
+ * @param in The newly created pipe's file for writing.
+ * @param out The newly created pipe's file for reading.
* @param pool The pool to operate on.
* @remark By default, the returned file descriptors will be inherited
* by child processes created using apr_proc_create(). This can be
* changed using apr_file_inherit_unset().
+ * @bug Some platforms cannot toggle between blocking and nonblocking,
+ * and when passing a pipe as a standard handle to an application which
+ * does not expect it, a non-blocking stream will fluxor the client app.
+ * @deprecated @see apr_file_pipe_create_ex
*/
APR_DECLARE(apr_status_t) apr_file_pipe_create(apr_file_t **in,
apr_file_t **out,
apr_pool_t *pool);
+
+/**
+ * Create an anonymous pipe which portably supports async timeout options.
+ * @param in The newly created pipe's file for writing.
+ * @param out The newly created pipe's file for reading.
+ * @param blocking one of these values defined in apr_thread_proc.h;
+ * <pre>
+ * APR_FULL_BLOCK
+ * APR_READ_BLOCK
+ * APR_WRITE_BLOCK
+ * APR_FULL_NONBLOCK
+ * </pre>
+ * @remark By default, the returned file descriptors will be inherited
+ * by child processes created using apr_proc_create(). This can be
+ * changed using apr_file_inherit_unset().
+ * @remark Some platforms cannot toggle between blocking and nonblocking,
+ * and when passing a pipe as a standard handle to an application which
+ * does not expect it, a non-blocking stream will fluxor the client app.
+ * Use this function rather than apr_file_pipe_create to create pipes
+ * where one or both ends require non-blocking semantics.
+ */
+APR_DECLARE(apr_status_t) apr_file_pipe_create_ex(apr_file_t **in,
+ apr_file_t **out,
+ apr_int32_t blocking,
+ apr_pool_t *p);
/**
* Create a named pipe.
Modified: apr/apr/trunk/include/apr_thread_proc.h
URL: http://svn.apache.org/viewvc/apr/apr/trunk/include/apr_thread_proc.h?rev=584487&r1=584486&r2=584487&view=diff
==============================================================================
--- apr/apr/trunk/include/apr_thread_proc.h (original)
+++ apr/apr/trunk/include/apr_thread_proc.h Sat Oct 13 23:00:00 2007
@@ -77,9 +77,9 @@
/** @see apr_procattr_io_set */
#define APR_NO_PIPE 0
-/** @see apr_procattr_io_set */
+/** @see apr_procattr_io_set and apr_file_pipe_create_ex */
#define APR_FULL_BLOCK 1
-/** @see apr_procattr_io_set */
+/** @see apr_procattr_io_set and apr_file_pipe_create_ex */
#define APR_FULL_NONBLOCK 2
/** @see apr_procattr_io_set */
#define APR_PARENT_BLOCK 3
@@ -87,6 +87,11 @@
#define APR_CHILD_BLOCK 4
/** @see apr_procattr_io_set */
#define APR_NO_FILE 8
+
+/** @see apr_file_pipe_create_ex */
+#define APR_READ_BLOCK 3
+/** @see apr_file_pipe_create_ex */
+#define APR_WRITE_BLOCK 4
/** @see apr_procattr_io_set
* @note Win32 only effective with version 1.2.12, portably introduced in 1.3.0
Modified: apr/apr/trunk/include/arch/win32/apr_arch_file_io.h
URL: http://svn.apache.org/viewvc/apr/apr/trunk/include/arch/win32/apr_arch_file_io.h?rev=584487&r1=584486&r2=584487&view=diff
==============================================================================
--- apr/apr/trunk/include/arch/win32/apr_arch_file_io.h (original)
+++ apr/apr/trunk/include/arch/win32/apr_arch_file_io.h Sat Oct 13 23:00:00 2007
@@ -251,33 +251,4 @@
apr_status_t file_cleanup(void *);
-/**
- * Internal function to create a Win32/NT pipe that respects some async
- * timeout options.
- * @param in new read end of the created pipe
- * @param out new write end of the created pipe
- * @param blocking_mode one of
- * <pre>
- * APR_FULL_BLOCK
- * APR_READ_BLOCK
- * APR_WRITE_BLOCK
- * APR_FULL_NONBLOCK
- * </pre>
- * @remark It so happens that APR_FULL_BLOCK and APR_FULL_NONBLOCK
- * are common to apr_procattr_io_set() in, out and err modes.
- * Because APR_CHILD_BLOCK and APR_WRITE_BLOCK share the same value,
- * as do APR_PARENT_BLOCK and APR_READ_BLOCK, it's possible to use
- * that value directly for creating the stdout/stderr pipes. When
- * creating the stdin pipe, the values must be transposed.
- * @see apr_procattr_io_set
- */
-apr_status_t apr_create_nt_pipe(apr_file_t **in, apr_file_t **out,
- apr_int32_t blocking_mode,
- apr_pool_t *p);
-
-/** @see apr_create_nt_pipe */
-#define APR_READ_BLOCK 3
-/** @see apr_create_nt_pipe */
-#define APR_WRITE_BLOCK 4
-
#endif /* ! FILE_IO_H */
|