diff --git a/include/boost/winasio/named_pipe/named_pipe.hpp b/include/boost/winasio/named_pipe/named_pipe.hpp index e2a5861..5f67358 100644 --- a/include/boost/winasio/named_pipe/named_pipe.hpp +++ b/include/boost/winasio/named_pipe/named_pipe.hpp @@ -75,50 +75,53 @@ class named_pipe : public boost::asio::windows::basic_stream_handle { parent_type::assign(hPipe); } - template - BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(ConnectHandler, - void(boost::system::error_code, - std::size_t)) - async_server_connect( - BOOST_ASIO_MOVE_ARG(ConnectHandler) - handler BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type)) { - boost::system::error_code ec; - boost::asio::windows::overlapped_ptr optr(this->get_executor(), - std::move(handler)); - bool fConnected = false; - fConnected = ConnectNamedPipe(this->native_handle(), optr.get()); - // Overlapped ConnectNamedPipe should return zero. - if (fConnected) { - // printf("ConnectNamedPipe failed with %d.\n", GetLastError()); - ec = boost::system::error_code(::GetLastError(), - boost::system::system_category()); - optr.complete(ec, 0); - return; - } - - switch (GetLastError()) { - // The overlapped connection in progress. - case ERROR_IO_PENDING: - optr.release(); - break; - // Client is already connected, so signal an event. - case ERROR_PIPE_CONNECTED: { - // In the win32 example here we need to reset the overlapp event when pipe - // already is connected. But this case overlapped_ptr cannot trigger this - // because iocp does not register this pipe instance. - optr.complete(ec, 0); - break; - } - // If an error occurs during the connect operation... - default: { - // printf("Some named pipe op failed with %d.\n", GetLastError()); - ec = boost::system::error_code(::GetLastError(), - boost::asio::error::get_system_category()); - optr.complete(ec, 0); - } - } + template auto async_server_connect(Token &&token) { + return boost::asio::async_initiate( + [this](auto handler) { + // init optr to pass through the user handler. + boost::asio::windows::overlapped_ptr optr( + this->get_executor(), + [h = std::move(handler)](boost::system::error_code ec, + std::size_t) mutable { + std::move(h)(ec); + }); + boost::system::error_code ec; + bool fConnected = false; + fConnected = ConnectNamedPipe(this->native_handle(), optr.get()); + // Overlapped ConnectNamedPipe should return zero. + if (fConnected) { + // printf("ConnectNamedPipe failed with %d.\n", GetLastError()); + ec = boost::system::error_code(::GetLastError(), + boost::system::system_category()); + optr.complete(ec, 0); + return; + } + + switch (GetLastError()) { + // The overlapped connection in progress. + case ERROR_IO_PENDING: + optr.release(); + break; + // Client is already connected, so signal an event. + case ERROR_PIPE_CONNECTED: { + // In the win32 example here we need to reset the overlapp event + // when pipe already is connected. But this case overlapped_ptr + // cannot trigger this because iocp does not register this pipe + // instance. + optr.complete(ec, 0); + break; + } + // If an error occurs during the connect operation... + default: { + // printf("Some named pipe op failed with %d.\n", GetLastError()); + ec = boost::system::error_code( + ::GetLastError(), boost::asio::error::get_system_category()); + optr.complete(ec, 0); + } + } + }, + token); } // used for client to connect diff --git a/include/boost/winasio/named_pipe/named_pipe_acceptor.hpp b/include/boost/winasio/named_pipe/named_pipe_acceptor.hpp index fa4efe3..a6c7bf5 100644 --- a/include/boost/winasio/named_pipe/named_pipe_acceptor.hpp +++ b/include/boost/winasio/named_pipe/named_pipe_acceptor.hpp @@ -56,11 +56,20 @@ template class named_pipe_acceptor { async_accept(named_pipe &pipe, BOOST_ASIO_MOVE_ARG(AcceptToken) token BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type)) { - - return boost::asio::async_compose( - details::async_accept_op(&pipe, this->endpoint_), token, - pipe); + return boost::asio::async_initiate( + [this, &pipe](auto handler) { + boost::system::error_code ec; + pipe.server_create(ec, endpoint_); + if (ec) { + std::move(handler)(ec); + return; + } + pipe.async_server_connect( + [h = std::move(handler), this]( + boost::system::error_code ec) mutable { std::move(h)(ec); }); + }, + token); } // TODO: fix move and rebind executor @@ -73,14 +82,22 @@ template class named_pipe_acceptor { named_pipe)) async_accept(BOOST_ASIO_MOVE_ARG(MoveAcceptToken) token BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type)) { - // std::cout << "async_accept func" << std::endl; - - return boost::asio::async_compose)>( - details::async_move_accept_op(&this->pipe_, - this->endpoint_), - token, this->pipe_); + return boost::asio::async_initiate)>( + [this](auto handler) { + boost::system::error_code ec; + pipe_.server_create(ec, endpoint_); + if (ec) { + std::move(handler)(ec, std::move(pipe_)); + return; + } + pipe_.async_server_connect([h = std::move(handler), this]( + boost::system::error_code ec) mutable { + std::move(h)(ec, std::move(pipe_)); + }); + }, + token); } const endpoint_type endpoint_; diff --git a/include/boost/winasio/named_pipe/named_pipe_server_details.hpp b/include/boost/winasio/named_pipe/named_pipe_server_details.hpp index e83e397..c76e344 100644 --- a/include/boost/winasio/named_pipe/named_pipe_server_details.hpp +++ b/include/boost/winasio/named_pipe/named_pipe_server_details.hpp @@ -18,84 +18,7 @@ namespace boost { namespace winasio { -namespace details { - -// handler of signature void(error_code, pipe) -template -class async_move_accept_op : boost::asio::coroutine { -public: - typedef std::string endpoint_type; - - async_move_accept_op(named_pipe *pipe, endpoint_type endpoint) - : pipe_(pipe), endpoint_(endpoint) {} - - template - void operator()(Self &self, boost::system::error_code ec = {}) { - // std::cout << "async_move_accept_op" << std::endl; - if (ec) { - // std::cout << "async_move_accept_op has error" << std::endl; - self.complete(ec, std::move(*pipe_)); - return; - } - // create named pipe - pipe_->server_create(ec, endpoint_); - if (ec) { - self.complete(ec, std::move(*pipe_)); - return; - } - // connect to namedpipe - pipe_->async_server_connect( - [self = std::move(self), p = pipe_](boost::system::error_code ec, - std::size_t) mutable { - self.complete(ec, std::move(*p)); - }); - } - -private: - // pipe for movable case is the pipe holder in acceptor, which needs to moved - // to handler function, so that to free acceptor pipe holder to handle the - // next connection. - named_pipe *pipe_; - endpoint_type const endpoint_; -}; - -// handler of signature void(error_code) -template class async_accept_op : boost::asio::coroutine { -public: - typedef std::string endpoint_type; - - async_accept_op(named_pipe *pipe, endpoint_type endpoint) - : pipe_(pipe), endpoint_(endpoint) {} - - template - void operator()(Self &self, boost::system::error_code ec = {}) { - // std::cout << "async_move_accept_op" << std::endl; - if (ec) { - // std::cout << "async_move_accept_op has error" << std::endl; - self.complete(ec); - return; - } - // create named pipe - pipe_->server_create(ec, endpoint_); - if (ec) { - self.complete(ec); - return; - } - // connect to namedpipe - pipe_->async_server_connect( - [self = std::move(self)](boost::system::error_code ec, - std::size_t) mutable { self.complete(ec); }); - } - -private: - // pipe for movable case is the pipe holder in acceptor, which needs to moved - // to handler function, so that to free acceptor pipe holder to handle the - // next connection. - named_pipe *pipe_; - endpoint_type const endpoint_; -}; - -} // namespace details +namespace details {} // namespace details } // namespace winasio } // namespace boost