user6429576
user6429576

Reputation:

Boost asio deadline timer completing immediately (C++)

The code below prints "connected" to the console immediately, as opposed to after 10s. Why is this? Is it to do with the way I'm passing my print callback?

void print(const boost::system::error_code& e) {
  std::cout << "connected!" << std::endl;
}

class WebSocketSession {
 public:
  WebSocketSession(asio::io_context &io_context) : io_context_(io_context) {}
  void connect() {
    boost::asio::deadline_timer
        timer(io_context_, boost::posix_time::seconds(10));
    timer.async_wait(&print);
  }
 private:
  asio::io_context &io_context_;
};

class WebSocketClient {
 public:
  WebSocketClient(asio::io_context &io_context) : io_context_(io_context) {}
  std::unique_ptr<WebSocketSession> exec() {
    auto session = std::make_unique<WebSocketSession>(io_context_);
    session->connect();
    return session;
  }
 private:
  asio::io_context &io_context_;
};

int main() {
  asio::io_context io_context;
  WebSocketClient client{io_context};
  std::unique_ptr<WebSocketSession> session = client.exec();
  io_context.run();
  return 0;
}

Upvotes: 1

Views: 450

Answers (1)

rustyx
rustyx

Reputation: 85452

As mentioned in the comments, deadline_timer is destroyed too soon because it's a local variable, thus canceling the I/O operation.

If we add some error handling, we will see the actual error reported:

void print(const boost::system::error_code& e) {
    if (e.failed())
        std::cout << "error: " << e.message() << std::endl;
    else
        std::cout << "connected!" << std::endl;
}

Prints:

error: The I/O operation has been aborted because of either a thread exit or an application request

A possible fix is to move deadline_timer to be member of WebSocketSession:

class WebSocketSession {
public:
    WebSocketSession(boost::asio::io_context& io_context) : io_context_(io_context),
        timer_(io_context, boost::posix_time::seconds(10)) {}
    void connect() {
        timer_.async_wait(&print);
    }
private:
    boost::asio::io_context& io_context_;
    boost::asio::deadline_timer timer_;
};

Upvotes: 0

Related Questions