2
0
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:
klemens-morgenstern
2016-04-09 13:54:52 +02:00
parent e7c7be6ad3
commit 11d56e28eb
6 changed files with 125 additions and 153 deletions

View File

@@ -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;

View File

@@ -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

View File

@@ -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);
});
};

View File

@@ -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;