gianpaolo
gianpaolo

Reputation: 903

Deadline_timer not firing while calling async_connect in a loop

Trying to use deadlinetimer in a similar way as suggested by boost documentation: https://www.boost.org/doc/libs/1_47_0/doc/html/boost_asio/example/timeouts/blocking_tcp_client.cpp

Code: JNI thread:

HttpClient client(io_service);
client.doAsyncOperation()
io_service.run()

HttpClient:

 doAsyncOperation(){
     timer_.expires_from_now(boost::posix_time::seconds(10));
     mSocket.async_connect( endpoint,
                       boost::bind(&HttpClient::handle_connect_async, this,
                                   boost::asio::placeholders::error)

}

void HttpClient::check_deadline(){
if (timer_.expires_at() <= deadline_timer::traits_type::now())
{
    mSocket.cancel();
}else{

   timer_.async_wait(boost::bind(&SchamanHttpClient::check_deadline, this));
}

}

Update: Fix: run io_service on a separate thread

So, inside the JNI thread:

 HttpClient client(io_service);
 client.doAsyncOperation()
 boost::thread t(boost::bind(&boost::asio::io_service::run,&io_service));
io_service.run();
t.join();

HttpClient:

void HttpClient::check_deadline(){
if (timer_.expires_at() <= deadline_timer::traits_type::now())
{
    mSocket.cancel();
    io_service.stop();
}else{

   timer_.async_wait(boost::bind(&SchamanHttpClient::check_deadline, this));
}

Upvotes: 1

Views: 134

Answers (1)

sehe
sehe

Reputation: 393829

None of these examples are that way anymore. For a long time much nicer interfaces exist. Definitely look into these samples in a recent version of boost:

libs/asio/example/cpp03/timeouts/blocking_tcp_client.cpp
libs/asio/example/cpp11/timeouts/blocking_tcp_client.cpp

The check_deadline() is never called again. What is wrong?

Many possibilities:

  • no operation times out (10s is a lot)
  • you're not running the io_service (if you don't poll/run tasks, nothing will happen)
  • the timer got destructed

However, the most likely thing I think might confuse you is: when the timer has expired (timed out) it will set it to never expire again:

void HttpClient::check_deadline() {
    if (timer_.expires_at() <= deadline_timer::traits_type::now()) {
        mSocket.cancel();
        timer_.expires_at(boost::posix_time::pos_infin);
    }
    timer_.async_wait(boost::bind(&HttpClient::check_deadline, this));
}

In short, the whole pattern behind all these 'blocking IO with timeouts' is that you set a timeout before every operation.

Upvotes: 1

Related Questions