mirror of
https://github.com/boostorg/process.git
synced 2026-02-01 08:42:15 +00:00
cleaned up async stuff
This commit is contained in:
@@ -77,26 +77,13 @@ struct std_in_
|
||||
api::pipe_in operator<(const boost::iostreams::file_descriptor_source &f) const {return api::pipe_in(f);}
|
||||
api::pipe_in operator<(const pipe & p) const {return api::pipe_in(p);}
|
||||
|
||||
api::async_in operator=(asio::mutable_buffer & buf) const {return api::async_in(buf);}
|
||||
api::async_in operator=(asio::const_buffer & buf) const {return api::async_in(buf);}
|
||||
api::async_in operator=(asio::streambuf & buf) const {return api::async_in(buf);}
|
||||
|
||||
api::async_in operator<(asio::mutable_buffer & buf) const {return api::async_in(buf);}
|
||||
api::async_in operator<(asio::const_buffer & buf) const {return api::async_in(buf);}
|
||||
api::async_in operator<(asio::streambuf & buf) const {return api::async_in(buf);}
|
||||
|
||||
// api::async_in_future<std::string> operator()(const std::string & st, std::future<void> & fut) {return {st, fut};}
|
||||
// api::async_in_future<std::vector<char>> operator()(const std::vector<char> & st, std::future<void> & fut) {return {st, fut};}
|
||||
//
|
||||
// using string_cb = const std::function<std::string (bool &)>;
|
||||
// using vector_cb = const std::function<std::vector<char>(bool &)>;
|
||||
//
|
||||
// api::async_in_cb<string_cb> operator<(string_cb & cb) const {return cb;}
|
||||
// api::async_in_cb<vector_cb> operator<(vector_cb & cb) const {return cb;}
|
||||
//
|
||||
// api::async_in_cb<string_cb> operator=(string_cb & cb) const {return cb;}
|
||||
// api::async_in_cb<vector_cb> operator=(vector_cb & cb) const {return cb;}
|
||||
api::async_in_buffer<const asio::mutable_buffer> operator=(const asio::mutable_buffer & buf) const {return buf;}
|
||||
api::async_in_buffer<const asio::const_buffer > operator=(const asio::const_buffer & buf) const {return buf;}
|
||||
api::async_in_buffer<asio::streambuf > operator=(asio::streambuf & buf) const {return buf;}
|
||||
|
||||
api::async_in_buffer<const asio::mutable_buffer> operator<(const asio::mutable_buffer & buf) const {return buf;}
|
||||
api::async_in_buffer<const asio::const_buffer > operator<(const asio::const_buffer & buf) const {return buf;}
|
||||
api::async_in_buffer<asio::streambuf > operator<(asio::streambuf & buf) const {return buf;}
|
||||
|
||||
};
|
||||
|
||||
@@ -139,15 +126,6 @@ struct std_out_
|
||||
api::async_out_buffer<p1, p2, asio::streambuf> operator>(asio::streambuf & os) const {return os ;}
|
||||
|
||||
|
||||
|
||||
using string_cb = const std::function<void(std::string)>;
|
||||
using vector_cb = const std::function<void(std::vector<char>)>;
|
||||
|
||||
api::async_out_cb <p1,p2, string_cb> operator= (string_cb & f) const {return f;}
|
||||
api::async_out_cb <p1,p2, vector_cb> operator= (vector_cb & f) const {return f;}
|
||||
api::async_out_cb <p1,p2, string_cb> operator> (string_cb & f) const {return f;}
|
||||
api::async_out_cb <p1,p2, vector_cb> operator> (vector_cb & f) const {return f;}
|
||||
|
||||
#if defined (BOOST_PROCESS_USE_FUTURE)
|
||||
api::async_out_future<p1,p2, std::string> operator=(std::future<std::string> & fut) const;
|
||||
api::async_out_future<p1,p2, std::string> operator>(std::future<std::string> & fut) const;
|
||||
@@ -155,8 +133,6 @@ struct std_out_
|
||||
api::async_out_future<p1,p2, std::vector<char>> operator>(std::future<std::vector<char>> & fut) const;
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
template<int pin, typename = std::enable_if_t<
|
||||
(((p1 == 1) && (pin == 2)) ||
|
||||
((p1 == 2) && (pin == 1)))
|
||||
@@ -181,37 +157,6 @@ constexpr static std_in_ std_in;
|
||||
constexpr static std_out_<1> std_out;
|
||||
constexpr static std_out_<2> std_err;
|
||||
|
||||
/*
|
||||
inline std::true_type is_initializer (const std_in_ &) {return {};}
|
||||
inline std::true_type is_initializer (const std_out_<1> &) {return {};}
|
||||
inline std::true_type is_initializer (const std_out_<2> &) {return {};}
|
||||
inline std::true_type is_initializer (const std_out_<1,2> &) {return {};}
|
||||
|
||||
|
||||
inline std::true_type is_initializer ( const api::close_in &) {return {}; }
|
||||
inline std::true_type is_initializer ( const api::null_in &) {return {}; }
|
||||
inline std::true_type is_initializer ( const api::file_in &) {return {}; }
|
||||
inline std::true_type is_initializer ( const api::pipe_in &) {return {}; }
|
||||
|
||||
template<int N, int M>
|
||||
inline std::true_type is_initializer ( const api::close_out<N,M> &) {return {}; }
|
||||
template<int N, int M>
|
||||
inline std::true_type is_initializer ( const api::null_out<N,M> &) {return {}; }
|
||||
template<int N, int M>
|
||||
inline std::true_type is_initializer ( const api::file_out<N,M> &) {return {}; }
|
||||
template<int N, int M>
|
||||
inline std::true_type is_initializer ( const api::pipe_out<N,M> &) {return {}; }
|
||||
|
||||
template<int N, int M, typename T>
|
||||
inline std::true_type is_initializer ( const api::async_out_buffer<N,M, T> &) {return {}; }
|
||||
|
||||
template<int N, int M, typename T>
|
||||
inline std::true_type is_initializer ( const api::async_out_cb<N,M, T> &) {return {}; }
|
||||
|
||||
template<int N, int M, typename T, typename U>
|
||||
inline std::true_type is_initializer ( const api::async_out_cb_until<N,M,T,U> &) {return {}; }
|
||||
*/
|
||||
|
||||
}
|
||||
|
||||
using boost::asio::buffer;
|
||||
|
||||
@@ -15,23 +15,98 @@
|
||||
#include <boost/process/detail/handler_base.hpp>
|
||||
#include <boost/iostreams/device/file_descriptor.hpp>
|
||||
|
||||
#if defined (BOOST_PROCESS_USE_FUTURE)
|
||||
#include <future>
|
||||
#endif
|
||||
|
||||
#include <iostream>
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace boost { namespace process { namespace detail { namespace windows {
|
||||
|
||||
struct async_in : public ::boost::process::detail::handler_base
|
||||
|
||||
template<typename Buffer>
|
||||
struct async_in_buffer : ::boost::process::detail::windows::async_handler
|
||||
{
|
||||
//boost::iostreams::file_descriptor_source file;
|
||||
std::shared_ptr<boost::asio::windows::stream_handle> stream_handle;
|
||||
|
||||
template<typename T>
|
||||
async_in(T&&) {}
|
||||
Buffer & buf;
|
||||
|
||||
template <class WindowsExecutor>
|
||||
void on_setup(WindowsExecutor &e) const
|
||||
#if defined (BOOST_PROCESS_USE_FUTURE)
|
||||
std::shared_ptr<std::promise<void>> promise;
|
||||
async_in_val operator<(std::future<void> & fut)
|
||||
{
|
||||
//e.startup_info.hStdInput = file.handle();
|
||||
//e.startup_info.dwFlags |= boost::detail::winapi::STARTF_USESTDHANDLES_;
|
||||
promise = std::make_shared<std::promise<void>>();
|
||||
fut = promise->get_future(); return std::move(*this);
|
||||
}
|
||||
#endif
|
||||
|
||||
std::shared_ptr<boost::process::pipe> pipe = std::make_shared<boost::process::pipe>(boost::process::pipe::create_async());
|
||||
//because the pipe will be moved later on, but i might need the source at another point.
|
||||
boost::iostreams::file_descriptor_source source = pipe->source();
|
||||
|
||||
async_in_buffer(Buffer & buf) : buf(buf)
|
||||
{
|
||||
}
|
||||
template <typename Executor>
|
||||
inline void on_success(Executor &exec) const
|
||||
{
|
||||
boost::asio::io_service &is_ser = get_io_service(exec.seq);
|
||||
auto stream_handle = this->stream_handle;
|
||||
auto pipe = this->pipe;
|
||||
|
||||
#if defined (BOOST_PROCESS_USE_FUTURE)
|
||||
if (this->promise)
|
||||
{
|
||||
auto promise = this->promise;
|
||||
|
||||
boost::asio::async_write(*stream_handle, buf,
|
||||
[promise](const boost::system::error_code & ec, std::size_t)
|
||||
{
|
||||
std::error_code e(ec.value(), std::system_category());
|
||||
promise->set_exception(std::make_exception_ptr(std::system_error(e)));
|
||||
promise->set_value();
|
||||
});
|
||||
}
|
||||
else
|
||||
#endif
|
||||
boost::asio::async_write(*stream_handle, buf,
|
||||
[stream_handle, pipe](const boost::system::error_code&ec, std::size_t size){});
|
||||
}
|
||||
|
||||
template<typename Executor>
|
||||
auto on_exit_handler(Executor & exec)
|
||||
{
|
||||
auto stream_handle = this->stream_handle;
|
||||
auto pipe = this->pipe;
|
||||
return [stream_handle, pipe](const std::error_code & ec)
|
||||
{
|
||||
boost::asio::io_service & ios = stream_handle->get_io_service();
|
||||
ios.post([stream_handle]
|
||||
{
|
||||
boost::system::error_code ec;
|
||||
stream_handle->close(ec);
|
||||
});
|
||||
};
|
||||
|
||||
};
|
||||
template <typename WindowsExecutor>
|
||||
void on_setup(WindowsExecutor &exec)
|
||||
{
|
||||
stream_handle = std::make_shared<boost::asio::windows::stream_handle>(get_io_service(exec.seq), pipe->sink().handle());
|
||||
|
||||
boost::detail::winapi::SetHandleInformation(source.handle(),
|
||||
boost::detail::winapi::HANDLE_FLAG_INHERIT_,
|
||||
boost::detail::winapi::HANDLE_FLAG_INHERIT_);
|
||||
|
||||
exec.startup_info.hStdInput = source.handle();
|
||||
exec.startup_info.dwFlags |= boost::detail::winapi::STARTF_USESTDHANDLES_;
|
||||
exec.inherit_handles = true;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
}}}}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -99,81 +99,11 @@ struct async_out_buffer : ::boost::process::detail::windows::async_handler
|
||||
return [stream_handle, pipe](const std::error_code & ec)
|
||||
{
|
||||
boost::asio::io_service & ios = stream_handle->get_io_service();
|
||||
ios.post([stream_handle]{stream_handle->close();});
|
||||
|
||||
};
|
||||
|
||||
};
|
||||
template <typename WindowsExecutor>
|
||||
void on_setup(WindowsExecutor &exec)
|
||||
{
|
||||
stream_handle = std::make_shared<boost::asio::windows::stream_handle>(get_io_service(exec.seq), pipe->source().handle());
|
||||
apply_out_handles(exec, sink.handle(), std::integral_constant<int, p1>(), std::integral_constant<int, p2>());
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T> struct deduce_async_out_cb_type;
|
||||
template<typename T> struct deduce_async_out_cb_type<const std::function<void(T)>> {using type = T;};
|
||||
|
||||
|
||||
struct completion_handler {};
|
||||
|
||||
template<int p1, int p2, typename Callback>
|
||||
struct async_out_cb : ::boost::process::detail::windows::async_handler
|
||||
{
|
||||
Callback cb;
|
||||
|
||||
using argument_type = typename deduce_async_out_cb_type<Callback>::type;
|
||||
|
||||
std::shared_ptr<boost::asio::windows::stream_handle> stream_handle;
|
||||
std::shared_ptr<boost::asio::streambuf> buffer = std::make_shared<boost::asio::streambuf>();
|
||||
|
||||
std::shared_ptr<boost::process::pipe> pipe = std::make_shared<boost::process::pipe>(boost::process::pipe::create_async());
|
||||
//because the pipe will be moved later on, but i might need the source at another point.
|
||||
boost::iostreams::file_descriptor_sink sink = pipe->sink();
|
||||
|
||||
async_out_cb(const Callback & cb) : cb(cb) {}
|
||||
|
||||
template <typename Executor>
|
||||
inline void on_success(Executor &exec) const
|
||||
{
|
||||
boost::asio::io_service &is_ser = get_io_service(exec.seq);
|
||||
auto& stream_handle = this->stream_handle;
|
||||
auto pipe = this->pipe;
|
||||
auto buffer = this->buffer;
|
||||
auto cb = this->cb;
|
||||
auto func_p = std::make_shared<std::function<std::size_t(const boost::system::error_code&, std::size_t)>>();
|
||||
|
||||
*func_p = [stream_handle, pipe, buffer, cb, func_p](const boost::system::error_code&, std::size_t size)
|
||||
{
|
||||
if (buffer->size() > 0)
|
||||
{
|
||||
std::istream is (buffer.get());
|
||||
argument_type arg;
|
||||
arg.resize(buffer->size());
|
||||
is.read(&*arg.begin(), buffer->size());
|
||||
cb(std::move(arg));
|
||||
}
|
||||
if (stream_handle->is_open())
|
||||
{
|
||||
return 1024u;
|
||||
}
|
||||
else
|
||||
return 0u;
|
||||
};
|
||||
|
||||
boost::asio::async_read(*stream_handle, *buffer, *func_p, [](const boost::system::error_code & , std::size_t){});
|
||||
}
|
||||
|
||||
template<typename Executor>
|
||||
auto on_exit_handler(Executor & exec)
|
||||
{
|
||||
auto stream_handle = this->stream_handle;
|
||||
auto & pipe = this->pipe;
|
||||
return [stream_handle, pipe](const std::error_code & ec)
|
||||
{
|
||||
boost::asio::io_service & ios = stream_handle->get_io_service();
|
||||
ios.post([stream_handle]{stream_handle->close();});
|
||||
ios.post([stream_handle]
|
||||
{
|
||||
boost::system::error_code ec;
|
||||
stream_handle->close(ec);
|
||||
});
|
||||
|
||||
};
|
||||
|
||||
@@ -241,7 +171,11 @@ struct async_out_future : ::boost::process::detail::windows::async_handler
|
||||
return [stream_handle, pipe](const std::error_code & ec)
|
||||
{
|
||||
boost::asio::io_service & ios = stream_handle->get_io_service();
|
||||
ios.post([stream_handle]{stream_handle->close();});
|
||||
ios.post([stream_handle]
|
||||
{
|
||||
boost::system::error_code ec;
|
||||
stream_handle->close(ec);
|
||||
});
|
||||
|
||||
};
|
||||
|
||||
|
||||
@@ -27,6 +27,9 @@ struct file_in : public ::boost::process::detail::handler_base
|
||||
template <class WindowsExecutor>
|
||||
void on_setup(WindowsExecutor &e) const
|
||||
{
|
||||
boost::detail::winapi::SetHandleInformation(file.handle(),
|
||||
boost::detail::winapi::HANDLE_FLAG_INHERIT_,
|
||||
boost::detail::winapi::HANDLE_FLAG_INHERIT_);
|
||||
e.startup_info.hStdInput = file.handle();
|
||||
e.startup_info.dwFlags |= boost::detail::winapi::STARTF_USESTDHANDLES_;
|
||||
e.inherit_handles = true;
|
||||
|
||||
Reference in New Issue
Block a user