| 124 | } |
| 125 | } |
| 126 | void local_socket_tcp_impl::async_receive(boost::asio::mutable_buffer _buffer, read_handler _r_handler) { |
| 127 | std::unique_lock lock{socket_mtx_}; |
| 128 | if (socket_->is_open()) { |
| 129 | |
| 130 | socket_->async_receive(_buffer, [handler = std::move(_r_handler), weak_self = weak_from_this()](auto const& _ec, auto bytes) { |
| 131 | #if defined(__linux__) |
| 132 | // yes, this needs to happen after every read |
| 133 | if (!_ec) { |
| 134 | if (auto self = weak_self.lock(); self) { |
| 135 | std::scoped_lock const inner_lock{self->socket_mtx_}; |
| 136 | // set TCP QUICKACK |
| 137 | // necessary, because local connections are TCP RST'd, and in order to guarantee no |
| 138 | // loss of data, there is (active!) waiting for TCP ACKs - which relies on speedy delivery of TCP ACKs |
| 139 | if (!self->socket_->set_quick_ack()) { |
| 140 | VSOMEIP_WARNING_P << "Could not setsockopt(TCP_QUICKACK), errno " << errno; |
| 141 | } |
| 142 | } |
| 143 | } |
| 144 | #endif |
| 145 | handler(_ec, bytes); |
| 146 | }); |
| 147 | } else { |
| 148 | boost::asio::post(io_context_, [h = std::move(_r_handler)] { h(boost::asio::error::fault, 0); }); |
| 149 | } |
| 150 | } |
| 151 | void local_socket_tcp_impl::async_send(std::vector<uint8_t> _data, write_handler _w_handle) { |
| 152 | std::unique_lock lock{socket_mtx_}; |
| 153 | if (socket_->is_open()) { |
nothing calls this directly
no test coverage detected