#include <boost/winapi/access_rights.hpp>
#include <boost/winapi/process.hpp>
#include <boost/process/detail/windows/basic_pipe.hpp>
+#include <boost/asio/post.hpp>
#include <boost/asio/windows/stream_handle.hpp>
#include <atomic>
#include <system_error>
{
::boost::asio::windows::stream_handle _source;
::boost::asio::windows::stream_handle _sink ;
+
+ inline async_pipe(boost::asio::io_context & ios_source,
+ boost::asio::io_context & ios_sink,
+ const std::string & name, bool private_);
+
public:
typedef ::boost::winapi::HANDLE_ native_handle_type;
typedef ::boost::asio::windows::stream_handle handle_type;
- inline async_pipe(boost::asio::io_context & ios,
- const std::string & name = make_pipe_name())
- : async_pipe(ios, ios, name) {}
+ async_pipe(boost::asio::io_context & ios) : async_pipe(ios, ios, make_pipe_name(), true) {}
+ async_pipe(boost::asio::io_context & ios_source, boost::asio::io_context & ios_sink)
+ : async_pipe(ios_source, ios_sink, make_pipe_name(), true) {}
+
+ async_pipe(boost::asio::io_context & ios, const std::string & name)
+ : async_pipe(ios, ios, name, false) {}
+
+ async_pipe(boost::asio::io_context & ios_source, boost::asio::io_context & ios_sink, const std::string & name)
+ : async_pipe(ios_source, ios_sink, name, false) {}
+
- inline async_pipe(boost::asio::io_context & ios_source,
- boost::asio::io_context & ios_sink,
- const std::string & name = make_pipe_name());
inline async_pipe(const async_pipe& rhs);
async_pipe(async_pipe&& rhs) : _source(std::move(rhs._source)), _sink(std::move(rhs._sink))
{
- rhs._source.assign (::boost::winapi::INVALID_HANDLE_VALUE_);
- rhs._sink .assign (::boost::winapi::INVALID_HANDLE_VALUE_);
}
template<class CharT, class Traits = std::char_traits<CharT>>
explicit async_pipe(::boost::asio::io_context & ios_source,
if (_sink.is_open())
{
_sink.close();
- _sink = handle_type(_sink.get_io_context());
+ _sink = handle_type(_sink.get_executor());
}
if (_source.is_open())
{
_source.close();
- _source = handle_type(_source.get_io_context());
+ _source = handle_type(_source.get_executor());
}
}
void close(boost::system::error_code & ec)
if (_sink.is_open())
{
_sink.close(ec);
- _sink = handle_type(_sink.get_io_context());
+ _sink = handle_type(_sink.get_executor());
}
if (_source.is_open())
{
_source.close(ec);
- _source = handle_type(_source.get_io_context());
+ _source = handle_type(_source.get_executor());
}
}
void async_close()
{
if (_sink.is_open())
- _sink.get_io_context(). post([this]{_sink.close();});
+ boost::asio::post(_sink.get_executor(), [this]{_sink.close();});
if (_source.is_open())
- _source.get_io_context().post([this]{_source.close();});
+ boost::asio::post(_source.get_executor(), [this]{_source.close();});
}
template<typename MutableBufferSequence>
const MutableBufferSequence & buffers,
ReadHandler &&handler)
{
- _source.async_read_some(buffers, std::forward<ReadHandler>(handler));
+ return _source.async_read_some(buffers, std::forward<ReadHandler>(handler));
}
template<typename ConstBufferSequence,
const ConstBufferSequence & buffers,
WriteHandler && handler)
{
- _sink.async_write_some(buffers, std::forward<WriteHandler>(handler));
+ return _sink.async_write_some(buffers, std::forward<WriteHandler>(handler));
}
const handle_type & sink () const & {return _sink;}
handle_type source(::boost::asio::io_context& ios) &&
{
- ::boost::asio::windows::stream_handle stolen(ios, _source.native_handle());
- _source.assign(::boost::winapi::INVALID_HANDLE_VALUE_);
+ ::boost::asio::windows::stream_handle stolen(ios.get_executor(), _source.native_handle());
+ boost::system::error_code ec;
+ _source.assign(::boost::winapi::INVALID_HANDLE_VALUE_, ec);
return stolen;
}
handle_type sink (::boost::asio::io_context& ios) &&
{
- ::boost::asio::windows::stream_handle stolen(ios, _sink.native_handle());
- _sink.assign(::boost::winapi::INVALID_HANDLE_VALUE_);
+ ::boost::asio::windows::stream_handle stolen(ios.get_executor(), _sink.native_handle());
+ boost::system::error_code ec;
+ _sink.assign(::boost::winapi::INVALID_HANDLE_VALUE_, ec);
return stolen;
}
::boost::winapi::DUPLICATE_SAME_ACCESS_))
throw_last_error("Duplicate Pipe Failed");
- return ::boost::asio::windows::stream_handle(ios, source);
+ return ::boost::asio::windows::stream_handle(ios.get_executor(), source);
}
handle_type sink (::boost::asio::io_context& ios) const &
{
::boost::winapi::DUPLICATE_SAME_ACCESS_))
throw_last_error("Duplicate Pipe Failed");
- return ::boost::asio::windows::stream_handle(ios, sink);
+ return ::boost::asio::windows::stream_handle(ios.get_executor(), sink);
}
};
-
-
async_pipe::async_pipe(const async_pipe& p) :
- _source(const_cast<handle_type&>(p._source).get_io_context()),
- _sink (const_cast<handle_type&>(p._sink).get_io_context())
+ _source(const_cast<handle_type&>(p._source).get_executor()),
+ _sink (const_cast<handle_type&>(p._sink).get_executor())
{
+
auto proc = ::boost::winapi::GetCurrentProcess();
::boost::winapi::HANDLE_ source;
::boost::winapi::DUPLICATE_SAME_ACCESS_))
throw_last_error("Duplicate Pipe Failed");
- _source.assign(source);
- _sink. assign(sink);
+ if (source != ::boost::winapi::INVALID_HANDLE_VALUE_)
+ _source.assign(source);
+ if (sink != ::boost::winapi::INVALID_HANDLE_VALUE_)
+ _sink. assign(sink);
}
async_pipe::async_pipe(boost::asio::io_context & ios_source,
boost::asio::io_context & ios_sink,
- const std::string & name) : _source(ios_source), _sink(ios_sink)
+ const std::string & name, bool private_) : _source(ios_source), _sink(ios_sink)
{
static constexpr int FILE_FLAG_OVERLAPPED_ = 0x40000000; //temporary
#endif
::boost::winapi::PIPE_ACCESS_INBOUND_
| FILE_FLAG_OVERLAPPED_, //write flag
- 0, 1, 8192, 8192, 0, nullptr);
+ 0, private_ ? 1 : ::boost::winapi::PIPE_UNLIMITED_INSTANCES_, 8192, 8192, 0, nullptr);
if (source == boost::winapi::INVALID_HANDLE_VALUE_)
_sink.assign(sink);
}
+template<class CharT, class Traits>
+async_pipe& async_pipe::operator=(const basic_pipe<CharT, Traits> & p)
+{
+ auto proc = ::boost::winapi::GetCurrentProcess();
+
+ ::boost::winapi::HANDLE_ source;
+ ::boost::winapi::HANDLE_ sink;
+
+ //cannot get the handle from a const object.
+ auto source_in = p.native_source();
+ auto sink_in = p.native_sink();
+
+ if (source_in == ::boost::winapi::INVALID_HANDLE_VALUE_)
+ source = ::boost::winapi::INVALID_HANDLE_VALUE_;
+ else if (!::boost::winapi::DuplicateHandle(
+ proc, source_in.native_handle(), proc, &source, 0,
+ static_cast<::boost::winapi::BOOL_>(true),
+ ::boost::winapi::DUPLICATE_SAME_ACCESS_))
+ throw_last_error("Duplicate Pipe Failed");
+
+ if (sink_in == ::boost::winapi::INVALID_HANDLE_VALUE_)
+ sink = ::boost::winapi::INVALID_HANDLE_VALUE_;
+ else if (!::boost::winapi::DuplicateHandle(
+ proc, sink_in.native_handle(), proc, &sink, 0,
+ static_cast<::boost::winapi::BOOL_>(true),
+ ::boost::winapi::DUPLICATE_SAME_ACCESS_))
+ throw_last_error("Duplicate Pipe Failed");
+
+ //so we also assign the io_context
+ if (source != ::boost::winapi::INVALID_HANDLE_VALUE_)
+ _source.assign(source);
+
+ if (sink != ::boost::winapi::INVALID_HANDLE_VALUE_)
+ _sink.assign(sink);
+
+ return *this;
+}
+
async_pipe& async_pipe::operator=(const async_pipe & p)
{
auto proc = ::boost::winapi::GetCurrentProcess();
auto &source_in = const_cast<::boost::asio::windows::stream_handle &>(p._source);
auto &sink_in = const_cast<::boost::asio::windows::stream_handle &>(p._sink);
+ source_in.get_executor();
+
if (source_in.native_handle() == ::boost::winapi::INVALID_HANDLE_VALUE_)
source = ::boost::winapi::INVALID_HANDLE_VALUE_;
else if (!::boost::winapi::DuplicateHandle(
throw_last_error("Duplicate Pipe Failed");
//so we also assign the io_context
- _source = ::boost::asio::windows::stream_handle(source_in.get_io_context(), source);
- _sink = ::boost::asio::windows::stream_handle(source_in.get_io_context(), sink);
+ if (source != ::boost::winapi::INVALID_HANDLE_VALUE_)
+ _source = ::boost::asio::windows::stream_handle(source_in.get_executor(), source);
+ else
+ _source = ::boost::asio::windows::stream_handle(source_in.get_executor());
+
+ if (sink != ::boost::winapi::INVALID_HANDLE_VALUE_)
+ _sink = ::boost::asio::windows::stream_handle(source_in.get_executor(), sink);
+ else
+ _sink = ::boost::asio::windows::stream_handle(source_in.get_executor());
return *this;
}
async_pipe& async_pipe::operator=(async_pipe && rhs)
{
- if (_source.native_handle() != ::boost::winapi::INVALID_HANDLE_VALUE_)
- ::boost::winapi::CloseHandle(_source.native_handle());
-
- if (_sink.native_handle() != ::boost::winapi::INVALID_HANDLE_VALUE_)
- ::boost::winapi::CloseHandle(_sink.native_handle());
-
- _source.assign(rhs._source.native_handle());
- _sink .assign(rhs._sink .native_handle());
- rhs._source.assign(::boost::winapi::INVALID_HANDLE_VALUE_);
- rhs._sink .assign(::boost::winapi::INVALID_HANDLE_VALUE_);
+ _source = std::move(rhs._source);
+ _sink = std::move(rhs._sink);
return *this;
}