| 326 | } |
| 327 | |
| 328 | void local_endpoint::send_buffer_unlock() { |
| 329 | if (send_queue_.empty()) { |
| 330 | is_sending_ = false; |
| 331 | if (is_flushing_) { |
| 332 | if (cleanup_handler_) { |
| 333 | // Note that even though we "post" the no-error case here, |
| 334 | // it "only" means that we receive a "stop" due to no error (and do not attempt to restart the routing connection) |
| 335 | // If we would internally encounter some error this would still be captured in our internal state, |
| 336 | // so that we will then close the socket due to our internal error anyhow |
| 337 | // -> there should be no error-handling race by moving the cleanup_handler out |
| 338 | // (and thereby guaranteeing that the cleanup code of this endpoint is executed exactly once) |
| 339 | boost::asio::post(io_, [handler = std::move(cleanup_handler_)] { handler(false); }); |
| 340 | } |
| 341 | } |
| 342 | return; |
| 343 | } |
| 344 | is_sending_ = true; |
| 345 | socket_->async_send(std::move(send_queue_), [weak_self = weak_from_this()](auto const& _ec, size_t _bytes, auto _buffer) { |
| 346 | if (auto self = weak_self.lock(); self) { |
| 347 | self->send_cbk(_ec, _bytes, std::move(_buffer)); |
| 348 | } |
| 349 | }); |
| 350 | send_queue_ = {}; |
| 351 | } |
| 352 | |
| 353 | void local_endpoint::connect_cbk(boost::system::error_code const& _ec) { |
| 354 | // first lock to ensure that if there is a close race with the timer |
nothing calls this directly
no test coverage detected