Hi all,

Various platforms have richer support for zero copy than they used to, no 
longer are we limited to just “send file to socket”.

In order to support this portably, I propose the following API, with 4 simple 
function calls covering the 4 possible combinations of apr_file_t and 
apr_socket_t. This allows us to ultimately deprecate and replace 
apr_socket_sendfile() with something more flexible.

In httpd it will allow us to form creative use of pipes in addition to just 
sockets.

Regards,
Graham
--

Index: include/apr_splice_io.h
===================================================================
--- include/apr_splice_io.h     (revision 0)
+++ include/apr_splice_io.h     (working copy)
@@ -0,0 +1,121 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef APR_SPLICE_IO_H
+#define APR_SPLICE_IO_H
+/**
+ * @file apr_splice_io.h
+ * @brief APR File/Network splice library
+ */
+
+#include "apr.h"
+#include "apr_pools.h"
+#include "apr_file_io.h"
+#include "apr_network_io.h"
+#include "apr_errno.h"
+
+/**
+ * Send from an open socket to a socket, along with optional headers and 
trailers.
+ * @param dest The socket to which we're writing
+ * @param src The socket from which to read
+ * @param hdtr A structure containing the headers and trailers to send
+ * @param offset Offset into the file where we should begin writing
+ * @param len (input)  - Number of bytes to send from the file
+ *            (output) - Number of bytes actually sent,
+ *                       including headers, file, and trailers
+ * @param flags APR flags that are mapped to OS specific flags
+ * @remark This functions acts like a blocking write by default.  To change
+ *         this behavior, use apr_socket_timeout_set() or the
+ *         APR_SO_NONBLOCK socket option.
+ * The number of bytes actually sent is stored in the len parameter.
+ *
+ * On platforms where this is supported, this function will be handled
+ * using splice or sendfile. If neither splice nor sendfile are available,
+ * APR_ENOTIMPL is returned.
+ */
+APR_DECLARE(apr_status_t) apr_splice_socket(apr_socket_t *dest,
+        apr_socket_t *src, apr_hdtr_t *hdtr, apr_off_t offset, apr_size_t *len,
+        apr_int32_t flags);
+
+/**
+ * Send from an open file/pipe to a socket, along with optional headers and 
trailers.
+ * @param dest The socket to which we're writing
+ * @param src The file/pipe from which to read
+ * @param hdtr A structure containing the headers and trailers to send
+ * @param offset Offset into the file where we should begin writing
+ * @param len (input)  - Number of bytes to send from the file
+ *            (output) - Number of bytes actually sent,
+ *                       including headers, file, and trailers
+ * @param flags APR flags that are mapped to OS specific flags
+ * @remark This functions acts like a blocking write by default.  To change
+ *         this behavior, use apr_socket_timeout_set() or the
+ *         APR_SO_NONBLOCK socket option.
+ * The number of bytes actually sent is stored in the len parameter.
+ *
+ * On platforms where this is supported, this function will be handled
+ * using splice or sendfile. If neither splice nor sendfile are available,
+ * APR_ENOTIMPL is returned.
+ */
+APR_DECLARE(apr_status_t) apr_splice_socket_file(apr_socket_t *dest,
+        apr_file_t *src, apr_hdtr_t *hdtr, apr_off_t offset, apr_size_t *len,
+        apr_int32_t flags);
+
+/**
+ * Send from one file or pipe to another file or pipe, along with optional
+ * headers and trailers.
+ * @param dest The file/pipe to which we're writing
+ * @param src The source file/pipe from which to read
+ * @param hdtr A structure containing the headers and trailers to send
+ * @param offset Offset into the file where we should begin writing
+ * @param len (input)  - Number of bytes to send from the file
+ *            (output) - Number of bytes actually sent,
+ *                       including headers, file, and trailers
+ * @param flags APR flags that are mapped to OS specific flags
+ * @remark This functions acts like a blocking write by default.  To change
+ *         this behavior, use apr_socket_timeout_set() or the
+ *         APR_SO_NONBLOCK socket option.
+ * The number of bytes actually sent is stored in the len parameter.
+ *
+ * On platforms where this is supported, this function will be handled
+ * using splice or sendfile. If neither splice nor sendfile are available,
+ * APR_ENOTIMPL is returned.
+ */
+APR_DECLARE(apr_status_t) apr_splice_file(apr_file_t *dest, apr_file_t *src,
+        apr_hdtr_t *hdtr, apr_off_t offset, apr_size_t *len, apr_int32_t 
flags);
+
+/**
+ * Send from a socket to a file or pipe, along with optional headers and 
trailers.
+ * @param dest The file/pipe to which we're writing
+ * @param src The source socket from which to read
+ * @param hdtr A structure containing the headers and trailers to send
+ * @param offset Offset into the file where we should begin writing
+ * @param len (input)  - Number of bytes to send from the file
+ *            (output) - Number of bytes actually sent,
+ *                       including headers, file, and trailers
+ * @param flags APR flags that are mapped to OS specific flags
+ * @remark This functions acts like a blocking write by default.  To change
+ *         this behavior, use apr_socket_timeout_set() or the
+ *         APR_SO_NONBLOCK socket option.
+ * The number of bytes actually sent is stored in the len parameter.
+ *
+ * On platforms where this is supported, this function will be handled
+ * using splice or sendfile. If neither splice nor sendfile are available,
+ * APR_ENOTIMPL is returned.
+ */
+APR_DECLARE(apr_status_t) apr_splice_file_socket(apr_file_t *dest, 
apr_socket_t *src,
+        apr_hdtr_t *hdtr, apr_off_t offset, apr_size_t *len, apr_int32_t 
flags);
+
+#endif /* ! APR_SPLICE_IO_H */

Reply via email to