Skip to content

Commit

Permalink
removed code_as_error.
Browse files Browse the repository at this point in the history
  • Loading branch information
klemens-morgenstern committed Jun 21, 2023
1 parent 15783cb commit 799a48c
Show file tree
Hide file tree
Showing 5 changed files with 51 additions and 149 deletions.
154 changes: 18 additions & 136 deletions include/boost/process/v2/exit_code.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -94,157 +94,39 @@ inline int evaluate_exit_code(int code)

#endif


/** Convert the exit-code in a completion into an error if the actual error isn't set.
/// @{
/** Helper to subsume an exit-code into an error_code if there's no actual error isn't set.
* @code {.cpp}
* process proc{ctx, "exit", {"1"}};
*
* proc.async_wait(code_as_error(
* proc.async_wait(
* asio::deferred(
* [&proc](error_code ec, int)
* {
* return asio::deferred.values(
* check_exit_code(ec, proc.native_exit_code())
* );
*
* [](error_code ec)
* {
* assert(ec.value() == 10);
* assert(ec.category() == error::get_exit_code_category());
* }));
*
* @endcode
*/
template<typename CompletionToken>
struct code_as_error_t
{
CompletionToken token_;
const error_category & category;

template<typename Token_>
code_as_error_t(Token_ && token, const error_category & category)
: token_(std::forward<Token_>(token)), category(category)
{
}
};

/// Deduction function for code_as_error_t.
template<typename CompletionToken>
code_as_error_t<CompletionToken> code_as_error(
CompletionToken && token,
const error_category & category = error::get_exit_code_category())
{
return code_as_error_t<typename std::decay<CompletionToken>::type>(
std::forward<CompletionToken>(token), category);
};

namespace detail
{
*/

template<typename Handler>
struct code_as_error_handler
inline error_code check_exit_code(
error_code &ec, native_exit_code_type native_code,
const error_category & category = error::get_exit_code_category())
{
typedef void result_type;

template<typename H>
code_as_error_handler(H && h, const error_category & category)
: handler_(std::forward<H>(h)), category(category)
{
}

void operator()(error_code ec, native_exit_code_type code)
{
if (!ec)
BOOST_PROCESS_V2_ASSIGN_EC(ec, code, category)
std::move(handler_)(ec);
}


Handler handler_;
const error_category & category;
};

if (!ec)
BOOST_PROCESS_V2_ASSIGN_EC(ec, native_code, category);
return ec;
}

/// @}

BOOST_PROCESS_V2_END_NAMESPACE


#if !defined(BOOST_PROCESS_V2_STANDALONE)
namespace boost
{
#endif
namespace asio
{

template <typename CompletionToken>
struct async_result<
BOOST_PROCESS_V2_NAMESPACE::code_as_error_t<CompletionToken>,
void(BOOST_PROCESS_V2_NAMESPACE::error_code,
BOOST_PROCESS_V2_NAMESPACE::native_exit_code_type)>
{
using signature = void(BOOST_PROCESS_V2_NAMESPACE::error_code);
using return_type = typename async_result<CompletionToken, void(BOOST_PROCESS_V2_NAMESPACE::error_code)>::return_type;


template <typename Initiation>
struct init_wrapper
{
init_wrapper(Initiation init)
: initiation_(std::move(init))
{
}

template <typename Handler, typename... Args>
void operator()(
Handler && handler,
const BOOST_PROCESS_V2_NAMESPACE::error_category & cat,
Args && ... args)
{
std::move(initiation_)(
BOOST_PROCESS_V2_NAMESPACE::detail::code_as_error_handler<typename decay<Handler>::type>(
std::forward<Handler>(handler), cat),
std::forward<Args>(args)...);
}

Initiation initiation_;

};

template <typename Initiation, typename RawCompletionToken, typename... Args>
static BOOST_PROCESS_V2_INITFN_DEDUCED_RESULT_TYPE(CompletionToken, signature,
(async_initiate<CompletionToken, signature>(
declval<init_wrapper<typename decay<Initiation>::type> >(),
declval<CompletionToken&>(),
declval<BOOST_ASIO_MOVE_ARG(Args)>()...)))
initiate(
Initiation && initiation,
RawCompletionToken && token,
Args &&... args)
{
return async_initiate<CompletionToken, signature>(
init_wrapper<typename decay<Initiation>::type>(
std::forward<Initiation>(initiation)),
token.token_,
token.category,
std::forward<Args>(args)...);
}
};




template<template <typename, typename> class Associator, typename Handler, typename DefaultCandidate>
struct associator<Associator,
BOOST_PROCESS_V2_NAMESPACE::detail::code_as_error_handler<Handler>, DefaultCandidate>
: Associator<Handler, DefaultCandidate>
{
static typename Associator<Handler, DefaultCandidate>::type get(
const BOOST_PROCESS_V2_NAMESPACE::detail::code_as_error_handler<Handler> & h,
const DefaultCandidate& c = DefaultCandidate()) noexcept
{
return Associator<Handler, DefaultCandidate>::get(h.handler_, c);
}
};


}
#if !defined(BOOST_PROCESS_V2_STANDALONE)
} // boost
#endif


