Fix up native_non_blocking() example and change it to be a complete
working example of wrapping Linux's sendfile system call.
diff --git a/asio/include/asio/basic_socket.hpp b/asio/include/asio/basic_socket.hpp
index ae43e1b..71f01f1 100644
--- a/asio/include/asio/basic_socket.hpp
+++ b/asio/include/asio/basic_socket.hpp
@@ -991,18 +991,19 @@
* This function is intended to allow the encapsulation of arbitrary
* non-blocking system calls as asynchronous operations, in a way that is
* transparent to the user of the socket object. The following example
- * illustrates how a @c sendfile system call might be encapsulated:
+ * illustrates how Linux's @c sendfile system call might be encapsulated:
* @code template <typename Handler>
* struct sendfile_op
* {
* tcp::socket& sock_;
* int fd_;
* Handler handler_;
+ * off_t offset_;
+ * std::size_t total_bytes_transferred_;
*
* // Function call operator meeting WriteHandler requirements.
* // Used as the handler for the async_write_some operation.
- * void operator()(asio::error_code ec,
- * std::size_t bytes_transferred)
+ * void operator()(asio::error_code ec, std::size_t)
* {
* // Put the underlying socket into non-blocking mode.
* if (!ec)
@@ -1015,10 +1016,10 @@
* {
* // Try the system call.
* errno = 0;
- * int n = ::sendfile(sock_.native_handle(), fd_, ...);
- * ec = asio::error_code(
- * n < 0 ? errno : 0,
- * asio::error::system_category());
+ * int n = ::sendfile(sock_.native_handle(), fd_, &offset_, 65536);
+ * ec = asio::error_code(n < 0 ? errno : 0,
+ * asio::error::get_system_category());
+ * total_bytes_transferred_ += ec ? 0 : n;
*
* // Retry operation immediately if interrupted by signal.
* if (ec == asio::error::interrupted)
@@ -1033,21 +1034,26 @@
* return;
* }
*
- * // The operation is done. Exit loop so we can call the handler.
- * bytes_transferred = ec ? 0 : n;
- * break;
+ * if (ec || n == 0)
+ * {
+ * // An error occurred, or we have reached the end of the file.
+ * // Either way we must exit the loop so we can call the handler.
+ * break;
+ * }
+ *
+ * // Loop around to try calling sendfile again.
* }
* }
*
* // Pass result back to user's handler.
- * handler_(ec, bytes_transferred);
+ * handler_(ec, total_bytes_transferred_);
* }
* };
*
* template <typename Handler>
* void async_sendfile(tcp::socket& sock, int fd, Handler h)
* {
- * sendfile_op op = { sock, fd, h };
+ * sendfile_op<Handler> op = { sock, fd, h, 0, 0 };
* sock.async_write_some(asio::null_buffers(), op);
* } @endcode
*/
@@ -1075,18 +1081,19 @@
* This function is intended to allow the encapsulation of arbitrary
* non-blocking system calls as asynchronous operations, in a way that is
* transparent to the user of the socket object. The following example
- * illustrates how a @c sendfile system call might be encapsulated:
+ * illustrates how Linux's @c sendfile system call might be encapsulated:
* @code template <typename Handler>
* struct sendfile_op
* {
* tcp::socket& sock_;
* int fd_;
* Handler handler_;
+ * off_t offset_;
+ * std::size_t total_bytes_transferred_;
*
* // Function call operator meeting WriteHandler requirements.
* // Used as the handler for the async_write_some operation.
- * void operator()(asio::error_code ec,
- * std::size_t bytes_transferred)
+ * void operator()(asio::error_code ec, std::size_t)
* {
* // Put the underlying socket into non-blocking mode.
* if (!ec)
@@ -1099,10 +1106,10 @@
* {
* // Try the system call.
* errno = 0;
- * int n = ::sendfile(sock_.native_handle(), fd_, ...);
- * ec = asio::error_code(
- * n < 0 ? errno : 0,
- * asio::error::system_category());
+ * int n = ::sendfile(sock_.native_handle(), fd_, &offset_, 65536);
+ * ec = asio::error_code(n < 0 ? errno : 0,
+ * asio::error::get_system_category());
+ * total_bytes_transferred_ += ec ? 0 : n;
*
* // Retry operation immediately if interrupted by signal.
* if (ec == asio::error::interrupted)
@@ -1117,21 +1124,26 @@
* return;
* }
*
- * // The operation is done. Exit loop so we can call the handler.
- * bytes_transferred = ec ? 0 : n;
- * break;
+ * if (ec || n == 0)
+ * {
+ * // An error occurred, or we have reached the end of the file.
+ * // Either way we must exit the loop so we can call the handler.
+ * break;
+ * }
+ *
+ * // Loop around to try calling sendfile again.
* }
* }
*
* // Pass result back to user's handler.
- * handler_(ec, bytes_transferred);
+ * handler_(ec, total_bytes_transferred_);
* }
* };
*
* template <typename Handler>
* void async_sendfile(tcp::socket& sock, int fd, Handler h)
* {
- * sendfile_op op = { sock, fd, h };
+ * sendfile_op<Handler> op = { sock, fd, h, 0, 0 };
* sock.async_write_some(asio::null_buffers(), op);
* } @endcode
*/
@@ -1161,18 +1173,19 @@
* This function is intended to allow the encapsulation of arbitrary
* non-blocking system calls as asynchronous operations, in a way that is
* transparent to the user of the socket object. The following example
- * illustrates how a @c sendfile system call might be encapsulated:
+ * illustrates how Linux's @c sendfile system call might be encapsulated:
* @code template <typename Handler>
* struct sendfile_op
* {
* tcp::socket& sock_;
* int fd_;
* Handler handler_;
+ * off_t offset_;
+ * std::size_t total_bytes_transferred_;
*
* // Function call operator meeting WriteHandler requirements.
* // Used as the handler for the async_write_some operation.
- * void operator()(asio::error_code ec,
- * std::size_t bytes_transferred)
+ * void operator()(asio::error_code ec, std::size_t)
* {
* // Put the underlying socket into non-blocking mode.
* if (!ec)
@@ -1185,10 +1198,10 @@
* {
* // Try the system call.
* errno = 0;
- * int n = ::sendfile(sock_.native_handle(), fd_, ...);
- * ec = asio::error_code(
- * n < 0 ? errno : 0,
- * asio::error::system_category());
+ * int n = ::sendfile(sock_.native_handle(), fd_, &offset_, 65536);
+ * ec = asio::error_code(n < 0 ? errno : 0,
+ * asio::error::get_system_category());
+ * total_bytes_transferred_ += ec ? 0 : n;
*
* // Retry operation immediately if interrupted by signal.
* if (ec == asio::error::interrupted)
@@ -1203,21 +1216,26 @@
* return;
* }
*
- * // The operation is done. Exit loop so we can call the handler.
- * bytes_transferred = ec ? 0 : n;
- * break;
+ * if (ec || n == 0)
+ * {
+ * // An error occurred, or we have reached the end of the file.
+ * // Either way we must exit the loop so we can call the handler.
+ * break;
+ * }
+ *
+ * // Loop around to try calling sendfile again.
* }
* }
*
* // Pass result back to user's handler.
- * handler_(ec, bytes_transferred);
+ * handler_(ec, total_bytes_transferred_);
* }
* };
*
* template <typename Handler>
* void async_sendfile(tcp::socket& sock, int fd, Handler h)
* {
- * sendfile_op op = { sock, fd, h };
+ * sendfile_op<Handler> op = { sock, fd, h, 0, 0 };
* sock.async_write_some(asio::null_buffers(), op);
* } @endcode
*/
diff --git a/asio/src/doc/reference.qbk b/asio/src/doc/reference.qbk
index 869e7c9..61d02cf 100644
--- a/asio/src/doc/reference.qbk
+++ b/asio/src/doc/reference.qbk
@@ -16,6 +16,7 @@
[include requirements/AsyncReadStream.qbk]
[include requirements/AsyncWriteStream.qbk]
[include requirements/CompletionHandler.qbk]
+[include requirements/ComposedConnectHandler.qbk]
[include requirements/ConnectHandler.qbk]
[include requirements/ConstBufferSequence.qbk]
[include requirements/ConvertibleToConstBuffer.qbk]
@@ -6171,7 +6172,7 @@
[heading Example]
-This function is intended to allow the encapsulation of arbitrary non-blocking system calls as asynchronous operations, in a way that is transparent to the user of the socket object. The following example illustrates how a `sendfile` system call might be encapsulated:
+This function is intended to allow the encapsulation of arbitrary non-blocking system calls as asynchronous operations, in a way that is transparent to the user of the socket object. The following example illustrates how Linux's `sendfile` system call might be encapsulated:
template <typename Handler>
struct sendfile_op
@@ -6179,11 +6180,12 @@
tcp::socket& sock_;
int fd_;
Handler handler_;
+ off_t offset_;
+ std::size_t total_bytes_transferred_;
// Function call operator meeting WriteHandler requirements.
// Used as the handler for the async_write_some operation.
- void operator()(asio::error_code ec,
- std::size_t bytes_transferred)
+ void operator()(asio::error_code ec, std::size_t)
{
// Put the underlying socket into non-blocking mode.
if (!ec)
@@ -6196,10 +6198,10 @@
{
// Try the system call.
errno = 0;
- int n = ::sendfile(sock_.native_handle(), fd_, ...);
- ec = asio::error_code(
- n < 0 ? errno : 0,
- asio::error::system_category());
+ int n = ::sendfile(sock_.native_handle(), fd_, &offset_, 65536);
+ ec = asio::error_code(n < 0 ? errno : 0,
+ asio::error::get_system_category());
+ total_bytes_transferred_ += ec ? 0 : n;
// Retry operation immediately if interrupted by signal.
if (ec == asio::error::interrupted)
@@ -6214,21 +6216,26 @@
return;
}
- // The operation is done. Exit loop so we can call the handler.
- bytes_transferred = ec ? 0 : n;
- break;
+ if (ec || n == 0)
+ {
+ // An error occurred, or we have reached the end of the file.
+ // Either way we must exit the loop so we can call the handler.
+ break;
+ }
+
+ // Loop around to try calling sendfile again.
}
}
// Pass result back to user's handler.
- handler_(ec, bytes_transferred);
+ handler_(ec, total_bytes_transferred_);
}
};
template <typename Handler>
void async_sendfile(tcp::socket& sock, int fd, Handler h)
{
- sendfile_op op = { sock, fd, h };
+ sendfile_op<Handler> op = { sock, fd, h, 0, 0 };
sock.async_write_some(asio::null_buffers(), op);
}
@@ -6280,7 +6287,7 @@
[heading Example]
-This function is intended to allow the encapsulation of arbitrary non-blocking system calls as asynchronous operations, in a way that is transparent to the user of the socket object. The following example illustrates how a `sendfile` system call might be encapsulated:
+This function is intended to allow the encapsulation of arbitrary non-blocking system calls as asynchronous operations, in a way that is transparent to the user of the socket object. The following example illustrates how Linux's `sendfile` system call might be encapsulated:
template <typename Handler>
struct sendfile_op
@@ -6288,11 +6295,12 @@
tcp::socket& sock_;
int fd_;
Handler handler_;
+ off_t offset_;
+ std::size_t total_bytes_transferred_;
// Function call operator meeting WriteHandler requirements.
// Used as the handler for the async_write_some operation.
- void operator()(asio::error_code ec,
- std::size_t bytes_transferred)
+ void operator()(asio::error_code ec, std::size_t)
{
// Put the underlying socket into non-blocking mode.
if (!ec)
@@ -6305,10 +6313,10 @@
{
// Try the system call.
errno = 0;
- int n = ::sendfile(sock_.native_handle(), fd_, ...);
- ec = asio::error_code(
- n < 0 ? errno : 0,
- asio::error::system_category());
+ int n = ::sendfile(sock_.native_handle(), fd_, &offset_, 65536);
+ ec = asio::error_code(n < 0 ? errno : 0,
+ asio::error::get_system_category());
+ total_bytes_transferred_ += ec ? 0 : n;
// Retry operation immediately if interrupted by signal.
if (ec == asio::error::interrupted)
@@ -6323,21 +6331,26 @@
return;
}
- // The operation is done. Exit loop so we can call the handler.
- bytes_transferred = ec ? 0 : n;
- break;
+ if (ec || n == 0)
+ {
+ // An error occurred, or we have reached the end of the file.
+ // Either way we must exit the loop so we can call the handler.
+ break;
+ }
+
+ // Loop around to try calling sendfile again.
}
}
// Pass result back to user's handler.
- handler_(ec, bytes_transferred);
+ handler_(ec, total_bytes_transferred_);
}
};
template <typename Handler>
void async_sendfile(tcp::socket& sock, int fd, Handler h)
{
- sendfile_op op = { sock, fd, h };
+ sendfile_op<Handler> op = { sock, fd, h, 0, 0 };
sock.async_write_some(asio::null_buffers(), op);
}
@@ -6382,7 +6395,7 @@
[heading Example]
-This function is intended to allow the encapsulation of arbitrary non-blocking system calls as asynchronous operations, in a way that is transparent to the user of the socket object. The following example illustrates how a `sendfile` system call might be encapsulated:
+This function is intended to allow the encapsulation of arbitrary non-blocking system calls as asynchronous operations, in a way that is transparent to the user of the socket object. The following example illustrates how Linux's `sendfile` system call might be encapsulated:
template <typename Handler>
struct sendfile_op
@@ -6390,11 +6403,12 @@
tcp::socket& sock_;
int fd_;
Handler handler_;
+ off_t offset_;
+ std::size_t total_bytes_transferred_;
// Function call operator meeting WriteHandler requirements.
// Used as the handler for the async_write_some operation.
- void operator()(asio::error_code ec,
- std::size_t bytes_transferred)
+ void operator()(asio::error_code ec, std::size_t)
{
// Put the underlying socket into non-blocking mode.
if (!ec)
@@ -6407,10 +6421,10 @@
{
// Try the system call.
errno = 0;
- int n = ::sendfile(sock_.native_handle(), fd_, ...);
- ec = asio::error_code(
- n < 0 ? errno : 0,
- asio::error::system_category());
+ int n = ::sendfile(sock_.native_handle(), fd_, &offset_, 65536);
+ ec = asio::error_code(n < 0 ? errno : 0,
+ asio::error::get_system_category());
+ total_bytes_transferred_ += ec ? 0 : n;
// Retry operation immediately if interrupted by signal.
if (ec == asio::error::interrupted)
@@ -6425,21 +6439,26 @@
return;
}
- // The operation is done. Exit loop so we can call the handler.
- bytes_transferred = ec ? 0 : n;
- break;
+ if (ec || n == 0)
+ {
+ // An error occurred, or we have reached the end of the file.
+ // Either way we must exit the loop so we can call the handler.
+ break;
+ }
+
+ // Loop around to try calling sendfile again.
}
}
// Pass result back to user's handler.
- handler_(ec, bytes_transferred);
+ handler_(ec, total_bytes_transferred_);
}
};
template <typename Handler>
void async_sendfile(tcp::socket& sock, int fd, Handler h)
{
- sendfile_op op = { sock, fd, h };
+ sendfile_op<Handler> op = { sock, fd, h, 0, 0 };
sock.async_write_some(asio::null_buffers(), op);
}
@@ -13087,7 +13106,7 @@
[heading Example]
-This function is intended to allow the encapsulation of arbitrary non-blocking system calls as asynchronous operations, in a way that is transparent to the user of the socket object. The following example illustrates how a `sendfile` system call might be encapsulated:
+This function is intended to allow the encapsulation of arbitrary non-blocking system calls as asynchronous operations, in a way that is transparent to the user of the socket object. The following example illustrates how Linux's `sendfile` system call might be encapsulated:
template <typename Handler>
struct sendfile_op
@@ -13095,11 +13114,12 @@
tcp::socket& sock_;
int fd_;
Handler handler_;
+ off_t offset_;
+ std::size_t total_bytes_transferred_;
// Function call operator meeting WriteHandler requirements.
// Used as the handler for the async_write_some operation.
- void operator()(asio::error_code ec,
- std::size_t bytes_transferred)
+ void operator()(asio::error_code ec, std::size_t)
{
// Put the underlying socket into non-blocking mode.
if (!ec)
@@ -13112,10 +13132,10 @@
{
// Try the system call.
errno = 0;
- int n = ::sendfile(sock_.native_handle(), fd_, ...);
- ec = asio::error_code(
- n < 0 ? errno : 0,
- asio::error::system_category());
+ int n = ::sendfile(sock_.native_handle(), fd_, &offset_, 65536);
+ ec = asio::error_code(n < 0 ? errno : 0,
+ asio::error::get_system_category());
+ total_bytes_transferred_ += ec ? 0 : n;
// Retry operation immediately if interrupted by signal.
if (ec == asio::error::interrupted)
@@ -13130,21 +13150,26 @@
return;
}
- // The operation is done. Exit loop so we can call the handler.
- bytes_transferred = ec ? 0 : n;
- break;
+ if (ec || n == 0)
+ {
+ // An error occurred, or we have reached the end of the file.
+ // Either way we must exit the loop so we can call the handler.
+ break;
+ }
+
+ // Loop around to try calling sendfile again.
}
}
// Pass result back to user's handler.
- handler_(ec, bytes_transferred);
+ handler_(ec, total_bytes_transferred_);
}
};
template <typename Handler>
void async_sendfile(tcp::socket& sock, int fd, Handler h)
{
- sendfile_op op = { sock, fd, h };
+ sendfile_op<Handler> op = { sock, fd, h, 0, 0 };
sock.async_write_some(asio::null_buffers(), op);
}
@@ -13196,7 +13221,7 @@
[heading Example]
-This function is intended to allow the encapsulation of arbitrary non-blocking system calls as asynchronous operations, in a way that is transparent to the user of the socket object. The following example illustrates how a `sendfile` system call might be encapsulated:
+This function is intended to allow the encapsulation of arbitrary non-blocking system calls as asynchronous operations, in a way that is transparent to the user of the socket object. The following example illustrates how Linux's `sendfile` system call might be encapsulated:
template <typename Handler>
struct sendfile_op
@@ -13204,11 +13229,12 @@
tcp::socket& sock_;
int fd_;
Handler handler_;
+ off_t offset_;
+ std::size_t total_bytes_transferred_;
// Function call operator meeting WriteHandler requirements.
// Used as the handler for the async_write_some operation.
- void operator()(asio::error_code ec,
- std::size_t bytes_transferred)
+ void operator()(asio::error_code ec, std::size_t)
{
// Put the underlying socket into non-blocking mode.
if (!ec)
@@ -13221,10 +13247,10 @@
{
// Try the system call.
errno = 0;
- int n = ::sendfile(sock_.native_handle(), fd_, ...);
- ec = asio::error_code(
- n < 0 ? errno : 0,
- asio::error::system_category());
+ int n = ::sendfile(sock_.native_handle(), fd_, &offset_, 65536);
+ ec = asio::error_code(n < 0 ? errno : 0,
+ asio::error::get_system_category());
+ total_bytes_transferred_ += ec ? 0 : n;
// Retry operation immediately if interrupted by signal.
if (ec == asio::error::interrupted)
@@ -13239,21 +13265,26 @@
return;
}
- // The operation is done. Exit loop so we can call the handler.
- bytes_transferred = ec ? 0 : n;
- break;
+ if (ec || n == 0)
+ {
+ // An error occurred, or we have reached the end of the file.
+ // Either way we must exit the loop so we can call the handler.
+ break;
+ }
+
+ // Loop around to try calling sendfile again.
}
}
// Pass result back to user's handler.
- handler_(ec, bytes_transferred);
+ handler_(ec, total_bytes_transferred_);
}
};
template <typename Handler>
void async_sendfile(tcp::socket& sock, int fd, Handler h)
{
- sendfile_op op = { sock, fd, h };
+ sendfile_op<Handler> op = { sock, fd, h, 0, 0 };
sock.async_write_some(asio::null_buffers(), op);
}
@@ -13298,7 +13329,7 @@
[heading Example]
-This function is intended to allow the encapsulation of arbitrary non-blocking system calls as asynchronous operations, in a way that is transparent to the user of the socket object. The following example illustrates how a `sendfile` system call might be encapsulated:
+This function is intended to allow the encapsulation of arbitrary non-blocking system calls as asynchronous operations, in a way that is transparent to the user of the socket object. The following example illustrates how Linux's `sendfile` system call might be encapsulated:
template <typename Handler>
struct sendfile_op
@@ -13306,11 +13337,12 @@
tcp::socket& sock_;
int fd_;
Handler handler_;
+ off_t offset_;
+ std::size_t total_bytes_transferred_;
// Function call operator meeting WriteHandler requirements.
// Used as the handler for the async_write_some operation.
- void operator()(asio::error_code ec,
- std::size_t bytes_transferred)
+ void operator()(asio::error_code ec, std::size_t)
{
// Put the underlying socket into non-blocking mode.
if (!ec)
@@ -13323,10 +13355,10 @@
{
// Try the system call.
errno = 0;
- int n = ::sendfile(sock_.native_handle(), fd_, ...);
- ec = asio::error_code(
- n < 0 ? errno : 0,
- asio::error::system_category());
+ int n = ::sendfile(sock_.native_handle(), fd_, &offset_, 65536);
+ ec = asio::error_code(n < 0 ? errno : 0,
+ asio::error::get_system_category());
+ total_bytes_transferred_ += ec ? 0 : n;
// Retry operation immediately if interrupted by signal.
if (ec == asio::error::interrupted)
@@ -13341,21 +13373,26 @@
return;
}
- // The operation is done. Exit loop so we can call the handler.
- bytes_transferred = ec ? 0 : n;
- break;
+ if (ec || n == 0)
+ {
+ // An error occurred, or we have reached the end of the file.
+ // Either way we must exit the loop so we can call the handler.
+ break;
+ }
+
+ // Loop around to try calling sendfile again.
}
}
// Pass result back to user's handler.
- handler_(ec, bytes_transferred);
+ handler_(ec, total_bytes_transferred_);
}
};
template <typename Handler>
void async_sendfile(tcp::socket& sock, int fd, Handler h)
{
- sendfile_op op = { sock, fd, h };
+ sendfile_op<Handler> op = { sock, fd, h, 0, 0 };
sock.async_write_some(asio::null_buffers(), op);
}
@@ -18293,7 +18330,7 @@
[heading Example]
-This function is intended to allow the encapsulation of arbitrary non-blocking system calls as asynchronous operations, in a way that is transparent to the user of the socket object. The following example illustrates how a `sendfile` system call might be encapsulated:
+This function is intended to allow the encapsulation of arbitrary non-blocking system calls as asynchronous operations, in a way that is transparent to the user of the socket object. The following example illustrates how Linux's `sendfile` system call might be encapsulated:
template <typename Handler>
struct sendfile_op
@@ -18301,11 +18338,12 @@
tcp::socket& sock_;
int fd_;
Handler handler_;
+ off_t offset_;
+ std::size_t total_bytes_transferred_;
// Function call operator meeting WriteHandler requirements.
// Used as the handler for the async_write_some operation.
- void operator()(asio::error_code ec,
- std::size_t bytes_transferred)
+ void operator()(asio::error_code ec, std::size_t)
{
// Put the underlying socket into non-blocking mode.
if (!ec)
@@ -18318,10 +18356,10 @@
{
// Try the system call.
errno = 0;
- int n = ::sendfile(sock_.native_handle(), fd_, ...);
- ec = asio::error_code(
- n < 0 ? errno : 0,
- asio::error::system_category());
+ int n = ::sendfile(sock_.native_handle(), fd_, &offset_, 65536);
+ ec = asio::error_code(n < 0 ? errno : 0,
+ asio::error::get_system_category());
+ total_bytes_transferred_ += ec ? 0 : n;
// Retry operation immediately if interrupted by signal.
if (ec == asio::error::interrupted)
@@ -18336,21 +18374,26 @@
return;
}
- // The operation is done. Exit loop so we can call the handler.
- bytes_transferred = ec ? 0 : n;
- break;
+ if (ec || n == 0)
+ {
+ // An error occurred, or we have reached the end of the file.
+ // Either way we must exit the loop so we can call the handler.
+ break;
+ }
+
+ // Loop around to try calling sendfile again.
}
}
// Pass result back to user's handler.
- handler_(ec, bytes_transferred);
+ handler_(ec, total_bytes_transferred_);
}
};
template <typename Handler>
void async_sendfile(tcp::socket& sock, int fd, Handler h)
{
- sendfile_op op = { sock, fd, h };
+ sendfile_op<Handler> op = { sock, fd, h, 0, 0 };
sock.async_write_some(asio::null_buffers(), op);
}
@@ -18402,7 +18445,7 @@
[heading Example]
-This function is intended to allow the encapsulation of arbitrary non-blocking system calls as asynchronous operations, in a way that is transparent to the user of the socket object. The following example illustrates how a `sendfile` system call might be encapsulated:
+This function is intended to allow the encapsulation of arbitrary non-blocking system calls as asynchronous operations, in a way that is transparent to the user of the socket object. The following example illustrates how Linux's `sendfile` system call might be encapsulated:
template <typename Handler>
struct sendfile_op
@@ -18410,11 +18453,12 @@
tcp::socket& sock_;
int fd_;
Handler handler_;
+ off_t offset_;
+ std::size_t total_bytes_transferred_;
// Function call operator meeting WriteHandler requirements.
// Used as the handler for the async_write_some operation.
- void operator()(asio::error_code ec,
- std::size_t bytes_transferred)
+ void operator()(asio::error_code ec, std::size_t)
{
// Put the underlying socket into non-blocking mode.
if (!ec)
@@ -18427,10 +18471,10 @@
{
// Try the system call.
errno = 0;
- int n = ::sendfile(sock_.native_handle(), fd_, ...);
- ec = asio::error_code(
- n < 0 ? errno : 0,
- asio::error::system_category());
+ int n = ::sendfile(sock_.native_handle(), fd_, &offset_, 65536);
+ ec = asio::error_code(n < 0 ? errno : 0,
+ asio::error::get_system_category());
+ total_bytes_transferred_ += ec ? 0 : n;
// Retry operation immediately if interrupted by signal.
if (ec == asio::error::interrupted)
@@ -18445,21 +18489,26 @@
return;
}
- // The operation is done. Exit loop so we can call the handler.
- bytes_transferred = ec ? 0 : n;
- break;
+ if (ec || n == 0)
+ {
+ // An error occurred, or we have reached the end of the file.
+ // Either way we must exit the loop so we can call the handler.
+ break;
+ }
+
+ // Loop around to try calling sendfile again.
}
}
// Pass result back to user's handler.
- handler_(ec, bytes_transferred);
+ handler_(ec, total_bytes_transferred_);
}
};
template <typename Handler>
void async_sendfile(tcp::socket& sock, int fd, Handler h)
{
- sendfile_op op = { sock, fd, h };
+ sendfile_op<Handler> op = { sock, fd, h, 0, 0 };
sock.async_write_some(asio::null_buffers(), op);
}
@@ -18504,7 +18553,7 @@
[heading Example]
-This function is intended to allow the encapsulation of arbitrary non-blocking system calls as asynchronous operations, in a way that is transparent to the user of the socket object. The following example illustrates how a `sendfile` system call might be encapsulated:
+This function is intended to allow the encapsulation of arbitrary non-blocking system calls as asynchronous operations, in a way that is transparent to the user of the socket object. The following example illustrates how Linux's `sendfile` system call might be encapsulated:
template <typename Handler>
struct sendfile_op
@@ -18512,11 +18561,12 @@
tcp::socket& sock_;
int fd_;
Handler handler_;
+ off_t offset_;
+ std::size_t total_bytes_transferred_;
// Function call operator meeting WriteHandler requirements.
// Used as the handler for the async_write_some operation.
- void operator()(asio::error_code ec,
- std::size_t bytes_transferred)
+ void operator()(asio::error_code ec, std::size_t)
{
// Put the underlying socket into non-blocking mode.
if (!ec)
@@ -18529,10 +18579,10 @@
{
// Try the system call.
errno = 0;
- int n = ::sendfile(sock_.native_handle(), fd_, ...);
- ec = asio::error_code(
- n < 0 ? errno : 0,
- asio::error::system_category());
+ int n = ::sendfile(sock_.native_handle(), fd_, &offset_, 65536);
+ ec = asio::error_code(n < 0 ? errno : 0,
+ asio::error::get_system_category());
+ total_bytes_transferred_ += ec ? 0 : n;
// Retry operation immediately if interrupted by signal.
if (ec == asio::error::interrupted)
@@ -18547,21 +18597,26 @@
return;
}
- // The operation is done. Exit loop so we can call the handler.
- bytes_transferred = ec ? 0 : n;
- break;
+ if (ec || n == 0)
+ {
+ // An error occurred, or we have reached the end of the file.
+ // Either way we must exit the loop so we can call the handler.
+ break;
+ }
+
+ // Loop around to try calling sendfile again.
}
}
// Pass result back to user's handler.
- handler_(ec, bytes_transferred);
+ handler_(ec, total_bytes_transferred_);
}
};
template <typename Handler>
void async_sendfile(tcp::socket& sock, int fd, Handler h)
{
- sendfile_op op = { sock, fd, h };
+ sendfile_op<Handler> op = { sock, fd, h, 0, 0 };
sock.async_write_some(asio::null_buffers(), op);
}
@@ -24512,7 +24567,7 @@
[heading Example]
-This function is intended to allow the encapsulation of arbitrary non-blocking system calls as asynchronous operations, in a way that is transparent to the user of the socket object. The following example illustrates how a `sendfile` system call might be encapsulated:
+This function is intended to allow the encapsulation of arbitrary non-blocking system calls as asynchronous operations, in a way that is transparent to the user of the socket object. The following example illustrates how Linux's `sendfile` system call might be encapsulated:
template <typename Handler>
struct sendfile_op
@@ -24520,11 +24575,12 @@
tcp::socket& sock_;
int fd_;
Handler handler_;
+ off_t offset_;
+ std::size_t total_bytes_transferred_;
// Function call operator meeting WriteHandler requirements.
// Used as the handler for the async_write_some operation.
- void operator()(asio::error_code ec,
- std::size_t bytes_transferred)
+ void operator()(asio::error_code ec, std::size_t)
{
// Put the underlying socket into non-blocking mode.
if (!ec)
@@ -24537,10 +24593,10 @@
{
// Try the system call.
errno = 0;
- int n = ::sendfile(sock_.native_handle(), fd_, ...);
- ec = asio::error_code(
- n < 0 ? errno : 0,
- asio::error::system_category());
+ int n = ::sendfile(sock_.native_handle(), fd_, &offset_, 65536);
+ ec = asio::error_code(n < 0 ? errno : 0,
+ asio::error::get_system_category());
+ total_bytes_transferred_ += ec ? 0 : n;
// Retry operation immediately if interrupted by signal.
if (ec == asio::error::interrupted)
@@ -24555,21 +24611,26 @@
return;
}
- // The operation is done. Exit loop so we can call the handler.
- bytes_transferred = ec ? 0 : n;
- break;
+ if (ec || n == 0)
+ {
+ // An error occurred, or we have reached the end of the file.
+ // Either way we must exit the loop so we can call the handler.
+ break;
+ }
+
+ // Loop around to try calling sendfile again.
}
}
// Pass result back to user's handler.
- handler_(ec, bytes_transferred);
+ handler_(ec, total_bytes_transferred_);
}
};
template <typename Handler>
void async_sendfile(tcp::socket& sock, int fd, Handler h)
{
- sendfile_op op = { sock, fd, h };
+ sendfile_op<Handler> op = { sock, fd, h, 0, 0 };
sock.async_write_some(asio::null_buffers(), op);
}
@@ -24618,7 +24679,7 @@
[heading Example]
-This function is intended to allow the encapsulation of arbitrary non-blocking system calls as asynchronous operations, in a way that is transparent to the user of the socket object. The following example illustrates how a `sendfile` system call might be encapsulated:
+This function is intended to allow the encapsulation of arbitrary non-blocking system calls as asynchronous operations, in a way that is transparent to the user of the socket object. The following example illustrates how Linux's `sendfile` system call might be encapsulated:
template <typename Handler>
struct sendfile_op
@@ -24626,11 +24687,12 @@
tcp::socket& sock_;
int fd_;
Handler handler_;
+ off_t offset_;
+ std::size_t total_bytes_transferred_;
// Function call operator meeting WriteHandler requirements.
// Used as the handler for the async_write_some operation.
- void operator()(asio::error_code ec,
- std::size_t bytes_transferred)
+ void operator()(asio::error_code ec, std::size_t)
{
// Put the underlying socket into non-blocking mode.
if (!ec)
@@ -24643,10 +24705,10 @@
{
// Try the system call.
errno = 0;
- int n = ::sendfile(sock_.native_handle(), fd_, ...);
- ec = asio::error_code(
- n < 0 ? errno : 0,
- asio::error::system_category());
+ int n = ::sendfile(sock_.native_handle(), fd_, &offset_, 65536);
+ ec = asio::error_code(n < 0 ? errno : 0,
+ asio::error::get_system_category());
+ total_bytes_transferred_ += ec ? 0 : n;
// Retry operation immediately if interrupted by signal.
if (ec == asio::error::interrupted)
@@ -24661,21 +24723,26 @@
return;
}
- // The operation is done. Exit loop so we can call the handler.
- bytes_transferred = ec ? 0 : n;
- break;
+ if (ec || n == 0)
+ {
+ // An error occurred, or we have reached the end of the file.
+ // Either way we must exit the loop so we can call the handler.
+ break;
+ }
+
+ // Loop around to try calling sendfile again.
}
}
// Pass result back to user's handler.
- handler_(ec, bytes_transferred);
+ handler_(ec, total_bytes_transferred_);
}
};
template <typename Handler>
void async_sendfile(tcp::socket& sock, int fd, Handler h)
{
- sendfile_op op = { sock, fd, h };
+ sendfile_op<Handler> op = { sock, fd, h, 0, 0 };
sock.async_write_some(asio::null_buffers(), op);
}
@@ -24717,7 +24784,7 @@
[heading Example]
-This function is intended to allow the encapsulation of arbitrary non-blocking system calls as asynchronous operations, in a way that is transparent to the user of the socket object. The following example illustrates how a `sendfile` system call might be encapsulated:
+This function is intended to allow the encapsulation of arbitrary non-blocking system calls as asynchronous operations, in a way that is transparent to the user of the socket object. The following example illustrates how Linux's `sendfile` system call might be encapsulated:
template <typename Handler>
struct sendfile_op
@@ -24725,11 +24792,12 @@
tcp::socket& sock_;
int fd_;
Handler handler_;
+ off_t offset_;
+ std::size_t total_bytes_transferred_;
// Function call operator meeting WriteHandler requirements.
// Used as the handler for the async_write_some operation.
- void operator()(asio::error_code ec,
- std::size_t bytes_transferred)
+ void operator()(asio::error_code ec, std::size_t)
{
// Put the underlying socket into non-blocking mode.
if (!ec)
@@ -24742,10 +24810,10 @@
{
// Try the system call.
errno = 0;
- int n = ::sendfile(sock_.native_handle(), fd_, ...);
- ec = asio::error_code(
- n < 0 ? errno : 0,
- asio::error::system_category());
+ int n = ::sendfile(sock_.native_handle(), fd_, &offset_, 65536);
+ ec = asio::error_code(n < 0 ? errno : 0,
+ asio::error::get_system_category());
+ total_bytes_transferred_ += ec ? 0 : n;
// Retry operation immediately if interrupted by signal.
if (ec == asio::error::interrupted)
@@ -24760,21 +24828,26 @@
return;
}
- // The operation is done. Exit loop so we can call the handler.
- bytes_transferred = ec ? 0 : n;
- break;
+ if (ec || n == 0)
+ {
+ // An error occurred, or we have reached the end of the file.
+ // Either way we must exit the loop so we can call the handler.
+ break;
+ }
+
+ // Loop around to try calling sendfile again.
}
}
// Pass result back to user's handler.
- handler_(ec, bytes_transferred);
+ handler_(ec, total_bytes_transferred_);
}
};
template <typename Handler>
void async_sendfile(tcp::socket& sock, int fd, Handler h)
{
- sendfile_op op = { sock, fd, h };
+ sendfile_op<Handler> op = { sock, fd, h, 0, 0 };
sock.async_write_some(asio::null_buffers(), op);
}
@@ -32599,7 +32672,7 @@
[heading Example]
-This function is intended to allow the encapsulation of arbitrary non-blocking system calls as asynchronous operations, in a way that is transparent to the user of the socket object. The following example illustrates how a `sendfile` system call might be encapsulated:
+This function is intended to allow the encapsulation of arbitrary non-blocking system calls as asynchronous operations, in a way that is transparent to the user of the socket object. The following example illustrates how Linux's `sendfile` system call might be encapsulated:
template <typename Handler>
struct sendfile_op
@@ -32607,11 +32680,12 @@
tcp::socket& sock_;
int fd_;
Handler handler_;
+ off_t offset_;
+ std::size_t total_bytes_transferred_;
// Function call operator meeting WriteHandler requirements.
// Used as the handler for the async_write_some operation.
- void operator()(asio::error_code ec,
- std::size_t bytes_transferred)
+ void operator()(asio::error_code ec, std::size_t)
{
// Put the underlying socket into non-blocking mode.
if (!ec)
@@ -32624,10 +32698,10 @@
{
// Try the system call.
errno = 0;
- int n = ::sendfile(sock_.native_handle(), fd_, ...);
- ec = asio::error_code(
- n < 0 ? errno : 0,
- asio::error::system_category());
+ int n = ::sendfile(sock_.native_handle(), fd_, &offset_, 65536);
+ ec = asio::error_code(n < 0 ? errno : 0,
+ asio::error::get_system_category());
+ total_bytes_transferred_ += ec ? 0 : n;
// Retry operation immediately if interrupted by signal.
if (ec == asio::error::interrupted)
@@ -32642,21 +32716,26 @@
return;
}
- // The operation is done. Exit loop so we can call the handler.
- bytes_transferred = ec ? 0 : n;
- break;
+ if (ec || n == 0)
+ {
+ // An error occurred, or we have reached the end of the file.
+ // Either way we must exit the loop so we can call the handler.
+ break;
+ }
+
+ // Loop around to try calling sendfile again.
}
}
// Pass result back to user's handler.
- handler_(ec, bytes_transferred);
+ handler_(ec, total_bytes_transferred_);
}
};
template <typename Handler>
void async_sendfile(tcp::socket& sock, int fd, Handler h)
{
- sendfile_op op = { sock, fd, h };
+ sendfile_op<Handler> op = { sock, fd, h, 0, 0 };
sock.async_write_some(asio::null_buffers(), op);
}
@@ -32708,7 +32787,7 @@
[heading Example]
-This function is intended to allow the encapsulation of arbitrary non-blocking system calls as asynchronous operations, in a way that is transparent to the user of the socket object. The following example illustrates how a `sendfile` system call might be encapsulated:
+This function is intended to allow the encapsulation of arbitrary non-blocking system calls as asynchronous operations, in a way that is transparent to the user of the socket object. The following example illustrates how Linux's `sendfile` system call might be encapsulated:
template <typename Handler>
struct sendfile_op
@@ -32716,11 +32795,12 @@
tcp::socket& sock_;
int fd_;
Handler handler_;
+ off_t offset_;
+ std::size_t total_bytes_transferred_;
// Function call operator meeting WriteHandler requirements.
// Used as the handler for the async_write_some operation.
- void operator()(asio::error_code ec,
- std::size_t bytes_transferred)
+ void operator()(asio::error_code ec, std::size_t)
{
// Put the underlying socket into non-blocking mode.
if (!ec)
@@ -32733,10 +32813,10 @@
{
// Try the system call.
errno = 0;
- int n = ::sendfile(sock_.native_handle(), fd_, ...);
- ec = asio::error_code(
- n < 0 ? errno : 0,
- asio::error::system_category());
+ int n = ::sendfile(sock_.native_handle(), fd_, &offset_, 65536);
+ ec = asio::error_code(n < 0 ? errno : 0,
+ asio::error::get_system_category());
+ total_bytes_transferred_ += ec ? 0 : n;
// Retry operation immediately if interrupted by signal.
if (ec == asio::error::interrupted)
@@ -32751,21 +32831,26 @@
return;
}
- // The operation is done. Exit loop so we can call the handler.
- bytes_transferred = ec ? 0 : n;
- break;
+ if (ec || n == 0)
+ {
+ // An error occurred, or we have reached the end of the file.
+ // Either way we must exit the loop so we can call the handler.
+ break;
+ }
+
+ // Loop around to try calling sendfile again.
}
}
// Pass result back to user's handler.
- handler_(ec, bytes_transferred);
+ handler_(ec, total_bytes_transferred_);
}
};
template <typename Handler>
void async_sendfile(tcp::socket& sock, int fd, Handler h)
{
- sendfile_op op = { sock, fd, h };
+ sendfile_op<Handler> op = { sock, fd, h, 0, 0 };
sock.async_write_some(asio::null_buffers(), op);
}
@@ -32810,7 +32895,7 @@
[heading Example]
-This function is intended to allow the encapsulation of arbitrary non-blocking system calls as asynchronous operations, in a way that is transparent to the user of the socket object. The following example illustrates how a `sendfile` system call might be encapsulated:
+This function is intended to allow the encapsulation of arbitrary non-blocking system calls as asynchronous operations, in a way that is transparent to the user of the socket object. The following example illustrates how Linux's `sendfile` system call might be encapsulated:
template <typename Handler>
struct sendfile_op
@@ -32818,11 +32903,12 @@
tcp::socket& sock_;
int fd_;
Handler handler_;
+ off_t offset_;
+ std::size_t total_bytes_transferred_;
// Function call operator meeting WriteHandler requirements.
// Used as the handler for the async_write_some operation.
- void operator()(asio::error_code ec,
- std::size_t bytes_transferred)
+ void operator()(asio::error_code ec, std::size_t)
{
// Put the underlying socket into non-blocking mode.
if (!ec)
@@ -32835,10 +32921,10 @@
{
// Try the system call.
errno = 0;
- int n = ::sendfile(sock_.native_handle(), fd_, ...);
- ec = asio::error_code(
- n < 0 ? errno : 0,
- asio::error::system_category());
+ int n = ::sendfile(sock_.native_handle(), fd_, &offset_, 65536);
+ ec = asio::error_code(n < 0 ? errno : 0,
+ asio::error::get_system_category());
+ total_bytes_transferred_ += ec ? 0 : n;
// Retry operation immediately if interrupted by signal.
if (ec == asio::error::interrupted)
@@ -32853,21 +32939,26 @@
return;
}
- // The operation is done. Exit loop so we can call the handler.
- bytes_transferred = ec ? 0 : n;
- break;
+ if (ec || n == 0)
+ {
+ // An error occurred, or we have reached the end of the file.
+ // Either way we must exit the loop so we can call the handler.
+ break;
+ }
+
+ // Loop around to try calling sendfile again.
}
}
// Pass result back to user's handler.
- handler_(ec, bytes_transferred);
+ handler_(ec, total_bytes_transferred_);
}
};
template <typename Handler>
void async_sendfile(tcp::socket& sock, int fd, Handler h)
{
- sendfile_op op = { sock, fd, h };
+ sendfile_op<Handler> op = { sock, fd, h, 0, 0 };
sock.async_write_some(asio::null_buffers(), op);
}
@@ -37396,7 +37487,7 @@
[heading Example]
-This function is intended to allow the encapsulation of arbitrary non-blocking system calls as asynchronous operations, in a way that is transparent to the user of the socket object. The following example illustrates how a `sendfile` system call might be encapsulated:
+This function is intended to allow the encapsulation of arbitrary non-blocking system calls as asynchronous operations, in a way that is transparent to the user of the socket object. The following example illustrates how Linux's `sendfile` system call might be encapsulated:
template <typename Handler>
struct sendfile_op
@@ -37404,11 +37495,12 @@
tcp::socket& sock_;
int fd_;
Handler handler_;
+ off_t offset_;
+ std::size_t total_bytes_transferred_;
// Function call operator meeting WriteHandler requirements.
// Used as the handler for the async_write_some operation.
- void operator()(asio::error_code ec,
- std::size_t bytes_transferred)
+ void operator()(asio::error_code ec, std::size_t)
{
// Put the underlying socket into non-blocking mode.
if (!ec)
@@ -37421,10 +37513,10 @@
{
// Try the system call.
errno = 0;
- int n = ::sendfile(sock_.native_handle(), fd_, ...);
- ec = asio::error_code(
- n < 0 ? errno : 0,
- asio::error::system_category());
+ int n = ::sendfile(sock_.native_handle(), fd_, &offset_, 65536);
+ ec = asio::error_code(n < 0 ? errno : 0,
+ asio::error::get_system_category());
+ total_bytes_transferred_ += ec ? 0 : n;
// Retry operation immediately if interrupted by signal.
if (ec == asio::error::interrupted)
@@ -37439,21 +37531,26 @@
return;
}
- // The operation is done. Exit loop so we can call the handler.
- bytes_transferred = ec ? 0 : n;
- break;
+ if (ec || n == 0)
+ {
+ // An error occurred, or we have reached the end of the file.
+ // Either way we must exit the loop so we can call the handler.
+ break;
+ }
+
+ // Loop around to try calling sendfile again.
}
}
// Pass result back to user's handler.
- handler_(ec, bytes_transferred);
+ handler_(ec, total_bytes_transferred_);
}
};
template <typename Handler>
void async_sendfile(tcp::socket& sock, int fd, Handler h)
{
- sendfile_op op = { sock, fd, h };
+ sendfile_op<Handler> op = { sock, fd, h, 0, 0 };
sock.async_write_some(asio::null_buffers(), op);
}
@@ -37505,7 +37602,7 @@
[heading Example]
-This function is intended to allow the encapsulation of arbitrary non-blocking system calls as asynchronous operations, in a way that is transparent to the user of the socket object. The following example illustrates how a `sendfile` system call might be encapsulated:
+This function is intended to allow the encapsulation of arbitrary non-blocking system calls as asynchronous operations, in a way that is transparent to the user of the socket object. The following example illustrates how Linux's `sendfile` system call might be encapsulated:
template <typename Handler>
struct sendfile_op
@@ -37513,11 +37610,12 @@
tcp::socket& sock_;
int fd_;
Handler handler_;
+ off_t offset_;
+ std::size_t total_bytes_transferred_;
// Function call operator meeting WriteHandler requirements.
// Used as the handler for the async_write_some operation.
- void operator()(asio::error_code ec,
- std::size_t bytes_transferred)
+ void operator()(asio::error_code ec, std::size_t)
{
// Put the underlying socket into non-blocking mode.
if (!ec)
@@ -37530,10 +37628,10 @@
{
// Try the system call.
errno = 0;
- int n = ::sendfile(sock_.native_handle(), fd_, ...);
- ec = asio::error_code(
- n < 0 ? errno : 0,
- asio::error::system_category());
+ int n = ::sendfile(sock_.native_handle(), fd_, &offset_, 65536);
+ ec = asio::error_code(n < 0 ? errno : 0,
+ asio::error::get_system_category());
+ total_bytes_transferred_ += ec ? 0 : n;
// Retry operation immediately if interrupted by signal.
if (ec == asio::error::interrupted)
@@ -37548,21 +37646,26 @@
return;
}
- // The operation is done. Exit loop so we can call the handler.
- bytes_transferred = ec ? 0 : n;
- break;
+ if (ec || n == 0)
+ {
+ // An error occurred, or we have reached the end of the file.
+ // Either way we must exit the loop so we can call the handler.
+ break;
+ }
+
+ // Loop around to try calling sendfile again.
}
}
// Pass result back to user's handler.
- handler_(ec, bytes_transferred);
+ handler_(ec, total_bytes_transferred_);
}
};
template <typename Handler>
void async_sendfile(tcp::socket& sock, int fd, Handler h)
{
- sendfile_op op = { sock, fd, h };
+ sendfile_op<Handler> op = { sock, fd, h, 0, 0 };
sock.async_write_some(asio::null_buffers(), op);
}
@@ -37607,7 +37710,7 @@
[heading Example]
-This function is intended to allow the encapsulation of arbitrary non-blocking system calls as asynchronous operations, in a way that is transparent to the user of the socket object. The following example illustrates how a `sendfile` system call might be encapsulated:
+This function is intended to allow the encapsulation of arbitrary non-blocking system calls as asynchronous operations, in a way that is transparent to the user of the socket object. The following example illustrates how Linux's `sendfile` system call might be encapsulated:
template <typename Handler>
struct sendfile_op
@@ -37615,11 +37718,12 @@
tcp::socket& sock_;
int fd_;
Handler handler_;
+ off_t offset_;
+ std::size_t total_bytes_transferred_;
// Function call operator meeting WriteHandler requirements.
// Used as the handler for the async_write_some operation.
- void operator()(asio::error_code ec,
- std::size_t bytes_transferred)
+ void operator()(asio::error_code ec, std::size_t)
{
// Put the underlying socket into non-blocking mode.
if (!ec)
@@ -37632,10 +37736,10 @@
{
// Try the system call.
errno = 0;
- int n = ::sendfile(sock_.native_handle(), fd_, ...);
- ec = asio::error_code(
- n < 0 ? errno : 0,
- asio::error::system_category());
+ int n = ::sendfile(sock_.native_handle(), fd_, &offset_, 65536);
+ ec = asio::error_code(n < 0 ? errno : 0,
+ asio::error::get_system_category());
+ total_bytes_transferred_ += ec ? 0 : n;
// Retry operation immediately if interrupted by signal.
if (ec == asio::error::interrupted)
@@ -37650,21 +37754,26 @@
return;
}
- // The operation is done. Exit loop so we can call the handler.
- bytes_transferred = ec ? 0 : n;
- break;
+ if (ec || n == 0)
+ {
+ // An error occurred, or we have reached the end of the file.
+ // Either way we must exit the loop so we can call the handler.
+ break;
+ }
+
+ // Loop around to try calling sendfile again.
}
}
// Pass result back to user's handler.
- handler_(ec, bytes_transferred);
+ handler_(ec, total_bytes_transferred_);
}
};
template <typename Handler>
void async_sendfile(tcp::socket& sock, int fd, Handler h)
{
- sendfile_op op = { sock, fd, h };
+ sendfile_op<Handler> op = { sock, fd, h, 0, 0 };
sock.async_write_some(asio::null_buffers(), op);
}
@@ -48889,9 +48998,9 @@
[heading Requirements]
-[*Header: ][^asio/error.hpp]
+[*Header: ][^asio/ssl/error.hpp]
-[*Convenience header: ][^asio.hpp]
+[*Convenience header: ][^asio/ssl.hpp]
[endsect]
@@ -49154,9 +49263,9 @@
[heading Requirements]
-[*Header: ][^asio/error.hpp]
+[*Header: ][^asio/ssl/error.hpp]
-[*Convenience header: ][^asio.hpp]
+[*Convenience header: ][^asio/ssl.hpp]
[endsect]
@@ -49172,9 +49281,9 @@
[heading Requirements]
-[*Header: ][^asio/error.hpp]
+[*Header: ][^asio/ssl/error.hpp]
-[*Convenience header: ][^asio.hpp]
+[*Convenience header: ][^asio/ssl.hpp]
[endsect]