Note that there are some explanatory texts on larger screens.

plurals
  1. POdeadline_timer waits only one time
    primarykey
    data
    text
    <p>i have implemented a pretty standard emulation of blocking api with timeouts for boost::asio. this is my main cycle:</p> <pre><code>io_service io_svc; tcp::endpoint endpoint(tcp::v4(), m_port); tcp::acceptor acceptor(io_svc, endpoint); accept_helper acc_hlpr(acceptor, 5000); while (m_bStop == false) { tcp::socket socket(io_svc); if (acc_hlpr.accept(socket)) { // do stuff socket.close(); } } </code></pre> <p><br> this is the helper class</p> <pre><code>class accept_helper { public: accept_helper (tcp::acceptor &amp;acc, size_t msTO) : m_timer(acc.get_io_service()), m_acceptor(acc), m_msTO(msTO) { } bool accept (tcp::socket &amp;socket) { m_bTimeout = false; m_bAccept = false; m_timer.expires_from_now(boost::posix_time::milliseconds(m_msTO)); m_timer.async_wait(boost::bind(&amp;accept_helper::handle_timeout, this, boost::asio::placeholders::error)); m_acceptor.async_accept(socket, boost::bind(&amp;accept_helper::handle_accept, this)); m_timer.get_io_service().run_one(); m_timer.get_io_service().reset(); if (m_bAccept) { m_timer.cancel(); return true; } else if (m_bTimeout) { // BOOST_ASIO_ENABLE_CANCELIO is defined boost::system::error_code ec; m_acceptor.cancel(ec); } return false; } private: void handle_accept (void) { boost::mutex::scoped_lock lock(m_mutex); m_bAccept = true; } void handle_timeout(const boost::system::error_code &amp; error) { if (!error) { boost::mutex::scoped_lock lock(m_mutex); m_bTimeout = true; } } private: boost::asio::deadline_timer m_timer; boost::asio::ip::tcp::acceptor &amp;m_acceptor; boost::mutex m_mutex; size_t m_msTO; bool m_bTimeout; bool m_bAccept; }; </code></pre> <p>the problem is that timer waits only on the first iteration. on others run_one method just returns immediately and no flags are set. i have tried to make timer local, but that didn't help. how to make timer wait every time?</p> <p>fixed version</p> <pre><code>bool accept (tcp::socket &amp;socket) { m_bTimeout = false; m_bAccept = false; m_timer.expires_from_now(boost::posix_time::milliseconds(m_msTO)); m_timer.async_wait(boost::bind(&amp;accept_helper::handle_timeout, this, boost::asio::placeholders::error)); m_acceptor.async_accept(socket, boost::bind(&amp;accept_helper::handle_accept, this, boost::asio::placeholders::error)); m_timer.get_io_service().reset(); m_timer.get_io_service().run_one(); if (m_bAccept) { m_timer.cancel(); } else if (m_bTimeout) { boost::system::error_code ec; m_acceptor.cancel(ec); } while (m_timer.get_io_service().run_one()); return m_bAccept; } private: void handle_accept (const boost::system::error_code &amp; error) { if (!error) { boost::mutex::scoped_lock lock(m_mutex); m_bAccept = true; } } void handle_timeout(const boost::system::error_code &amp; error) { if (!error) { boost::mutex::scoped_lock lock(m_mutex); m_bTimeout = true; } } </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload