Устанавливает неблокирующий режим реализации родного гнезда.
void native_non_blocking(
bool mode);
Эта функция используется для изменения режима неблокировки базового нативного гнезда. Он не влияет на поведение синхронных операций объекта разъема.
- mode
Если<true
>, базовое гнездо помещается в неблокирующий режим и прямые системные вызовы могут выйти из строя с<boost::asio::error::would_block
>(или эквивалентной системной ошибкой).
- boost::system::system_error
Выброшен на провал. Если<mode
>—<false
>, а текущее значение<non_blocking()
>—<true
>, то эта функция не срабатывает<boost::asio::error::invalid_argument
>, так как комбинация не имеет смысла.
Эта функция предназначена для обеспечения инкапсуляции произвольных неблокирующих системных вызовов в виде асинхронных операций, таким образом, чтобы это было прозрачно для пользователя объекта разъема. Следующий пример иллюстрирует, как системный вызов Linux<sendfile
>может быть инкапсулирован:
template <typename Handler>
struct sendfile_op
{
tcp::socket& sock_;
int fd_;
Handler handler_;
off_t offset_;
std::size_t total_bytes_transferred_;
void operator()(boost::system::error_code ec, std::size_t)
{
if (!ec)
if (!sock_.native_non_blocking())
sock_.native_non_blocking(true, ec);
if (!ec)
{
for (;;)
{
errno = 0;
int n = ::sendfile(sock_.native_handle(), fd_, &offset_, 65536);
ec = boost::system::error_code(n < 0 ? errno : 0,
boost::asio::error::get_system_category());
total_bytes_transferred_ += ec ? 0 : n;
if (ec == boost::asio::error::interrupted)
continue;
if (ec == boost::asio::error::would_block
|| ec == boost::asio::error::try_again)
{
sock_.async_write_some(boost::asio::null_buffers(), *this);
return;
}
if (ec || n == 0)
{
break;
}
}
}
handler_(ec, total_bytes_transferred_);
}
};
template <typename Handler>
void async_sendfile(tcp::socket& sock, int fd, Handler h)
{
sendfile_op<Handler> op = { sock, fd, h, 0, 0 };
sock.async_write_some(boost::asio::null_buffers(), op);
}