in include/unifex/linux/io_epoll_context.hpp [811:850]
static void on_write_complete(operation_base* op) noexcept {
auto& self = *static_cast<operation*>(static_cast<completion_base*>(op));
UNIFEX_ASSERT(static_cast<completion_base&>(self).enqueued_.load() == 0);
self.stopCallback_.destruct();
epoll_event event = {};
(void)epoll_ctl(self.context_.epollFd_.get(), EPOLL_CTL_DEL, self.fd_, &event);
auto oldState = self.state_.fetch_add(
io_epoll_context::write_sender::operation<Receiver>::io_flag,
std::memory_order_acq_rel);
if ((oldState & io_epoll_context::write_sender::operation<Receiver>::cancel_pending_mask) != 0) {
// io has been cancelled by a remote thread.
// The other thread is responsible for enqueueing the operation completion
return;
}
auto result = writev(self.fd_, self.buffer_, 1);
UNIFEX_ASSERT(result != -EAGAIN);
UNIFEX_ASSERT(result != -EWOULDBLOCK);
if (result == -ECANCELED) {
unifex::set_done(std::move(self.receiver_));
} else if (result >= 0) {
if constexpr (is_nothrow_receiver_of_v<Receiver, ssize_t>) {
unifex::set_value(std::move(self).receiver_, ssize_t(result));
} else {
UNIFEX_TRY {
unifex::set_value(std::move(self).receiver_, ssize_t(result));
} UNIFEX_CATCH (...) {
unifex::set_error(std::move(self).receiver_, std::current_exception());
}
}
} else {
unifex::set_error(
std::move(self.receiver_),
std::error_code{-int(result), std::system_category()});
}
}