Home > Net >  Getting co_await with boost::process::async_system working
Getting co_await with boost::process::async_system working

Time:10-18

Like the title says, I want to co_await for a process spawned with boost::process::async_system.

So I'm doing something like this:

Example on Coliru

  namespace bp = boost::process;
  bp::async_pipe ap(io_);

  // Create the child process object with our parameters and a redirected stdout
  co_await bp::async_system(io_,
                            boost::asio::use_awaitable,
                            bp::search_path(command),
                            bp::start_dir(cwd),
                            bp::args(args),
                            bp::std_out > ap);

But I'm getting a very unhelpful error-message.

My assumption now is, that async_system is not compatible with co_await. Is there another (maybe generic) way to integrate 3rd party async mechanisms in boost::asio::awaitable?

(I feel a bit lost in this whole boost::asio / c coro topic. Google is not very helpful and the boost doc a bit too minimalistic for me.)

CodePudding user response:

I'd mold the code a bit for style: http://coliru.stacked-crooked.com/a/33667a7d106de0e7

The Real Problem

Now with the above, there's is still an error inside my_coro when you try to uncomment the async_system call.

Instead of reading the message, I looked at the code, figured that it should have worked, and looked at the implementation:

template<typename ExitHandler, typename ...Args>
inline BOOST_ASIO_INITFN_RESULT_TYPE(ExitHandler, void (boost::system::error_code, int))
    async_system(boost::asio::io_context & ios, ExitHandler && exit_handler, Args && ...args)
{
    detail::async_system_handler<ExitHandler> async_h{ios, std::forward<ExitHandler>(exit_handler)};

    typedef typename ::boost::process::detail::has_error_handler<boost::fusion::tuple<Args...>>::type
            has_err_handling;

    static_assert(!has_err_handling::value, "async_system cannot have custom error handling");


    child(ios, std::forward<Args>(args)..., async_h ).detach();

    return async_h.get_result();
}

After looking at the implementation, I figured that

/usr/local/include/boost/asio/async_result.hpp:651:9: error: no type named 'completion_handler_type' in 'class boost::asio::async_result<boost::asio::use_awaitable_t<>, void(boost::system::error_code, int)>'

indicates that Boost Process has not been updated to support newer async_result protocol, which instead of completion_handler_type appears to use the initiate member function. This gives the async_result implementation more options, which are probably required for use_awaitable_t tokens.

I'd raise an issue at the library.

Note that current develop branch has code underway that does seem to correctly support use_awaitable (e.v. boost/process/v2/popen.hpp)

  • Related