]> git.proxmox.com Git - ceph.git/blobdiff - ceph/src/boost/boost/process/detail/windows/async_pipe.hpp
import new upstream nautilus stable release 14.2.8
[ceph.git] / ceph / src / boost / boost / process / detail / windows / async_pipe.hpp
index 1bc2c8fec5e31d32742ae7f3222e48056ac59124..06d5f2d854fd271540f074f49e657d968124b9a0 100644 (file)
@@ -14,6 +14,7 @@
 #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>
@@ -39,23 +40,30 @@ class async_pipe
 {
     ::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,
@@ -99,12 +107,12 @@ public:
         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)
@@ -112,12 +120,12 @@ public:
         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());
         }
     }
 
@@ -128,9 +136,9 @@ public:
     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>
@@ -167,7 +175,7 @@ public:
         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,
@@ -178,7 +186,7 @@ public:
         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;}
@@ -189,14 +197,16 @@ public:
 
     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;
     }
 
@@ -214,7 +224,7 @@ public:
                  ::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 &
     {
@@ -230,16 +240,15 @@ public:
                  ::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;
@@ -265,14 +274,16 @@ async_pipe::async_pipe(const async_pipe& p)  :
              ::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
 
@@ -284,7 +295,7 @@ async_pipe::async_pipe(boost::asio::io_context & ios_source,
 #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_)
@@ -309,6 +320,44 @@ async_pipe::async_pipe(boost::asio::io_context & ios_source,
     _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();
@@ -320,6 +369,8 @@ async_pipe& async_pipe::operator=(const async_pipe & p)
     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(
@@ -337,24 +388,23 @@ async_pipe& async_pipe::operator=(const async_pipe & p)
         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;
 }