#endif //BOOST_PROCESS_V2_EXIT_CODE_HPP
2 changes: 1 addition & 1 deletion include/boost/process/v2/impl/error.ipp
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ struct exit_code_category final : public error_category
}
std::string message(int status) const
{
switch (status)
switch (evaluate_exit_code(status))
{
case v2::detail::still_active:
return "still-active";
Expand Down
7 changes: 4 additions & 3 deletions include/boost/process/v2/process.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -255,7 +255,7 @@ struct basic_process
{
error_code ec;
if (running(ec))
wait(ec);
process_handle_.wait(exit_status_, ec);
if (ec)
detail::throw_error(ec, "wait failed");
return exit_code();
Expand All @@ -277,8 +277,9 @@ struct basic_process
return boost::exchange(process_handle_, get_executor());
#endif
}
// Get the native
/// Get the native
native_handle_type native_handle() {return process_handle_.native_handle(); }
/// Return the evaluated exit_code.
int exit_code() const
{
return evaluate_exit_code(exit_status_);
Expand Down Expand Up @@ -324,7 +325,7 @@ struct basic_process
/** Note that this might be a process that already exited.*/
bool is_open() const { return process_handle_.is_open(); }

/// Asynchronously wait for the process to exit and deliver the portable exit-code in the completion handler.
/// Asynchronously wait for the process to exit and deliver the native exit-code in the completion handler.
template <BOOST_PROCESS_V2_COMPLETION_TOKEN_FOR(void (error_code, int))
WaitHandler BOOST_PROCESS_V2_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
BOOST_PROCESS_V2_INITFN_AUTO_RESULT_TYPE(WaitHandler, void (error_code, int))
Expand Down
8 changes: 3 additions & 5 deletions test/v2/pid.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,6 @@ BOOST_AUTO_TEST_CASE(test_pid)
BOOST_CHECK_GT(all.size(), 0u);
BOOST_CHECK(itr != all.end());



}

BOOST_AUTO_TEST_CASE(child_pid)
Expand All @@ -34,12 +32,12 @@ BOOST_AUTO_TEST_CASE(child_pid)

using boost::unit_test::framework::master_test_suite;
const auto pth = bp2::filesystem::absolute(master_test_suite().argv[1]);
std::this_thread::sleep_for(std::chrono::milliseconds(20));
std::this_thread::sleep_for(std::chrono::milliseconds(100));

auto cs = bp2::child_pids(bp2::current_pid());
boost::asio::io_context ctx;
bp2::process proc(ctx, pth, {"sleep", "50000"});
std::this_thread::sleep_for(std::chrono::milliseconds(20));
bp2::process proc(ctx, pth, {"loop"});
std::this_thread::sleep_for(std::chrono::milliseconds(100));
auto c2 = bp2::child_pids(bp2::current_pid());
BOOST_CHECK_LT(cs.size(), c2.size());
BOOST_CHECK(std::find(cs.begin(), cs.end(), proc.id()) == cs.end());
Expand Down
29 changes: 25 additions & 4 deletions test/v2/process.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -521,13 +521,34 @@ BOOST_AUTO_TEST_CASE(exit_code_as_error)

proc3.terminate();

proc1.async_wait(bpv::code_as_error([&](bpv::error_code ec){called ++; BOOST_CHECK(!ec);}));
proc2.async_wait(bpv::code_as_error([&](bpv::error_code ec){called ++; BOOST_CHECK_MESSAGE(ec, ec.message());}));
proc3.async_wait(bpv::code_as_error([&](bpv::error_code ec){called ++; BOOST_CHECK_MESSAGE(ec, ec.message());}));

proc1.async_wait(
[&](bpv::error_code ec, int)
{
called ++;
bpv::check_exit_code(ec, proc1.native_exit_code());
BOOST_CHECK(!ec);
});

proc2.async_wait(
[&](bpv::error_code ec, int)
{
called ++;
bpv::check_exit_code(ec, proc2.native_exit_code());
BOOST_CHECK_MESSAGE(ec, ec.message());
});

proc3.async_wait(
[&](bpv::error_code ec, int)
{
called ++;
bpv::check_exit_code(ec, proc3.native_exit_code());
BOOST_CHECK_MESSAGE(ec, ec.message());
});


ctx.run();
BOOST_CHECK_EQUAL(called, 3);

}

BOOST_AUTO_TEST_CASE(bind_launcher)
Expand Down

0 comments on commit 799a48c

Please sign in to comment.