apr-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Graham Leggett <minf...@sharp.fm>
Subject apr_splice_io: A more modern approach to sendfile
Date Sun, 13 Mar 2016 16:21:45 GMT
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 */


Mime
View raw message