~ws_echo_server() { work_.reset(); t_.join(); }
// By having a default value for the second argument, this function call // operator matches the completion signature of both the async_write and // steady_timer::async_wait operations. void operator()(const boost::system::error_code& error, std::size_t = 0) { if (!error) { switch (state_) { case starting: case writing: if (repeat_count_ > 0) { --repeat_count_; state_ = waiting; delay_timer_->expires_after(std::chrono::seconds(1)); delay_timer_->async_wait(std::move(*this)); return; // Composed operation not yet complete. } break; // Composed operation complete, continue below. case waiting: state_ = writing; boost::asio::async_write(socket_, boost::asio::buffer(*encoded_message_), std::move(*this)); return; // Composed operation not yet complete. } } // This point is reached only on completion of the entire composed // operation. // We no longer have any future work coming for the I/O executor. io_work_.reset(); // Deallocate the encoded message before calling the user-supplied // completion handler. encoded_message_.reset(); // Call the user-supplied handler with the result of the operation. handler_(error); }