Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

timer does only work once when building with BOOST_ASIO_HAS_IO_URING_AS_DEFAULT #1530

Open
ceggers-arri opened this issue Sep 20, 2024 · 1 comment

Comments

@ceggers-arri
Copy link
Contributor

OS: linux-6.6.49
Boost: 1.84.0

I have taken an older "blocking read with timeout" example from here:
https://lists.boost.org/Archives/boost/2007/04/120339.php

This example (updated source code below) works fine as long as using
the epoll reactor (simply try with a non connected UART, the program
should finish after two seconds).

But as soon as I switch to the io_uring implementation (by defining
BOOST_ASIO_HAS_IO_URING and BOOST_ASIO_HAS_IO_URING_AS_DEFAULT), the
2nd timeout is not reached (program exits after 301 seconds).

When I only define BOOST_ASIO_HAS_IO_URING (without BOOST_ASIO_HAS_IO_URING_AS_DEFAULT),
the program works fine. Additionally I recognized that the behavior
depends on the timing. When single stepping in a debugger, also the
2nd timeout works correctly.

Q: Is the example program correct?
Q: Why does it not work as expected with io_uring?

#include <chrono>
#include <iostream>

#include <boost/asio.hpp>
#include <boost/bind/bind.hpp>
#include <boost/optional.hpp>
#include <boost/system/error_code.hpp>

using namespace boost;
using namespace boost::asio;
using namespace std::chrono;
using namespace boost::placeholders;
using namespace boost::system;

void set_result(optional<boost::system::error_code>* a, boost::system::error_code b)
{
        a->reset(b);
}

template <typename MutableBufferSequence>
void read_with_timeout(io_context& io_context, serial_port& port,
                const MutableBufferSequence& buffers)
{
        optional<error_code> timer_result;
        steady_timer timer(io_context);
        timer.expires_after(seconds(1));
        timer.async_wait(
                boost::bind(set_result, &timer_result, _1));

        optional<error_code> port_result;
        async_read(port, buffers,
                boost::bind(set_result, &port_result, _1));

        io_context.restart();
        while (io_context.run_one())
        {
                if (timer_result)
                        port.cancel();
                else if (port_result)
                        timer.cancel();
        }

        if (port_result && *port_result)
                throw system_error(*port_result);
}

int main(int argc, char *argv[])
{
        io_context io_context;
        serial_port port(io_context, "/dev/ttymxc6");
        char buf[4096];

        try
        {
                std::cout << "Read (1) ...\n";
                read_with_timeout(io_context, port, buffer(buf));
        }
        catch (const std::exception& e)
        {
                std::cerr << "Exception: " << e.what() << '\n';
        }

        try
        {
                std::cout << "Read (2) ...\n";
                read_with_timeout(io_context, port, buffer(buf));
        }
        catch (const std::exception& e)
        {
                std::cerr << "Exception: " << e.what() << '\n';
        }
}

@kealqqq
Copy link

kealqqq commented Sep 23, 2024

I have encountered a similar problem where when I enable BOOST_ASIO_DISABLE_EPOLL and BOOST_ASIO_HAS_IO_URING, the boost::asio::steady_timer callback cycle setting does not take effect and runs every 300 seconds.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants