Skip to content

Conversation

@ZerocksX
Copy link

@ZerocksX ZerocksX commented Jun 7, 2021

#835

I noticed that dispatching coroutine initiation function to attached thread's executor solves this issue.

@ZerocksX ZerocksX marked this pull request as ready for review June 7, 2021 11:55
@ZerocksX ZerocksX changed the title dispatch coroutine initialization function dispatch coroutine initiation function Jun 7, 2021
@ZerocksX
Copy link
Author

ZerocksX commented Jun 9, 2021

When running this code

#include <boost/asio/co_spawn.hpp>
#include <boost/asio/awaitable.hpp>
#include <boost/asio/use_awaitable.hpp>
#include <boost/asio/detached.hpp>
#include <boost/asio/steady_timer.hpp>
#include <boost/asio/strand.hpp>

#include <cstdio>
#include <thread>

namespace net = boost::asio;

class my_app {
    using strand_t = net::strand<net::io_context::executor_type>;

private:    
    strand_t _strand;
    net::steady_timer _render_timer;
    static inline const int render_wait_target_ms = 33;

public:
    template <class T>
    my_app(T&& executor) 
        : _strand(net::make_strand(executor)), _render_timer(_strand) {
    }

    net::awaitable<void> run() {
        using namespace std::chrono;
        auto last_render = steady_clock::now();
        int sleep_ms = 0;
        for(;;) {
            int render_time = co_await render();
            printf("Time to render: %d\n", render_time);
            auto now = steady_clock::now();
            int passed_ms = duration_cast<milliseconds>(now - last_render).count() - sleep_ms;
            last_render = now;
            sleep_ms = std::max(
                render_wait_target_ms - passed_ms,
                0
            );
            _render_timer.expires_after(milliseconds(sleep_ms));
            printf("Passed %dms, waiting for %dms\n", passed_ms, sleep_ms);
            co_await _render_timer.async_wait(net::use_awaitable);
        }
    }

    strand_t strand() {
        return _strand;
    }

private:
    net::awaitable<int> render() {
        int work_done = rand() % 10 + 5;
        std::this_thread::sleep_for(std::chrono::milliseconds(work_done));
        printf("Rendered at %zd\n", 
            std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now().time_since_epoch()).count() % 100000
        );
        co_return work_done;
    }
};

int main(int argc, char** argv) {
    net::io_context ioc;
    auto app = my_app(ioc);
    net::post(
        app.strand(),
        app.run(),
        net::detached
    );
    ioc.run();
    return 0;
}

impl/use_awaitable.hpp async_result::initiate(Initiation, use_awaitable, Initargs...) reaches this line for (;;) {} // Never reached.
I will look more into this.

@ZerocksX ZerocksX closed this Jun 29, 2021
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

Successfully merging this pull request may close these issues.

1 participant