From c2fd1215f5ce38136df24f0e45778e2002217c96 Mon Sep 17 00:00:00 2001 From: Vinnie Falco Date: Fri, 7 Mar 2014 20:06:12 -0800 Subject: [PATCH] Refactor beast::asio: * New tools for completion handlers: - wrap_handler provides composed io_service execution guarantees. - bind_handler rebinds arguments to handlers. - shared_handler type-erases any completion handler. - buffer_sequence type-erases templated BufferSequences - abstract_socket replaces Socket - socket_wrapper replaces SocketWrapper - beast::asio placeholders to work with std::bind * Removed obsolete classes and functions - AbstractHandler - ComposedAsyncOperation - SharedFunction - SharedHandler - SharedHandlerAllocator - SharedHandlerPtr - SharedHandlerType - SocketBase - SocketWrapperStrand - wrapHandler * Refactored classes to use new tools - abstract_socket - socket_wrapper - HandshakeDetector - HttpClientType * Miscellanous tidying - socket classes moved to beast::asio namespace - beast asio files provide their own namespace declaration. - Fix IsCallPossible conflicting template parameter name - Use for C++11 compatibility. - Remove extraneous include path from build environment. --- Builds/QtCreator/rippled.pro | 2 +- Builds/VisualStudio2013/RippleD.props | 2 +- Builds/VisualStudio2013/RippleD.vcxproj | 2 +- .../VisualStudio2013/RippleD.vcxproj.filters | 1 - SConstruct | 3 +- src/{ => BeastConfig}/BeastConfig.h | 0 .../Builds/VisualStudio2013/beast.vcxproj | 44 +- .../VisualStudio2013/beast.vcxproj.filters | 75 +- src/beast/beast/Asio.h | 2 - src/beast/beast/asio/Asio.cpp | 6 + src/beast/beast/asio/abstract_socket.cpp | 217 ++++++ .../Socket.h => beast/asio/abstract_socket.h} | 282 +++---- src/beast/beast/asio/bind_handler.h | 163 ++++ src/beast/beast/asio/buffer_sequence.h | 110 +++ .../asio/placeholders.h} | 40 +- src/beast/beast/asio/shared_handler.h | 472 ++++++++++++ .../asio/socket_wrapper.h} | 595 +++++++-------- .../asio/tests/bind_handler_tests.cpp} | 51 +- .../beast/asio/tests/shared_handler_tests.cpp | 239 ++++++ .../beast/asio/tests/wrap_handler_tests.cpp | 287 +++++++ src/beast/beast/asio/wrap_handler.h | 176 +++++ .../boost/get_pointer.h} | 36 +- src/beast/beast/cxx14/memory.h | 2 - src/beast/beast/http/impl/ParsedURL.cpp | 4 +- src/beast/beast/http/impl/http_parser.cpp | 8 +- src/beast/beast/http/impl/http_parser.h | 33 + src/beast/beast/mpl/IsCallPossible.h | 7 +- .../beast_asio/async/AbstractHandler.h | 712 ------------------ .../modules/beast_asio/async/AsyncObject.h | 6 + .../beast_asio/async/ComposedAsyncOperation.h | 98 --- .../modules/beast_asio/async/SharedHandler.h | 108 --- .../beast_asio/async/SharedHandlerAllocator.h | 123 --- .../beast_asio/async/SharedHandlerPtr.h | 326 -------- .../beast_asio/async/SharedHandlerType.h | 211 ------ .../modules/beast_asio/async/WrapHandler.h | 209 ----- .../modules/beast_asio/basics/BuffersType.h | 135 ---- .../beast_asio/basics/FixedInputBuffer.h | 12 +- .../modules/beast_asio/basics/PeerRole.cpp | 12 +- .../modules/beast_asio/basics/PeerRole.h | 6 + .../modules/beast_asio/basics/SSLContext.cpp | 5 + .../modules/beast_asio/basics/SSLContext.h | 6 + .../modules/beast_asio/basics/SharedArg.h | 6 + src/beast/modules/beast_asio/beast_asio.cpp | 11 +- src/beast/modules/beast_asio/beast_asio.h | 34 +- .../beast_asio/http/HTTPClientType.cpp | 105 ++- .../modules/beast_asio/http/HTTPClientType.h | 15 +- .../modules/beast_asio/http/HTTPField.cpp | 4 + src/beast/modules/beast_asio/http/HTTPField.h | 4 + .../modules/beast_asio/http/HTTPHeaders.cpp | 3 + .../modules/beast_asio/http/HTTPHeaders.h | 4 + .../modules/beast_asio/http/HTTPMessage.cpp | 4 + .../modules/beast_asio/http/HTTPMessage.h | 4 + .../modules/beast_asio/http/HTTPParserImpl.h | 4 + .../modules/beast_asio/http/HTTPRequest.cpp | 3 + .../modules/beast_asio/http/HTTPRequest.h | 4 + .../modules/beast_asio/http/HTTPResponse.cpp | 3 + .../modules/beast_asio/http/HTTPResponse.h | 4 + .../modules/beast_asio/http/HTTPVersion.cpp | 4 + .../modules/beast_asio/http/HTTPVersion.h | 4 + .../protocol/HandshakeDetectLogic.h | 6 + .../protocol/HandshakeDetectLogicPROXY.cpp | 4 + .../protocol/HandshakeDetectLogicPROXY.h | 6 + .../protocol/HandshakeDetectLogicSSL2.h | 6 + .../protocol/HandshakeDetectLogicSSL3.h | 6 + .../beast_asio/protocol/HandshakeDetector.h | 95 ++- .../modules/beast_asio/protocol/InputParser.h | 9 +- .../beast_asio/protocol/PrefilledReadStream.h | 76 +- .../modules/beast_asio/sockets/Socket.cpp | 199 ----- .../beast_asio/sockets/SocketWrapperStrand.h | 66 -- .../modules/beast_asio/system/BoostIncludes.h | 3 + .../beast_asio/system/BoostUnitTests.cpp | 4 + .../modules/beast_asio/tests/PeerTest.cpp | 6 + src/beast/modules/beast_asio/tests/PeerTest.h | 9 +- src/beast/modules/beast_asio/tests/TestPeer.h | 9 +- .../beast_asio/tests/TestPeerBasics.cpp | 6 + .../modules/beast_asio/tests/TestPeerBasics.h | 6 + .../beast_asio/tests/TestPeerDetails.h | 15 +- .../beast_asio/tests/TestPeerDetailsTcp.h | 19 +- .../beast_asio/tests/TestPeerLogic.cpp | 10 +- .../modules/beast_asio/tests/TestPeerLogic.h | 15 +- .../tests/TestPeerLogicAsyncClient.cpp | 14 +- .../tests/TestPeerLogicAsyncClient.h | 8 +- .../tests/TestPeerLogicAsyncServer.cpp | 15 +- .../tests/TestPeerLogicAsyncServer.h | 8 +- .../tests/TestPeerLogicProxyClient.cpp | 9 +- .../tests/TestPeerLogicProxyClient.h | 8 +- .../tests/TestPeerLogicSyncClient.cpp | 10 +- .../tests/TestPeerLogicSyncClient.h | 8 +- .../tests/TestPeerLogicSyncServer.cpp | 10 +- .../tests/TestPeerLogicSyncServer.h | 8 +- .../modules/beast_asio/tests/TestPeerType.h | 6 + .../beast_asio/tests/TestPeerUnitTests.cpp | 9 +- src/beast/modules/beast_core/beast_core.h | 1 - .../beast_core/memory/SharedFunction.h | 334 -------- src/ripple/algorithm/api/CycledSet.h | 1 - src/ripple/beast/ripple_beast.cpp | 2 + src/ripple/common/KeyCache.h | 4 +- src/ripple/common/MultiSocket.h | 7 +- src/ripple/common/RippleSSLContext.h | 2 +- src/ripple/common/TaggedCache.h | 6 +- src/ripple/common/impl/MultiSocket.cpp | 69 +- src/ripple/common/impl/MultiSocketType.h | 286 +++---- src/ripple/common/impl/ResolverAsio.cpp | 20 +- src/ripple/common/seconds_clock.h | 2 +- src/ripple/http/api/Port.h | 4 +- src/ripple/http/impl/Door.h | 2 +- src/ripple/http/impl/Peer.h | 8 +- src/ripple/http/impl/Port.cpp | 2 +- src/ripple/http/ripple_http.cpp | 2 +- src/ripple/http/ripple_http.h | 4 +- src/ripple/json/ripple_json.cpp | 2 +- src/ripple/json/ripple_json.h | 6 +- src/ripple/peerfinder/api/Types.h | 2 +- src/ripple/peerfinder/impl/Checker.cpp | 14 +- src/ripple/peerfinder/impl/Checker.h | 15 +- src/ripple/peerfinder/impl/CheckerAdapter.h | 6 +- src/ripple/peerfinder/ripple_peerfinder.cpp | 10 +- src/ripple/peerfinder/ripple_peerfinder.h | 2 +- src/ripple/peerfinder/sim/Tests.cpp | 2 +- src/ripple/radmap/api/BasicFullBelowCache.h | 2 +- src/ripple/resource/api/Manager.h | 2 +- src/ripple/resource/ripple_resource.cpp | 2 +- src/ripple/resource/ripple_resource.h | 2 +- src/ripple/rocksdb/ripple_rocksdb.h | 2 +- src/ripple/sitefiles/impl/Logic.h | 7 +- src/ripple/sitefiles/ripple_sitefiles.cpp | 6 +- src/ripple/sitefiles/ripple_sitefiles.h | 8 +- src/ripple/sslutil/ripple_sslutil.h | 2 +- src/ripple/testoverlay/ripple_testoverlay.h | 4 +- src/ripple/types/api/CryptoIdentifier.h | 4 +- src/ripple/types/api/IdentifierStorage.h | 4 +- src/ripple/types/ripple_types.h | 6 +- src/ripple/validators/impl/SourceURL.cpp | 6 +- src/ripple/validators/ripple_validators.cpp | 8 +- src/ripple/validators/ripple_validators.h | 4 +- src/ripple_app/main/Application.cpp | 4 +- src/ripple_app/main/CollectorManager.h | 2 +- src/ripple_app/ripple_app.cpp | 2 +- src/ripple_app/ripple_app.h | 6 +- src/ripple_app/ripple_app_pt1.cpp | 2 +- src/ripple_basics/ripple_basics.cpp | 2 +- src/ripple_basics/ripple_basics.h | 27 +- src/ripple_basics/system/BoostIncludes.h | 9 +- src/ripple_basics/types/BasicTypes.h | 2 +- src/ripple_core/functional/Job.cpp | 4 +- src/ripple_core/functional/JobQueue.cpp | 4 +- src/ripple_core/ripple_core.cpp | 2 +- src/ripple_core/ripple_core.h | 4 +- src/ripple_data/ripple_data.cpp | 2 +- .../ripple_hyperleveldb.cpp | 84 +-- src/ripple_hyperleveldb/ripple_hyperleveldb.h | 10 +- src/ripple_leveldb/ripple_leveldb.cpp | 84 +-- src/ripple_net/ripple_net.cpp | 2 +- src/ripple_net/ripple_net.h | 2 +- src/ripple_overlay/api/PackedMessage.h | 2 +- src/ripple_overlay/ripple_overlay.h | 2 +- src/ripple_rpc/ripple_rpc.cpp | 2 +- src/ripple_rpc/ripple_rpc.h | 2 +- src/ripple_websocket/autosocket/AutoSocket.h | 10 +- src/ripple_websocket/ripple_websocket.cpp | 20 +- src/ripple_websocket/ripple_websocket.h | 12 +- 161 files changed, 3138 insertions(+), 3786 deletions(-) rename src/{ => BeastConfig}/BeastConfig.h (100%) create mode 100644 src/beast/beast/asio/abstract_socket.cpp rename src/beast/{modules/beast_asio/sockets/Socket.h => beast/asio/abstract_socket.h} (54%) create mode 100644 src/beast/beast/asio/bind_handler.h create mode 100644 src/beast/beast/asio/buffer_sequence.h rename src/beast/{modules/beast_asio/async/SharedHandler.cpp => beast/asio/placeholders.h} (55%) create mode 100644 src/beast/beast/asio/shared_handler.h rename src/beast/{modules/beast_asio/sockets/SocketWrapper.h => beast/asio/socket_wrapper.h} (59%) rename src/beast/{modules/beast_asio/sockets/SocketBase.h => beast/asio/tests/bind_handler_tests.cpp} (50%) create mode 100644 src/beast/beast/asio/tests/shared_handler_tests.cpp create mode 100644 src/beast/beast/asio/tests/wrap_handler_tests.cpp create mode 100644 src/beast/beast/asio/wrap_handler.h rename src/beast/{modules/beast_asio/sockets/SocketBase.cpp => beast/boost/get_pointer.h} (60%) create mode 100644 src/beast/beast/http/impl/http_parser.h delete mode 100644 src/beast/modules/beast_asio/async/AbstractHandler.h delete mode 100644 src/beast/modules/beast_asio/async/ComposedAsyncOperation.h delete mode 100644 src/beast/modules/beast_asio/async/SharedHandler.h delete mode 100644 src/beast/modules/beast_asio/async/SharedHandlerAllocator.h delete mode 100644 src/beast/modules/beast_asio/async/SharedHandlerPtr.h delete mode 100644 src/beast/modules/beast_asio/async/SharedHandlerType.h delete mode 100644 src/beast/modules/beast_asio/async/WrapHandler.h delete mode 100644 src/beast/modules/beast_asio/basics/BuffersType.h delete mode 100644 src/beast/modules/beast_asio/sockets/Socket.cpp delete mode 100644 src/beast/modules/beast_asio/sockets/SocketWrapperStrand.h delete mode 100644 src/beast/modules/beast_core/memory/SharedFunction.h diff --git a/Builds/QtCreator/rippled.pro b/Builds/QtCreator/rippled.pro index b4801a55fb5..7e67307791b 100644 --- a/Builds/QtCreator/rippled.pro +++ b/Builds/QtCreator/rippled.pro @@ -45,7 +45,7 @@ linux-g++:QMAKE_CXXFLAGS += \ -pthread INCLUDEPATH += \ - "../../src" \ + "../../src/BeastConfig/" \ "../../src/leveldb/" \ "../../src/leveldb/port" \ "../../src/leveldb/include" \ diff --git a/Builds/VisualStudio2013/RippleD.props b/Builds/VisualStudio2013/RippleD.props index 0e086127dd7..82632911480 100644 --- a/Builds/VisualStudio2013/RippleD.props +++ b/Builds/VisualStudio2013/RippleD.props @@ -14,7 +14,7 @@ _VARIADIC_MAX=10;_WIN32_WINNT=0x0600;_SCL_SECURE_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;WIN32;%(PreprocessorDefinitions) true Level3 - $(RepoDir)\src\protobuf\src;$(RepoDir)\src\protobuf\vsprojects;$(RepoDir)\src;$(RepoDir)\src\leveldb;$(RepoDir)\src\leveldb\include;$(RepoDir)\build\proto;%(AdditionalIncludeDirectories) + $(RepoDir)\src\BeastConfig;$(RepoDir)\src\protobuf\src;$(RepoDir)\src\protobuf\vsprojects;$(RepoDir)\src\leveldb;$(RepoDir)\src\leveldb\include;$(RepoDir)\build\proto;%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) Async 4018;4244 diff --git a/Builds/VisualStudio2013/RippleD.vcxproj b/Builds/VisualStudio2013/RippleD.vcxproj index b2af9278833..af832708e9b 100644 --- a/Builds/VisualStudio2013/RippleD.vcxproj +++ b/Builds/VisualStudio2013/RippleD.vcxproj @@ -2228,6 +2228,7 @@ + @@ -2663,7 +2664,6 @@ - diff --git a/Builds/VisualStudio2013/RippleD.vcxproj.filters b/Builds/VisualStudio2013/RippleD.vcxproj.filters index 6c75d25b39b..912dd38f202 100644 --- a/Builds/VisualStudio2013/RippleD.vcxproj.filters +++ b/Builds/VisualStudio2013/RippleD.vcxproj.filters @@ -2069,7 +2069,6 @@ [2] Old Ripple\ripple_app\misc - [2] Old Ripple\ripple_core\functional diff --git a/SConstruct b/SConstruct index d5c559b11cf..8ba8bbd4ce0 100644 --- a/SConstruct +++ b/SConstruct @@ -149,11 +149,10 @@ else: # INCLUDE_PATHS = [ '.', - 'src', + 'src/BeastConfig', 'src/leveldb', 'src/leveldb/port', 'src/leveldb/include', - 'src/beast', 'build/proto' ] diff --git a/src/BeastConfig.h b/src/BeastConfig/BeastConfig.h similarity index 100% rename from src/BeastConfig.h rename to src/BeastConfig/BeastConfig.h diff --git a/src/beast/Builds/VisualStudio2013/beast.vcxproj b/src/beast/Builds/VisualStudio2013/beast.vcxproj index ca4bc0d47bc..6bceab5094d 100644 --- a/src/beast/Builds/VisualStudio2013/beast.vcxproj +++ b/src/beast/Builds/VisualStudio2013/beast.vcxproj @@ -83,8 +83,15 @@ + + + + + + + @@ -150,6 +157,7 @@ + @@ -238,15 +246,7 @@ - - - - - - - - @@ -270,9 +270,6 @@ - - - @@ -325,7 +322,6 @@ - @@ -424,6 +420,12 @@ + + true + true + true + true + true @@ -743,12 +745,6 @@ true - - true - true - true - true - true true @@ -826,18 +822,6 @@ true true - - true - true - true - true - - - true - true - true - true - true true diff --git a/src/beast/Builds/VisualStudio2013/beast.vcxproj.filters b/src/beast/Builds/VisualStudio2013/beast.vcxproj.filters index f28b074d10d..09b0c43b5a2 100644 --- a/src/beast/Builds/VisualStudio2013/beast.vcxproj.filters +++ b/src/beast/Builds/VisualStudio2013/beast.vcxproj.filters @@ -159,9 +159,6 @@ {54bbe439-76c3-4781-becc-9c70a2be6d82} - - {af535ad5-a06c-462f-8ac0-8207a708e032} - {c7a576bb-27b2-486e-aa14-3c51aa86c50f} @@ -710,36 +707,12 @@ beast_core\system - - beast_asio\async - - - beast_asio\async - - - beast_asio\async - - - beast_asio\async - - - beast_asio\async - beast_asio\basics beast_asio\basics - - beast_asio\sockets - - - beast_asio\sockets - - - beast_asio\sockets - beast_asio\system @@ -824,9 +797,6 @@ beast_asio\http - - beast_asio\basics - beast_core\memory @@ -839,9 +809,6 @@ beast_core\diagnostic - - beast_core\memory - beast @@ -986,12 +953,6 @@ beast\crypto - - beast_asio\async - - - beast_asio\async - beast @@ -1338,6 +1299,30 @@ beast\cxx14 + + beast\asio + + + beast\asio + + + beast\asio + + + beast\asio + + + beast\asio + + + beast\asio + + + beast\asio + + + beast\http\impl + @@ -1649,18 +1634,9 @@ beast_core\system - - beast_asio\async - beast_asio\basics - - beast_asio\sockets - - - beast_asio\sockets - beast_asio\system @@ -1931,6 +1907,9 @@ beast\cxx14\tests + + beast\asio + diff --git a/src/beast/beast/Asio.h b/src/beast/beast/Asio.h index d4e8c590f60..13c961f4775 100644 --- a/src/beast/beast/Asio.h +++ b/src/beast/beast/Asio.h @@ -20,6 +20,4 @@ #ifndef BEAST_ASIO_H_INCLUDED #define BEAST_ASIO_H_INCLUDED -#include "asio/IPAddressConversion.h" - #endif diff --git a/src/beast/beast/asio/Asio.cpp b/src/beast/beast/asio/Asio.cpp index 5aa88c74a63..aada5e4b3d9 100644 --- a/src/beast/beast/asio/Asio.cpp +++ b/src/beast/beast/asio/Asio.cpp @@ -20,3 +20,9 @@ #include "BeastConfig.h" #include "impl/IPAddressConversion.cpp" + +#include "tests/wrap_handler_tests.cpp" +#include "tests/bind_handler_tests.cpp" +#include "tests/shared_handler_tests.cpp" + +#include "abstract_socket.cpp" // TEMPORARY! diff --git a/src/beast/beast/asio/abstract_socket.cpp b/src/beast/beast/asio/abstract_socket.cpp new file mode 100644 index 00000000000..ba2e950e30b --- /dev/null +++ b/src/beast/beast/asio/abstract_socket.cpp @@ -0,0 +1,217 @@ +//------------------------------------------------------------------------------ +/* + This file is part of Beast: https://github.com/vinniefalco/Beast + Copyright 2013, Vinnie Falco + + Permission to use, copy, modify, and/or distribute this software for any + purpose with or without fee is hereby granted, provided that the above + copyright notice and this permission notice appear in all copies. + + THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +*/ +//============================================================================== + +#include "abstract_socket.h" +#include "bind_handler.h" + +namespace beast { +namespace asio { + +#if ! BEAST_COMPILER_CHECKS_SOCKET_OVERRIDES + +//------------------------------------------------------------------------------ +// +// Socket +// +//------------------------------------------------------------------------------ + +void* abstract_socket::this_layer_ptr (char const*) const +{ + pure_virtual_called (); + return nullptr; +} + +//------------------------------------------------------------------------------ +// +// native_handle +// +//------------------------------------------------------------------------------ + +bool abstract_socket::native_handle (char const*, void*) +{ + pure_virtual_called (); + return false; +} + +//------------------------------------------------------------------------------ +// +// basic_io_object +// +//------------------------------------------------------------------------------ + +boost::asio::io_service& abstract_socket::get_io_service () +{ + pure_virtual_called (); + return *static_cast (nullptr); +} + +//------------------------------------------------------------------------------ +// +// basic_socket +// +//------------------------------------------------------------------------------ + +void* +abstract_socket::lowest_layer_ptr (char const*) const +{ + pure_virtual_called (); + return nullptr; +} + +auto +abstract_socket::cancel (boost::system::error_code& ec) -> error_code +{ + return pure_virtual_error (ec); +} + +auto +abstract_socket::shutdown (shutdown_type, boost::system::error_code& ec) -> error_code +{ + return pure_virtual_error (ec); +} + +auto +abstract_socket::close (boost::system::error_code& ec) -> error_code +{ + return pure_virtual_error (ec); +} + +//------------------------------------------------------------------------------ +// +// basic_socket_acceptor +// +//------------------------------------------------------------------------------ + +auto +abstract_socket::accept (abstract_socket&, error_code& ec) -> error_code +{ + return pure_virtual_error (ec); +} + +void +abstract_socket::async_accept (abstract_socket&, error_handler handler) +{ + get_io_service ().post (bind_handler ( + handler, pure_virtual_error())); +} + +//------------------------------------------------------------------------------ +// +// basic_stream_socket +// +//------------------------------------------------------------------------------ + +std::size_t +abstract_socket::read_some (mutable_buffers, error_code& ec) +{ + ec = pure_virtual_error (); + return 0; +} + +std::size_t +abstract_socket::write_some (const_buffers, error_code& ec) +{ + ec = pure_virtual_error (); + return 0; +} + +void +abstract_socket::async_read_some (mutable_buffers, transfer_handler handler) +{ + get_io_service ().post (bind_handler ( + handler, pure_virtual_error(), 0)); +} + +void +abstract_socket::async_write_some (const_buffers, transfer_handler handler) +{ + get_io_service ().post (bind_handler ( + handler, pure_virtual_error(), 0)); +} + +//------------------------------------------------------------------------------ +// +// ssl::stream +// +//------------------------------------------------------------------------------ + +void* +abstract_socket::next_layer_ptr (char const*) const +{ + pure_virtual_called (); + return nullptr; +} + +bool +abstract_socket::needs_handshake () +{ + return false; +} + +void +abstract_socket::set_verify_mode (int) +{ + pure_virtual_called (); +} + +auto +abstract_socket::handshake (handshake_type, error_code& ec) -> error_code +{ + return pure_virtual_error (ec); +} + +void +abstract_socket::async_handshake (handshake_type, error_handler handler) +{ + get_io_service ().post (bind_handler ( + handler, pure_virtual_error())); +} + +auto +abstract_socket::handshake (handshake_type, const_buffers, error_code& ec) -> + error_code +{ + return pure_virtual_error (ec); +} + +void +abstract_socket::async_handshake (handshake_type, const_buffers, + transfer_handler handler) +{ + get_io_service ().post (bind_handler ( + handler, pure_virtual_error(), 0)); +} + +auto +abstract_socket::shutdown (error_code& ec) -> error_code +{ + return pure_virtual_error (ec); +} + +void +abstract_socket::async_shutdown (error_handler handler) +{ + get_io_service ().post (bind_handler ( + handler, pure_virtual_error())); +} + +#endif + +} +} diff --git a/src/beast/modules/beast_asio/sockets/Socket.h b/src/beast/beast/asio/abstract_socket.h similarity index 54% rename from src/beast/modules/beast_asio/sockets/Socket.h rename to src/beast/beast/asio/abstract_socket.h index 963563e31ff..9900e184d2e 100644 --- a/src/beast/modules/beast_asio/sockets/Socket.h +++ b/src/beast/beast/asio/abstract_socket.h @@ -17,8 +17,28 @@ */ //============================================================================== -#ifndef BEAST_ASIO_SOCKETS_SOCKET_H_INCLUDED -#define BEAST_ASIO_SOCKETS_SOCKET_H_INCLUDED +#ifndef BEAST_ASIO_ABSTRACT_SOCKET_H_INCLUDED +#define BEAST_ASIO_ABSTRACT_SOCKET_H_INCLUDED + +#include "buffer_sequence.h" +#include "shared_handler.h" + +#include +#include + +// Checking overrides replaces unimplemented stubs with pure virtuals +#ifndef BEAST_COMPILER_CHECKS_SOCKET_OVERRIDES +# define BEAST_COMPILER_CHECKS_SOCKET_OVERRIDES 1 +#endif + +#if BEAST_COMPILER_CHECKS_SOCKET_OVERRIDES +# define BEAST_SOCKET_VIRTUAL = 0 +#else +# define BEAST_SOCKET_VIRTUAL +#endif + +namespace beast { +namespace asio { /** A high level socket abstraction. @@ -29,18 +49,61 @@ When member functions are called and the underlying implementation does not support the operation, a fatal error is generated. */ -class Socket - : public SocketBase - , public boost::asio::ssl::stream_base +class abstract_socket + : public boost::asio::ssl::stream_base , public boost::asio::socket_base { +protected: + typedef boost::system::error_code error_code; + + typedef asio::shared_handler post_handler; + + typedef asio::shared_handler error_handler; + + typedef asio::shared_handler < + void (error_code, std::size_t)> transfer_handler; + + static + void + pure_virtual_called() + { + throw std::runtime_error ("pure virtual called"); + } + + static + error_code + pure_virtual_error () + { + pure_virtual_called(); + return boost::system::errc::make_error_code ( + boost::system::errc::function_not_supported); + } + + static + error_code + pure_virtual_error (error_code& ec) + { + return ec = pure_virtual_error(); + } + + static + void + throw_if (error_code const& ec) + { + if (ec) + throw boost::system::system_error (ec); + } + public: - virtual ~Socket (); + virtual ~abstract_socket () + { + } //-------------------------------------------------------------------------- // - // Socket + // abstract_socket // + //-------------------------------------------------------------------------- /** Retrieve the underlying object. @@ -48,32 +111,32 @@ class Socket exception is thrown if trying to acquire a reference. */ /** @{ */ - template + template Object& this_layer () { Object* object (this->this_layer_ptr ()); if (object == nullptr) - Throw (std::bad_cast (), __FILE__, __LINE__); + throw std::bad_cast (); return *object; } - template + template Object const& this_layer () const { Object const* object (this->this_layer_ptr ()); if (object == nullptr) - Throw (std::bad_cast (), __FILE__, __LINE__); + throw std::bad_cast (); return *object; } - template + template Object* this_layer_ptr () { return static_cast ( this->this_layer_ptr (typeid (Object).name ())); } - template + template Object const* this_layer_ptr () const { return static_cast ( @@ -88,6 +151,7 @@ class Socket // // native_handle // + //-------------------------------------------------------------------------- /** Retrieve the native representation of the object. @@ -101,7 +165,7 @@ class Socket void native_handle (Handle* dest) { if (! native_handle (typeid (Handle).name (), dest)) - Throw (std::bad_cast (), __FILE__, __LINE__); + throw std::bad_cast (); } virtual bool native_handle (char const* type_name, void* dest) @@ -111,6 +175,7 @@ class Socket // // basic_io_object // + //-------------------------------------------------------------------------- virtual boost::asio::io_service& get_io_service () BEAST_SOCKET_VIRTUAL; @@ -119,6 +184,7 @@ class Socket // // basic_socket // + //-------------------------------------------------------------------------- /** Retrieve the lowest layer object. @@ -126,32 +192,32 @@ class Socket exception is thrown if trying to acquire a reference. */ /** @{ */ - template + template Object& lowest_layer () { Object* object (this->lowest_layer_ptr ()); if (object == nullptr) - Throw (std::bad_cast (), __FILE__, __LINE__); + throw std::bad_cast (); return *object; } - template + template Object const& lowest_layer () const { Object const* object (this->lowest_layer_ptr ()); if (object == nullptr) - Throw (std::bad_cast (), __FILE__, __LINE__); + throw std::bad_cast (); return *object; } - template + template Object* lowest_layer_ptr () { return static_cast ( this->lowest_layer_ptr (typeid (Object).name ())); } - template + template Object const* lowest_layer_ptr () const { return static_cast ( @@ -167,7 +233,8 @@ class Socket void cancel () { error_code ec; - throw_error (cancel (ec), __FILE__, __LINE__); + cancel (ec); + throw_if (ec); } virtual error_code cancel (error_code& ec) @@ -176,7 +243,8 @@ class Socket void shutdown (shutdown_type what) { error_code ec; - throw_error (shutdown (what, ec), __FILE__, __LINE__); + shutdown (what, ec); + throw_if (ec); } virtual error_code shutdown (shutdown_type what, @@ -186,7 +254,8 @@ class Socket void close () { error_code ec; - throw_error (close (ec), __FILE__, __LINE__); + close (ec); + throw_if (ec); } virtual error_code close (error_code& ec) @@ -196,82 +265,39 @@ class Socket // // basic_socket_acceptor // + //-------------------------------------------------------------------------- - virtual error_code accept (Socket& peer, error_code& ec) + virtual error_code accept (abstract_socket& peer, error_code& ec) BEAST_SOCKET_VIRTUAL; - template - void async_accept (Socket& peer, BOOST_ASIO_MOVE_ARG(AcceptHandler) handler) - { - return async_accept (peer, - newAcceptHandler (BOOST_ASIO_MOVE_CAST(AcceptHandler)(handler))); - } - - virtual void async_accept (Socket& peer, SharedHandlerPtr handler) + virtual void async_accept (abstract_socket& peer, error_handler handler) BEAST_SOCKET_VIRTUAL; //-------------------------------------------------------------------------- // // basic_stream_socket // + //-------------------------------------------------------------------------- - // SyncReadStream - // http://www.boost.org/doc/libs/1_54_0/doc/html/boost_asio/reference/SyncReadStream.html - // - template - std::size_t read_some (MutableBufferSequence const& buffers, - error_code& ec) - { - return read_some (MutableBuffers (buffers), ec); - } - - virtual std::size_t read_some (MutableBuffers const& buffers, error_code& ec) + virtual std::size_t read_some (mutable_buffers buffers, error_code& ec) BEAST_SOCKET_VIRTUAL; - // SyncWriteStream - // http://www.boost.org/doc/libs/1_54_0/doc/html/boost_asio/reference/SyncWriteStream.html - // - template - std::size_t write_some (ConstBufferSequence const& buffers, error_code &ec) - { - return write_some (ConstBuffers (buffers), ec); - } - - virtual std::size_t write_some (ConstBuffers const& buffers, error_code& ec) + virtual std::size_t write_some (const_buffers buffers, error_code& ec) BEAST_SOCKET_VIRTUAL; - // AsyncReadStream - // http://www.boost.org/doc/libs/1_54_0/doc/html/boost_asio/reference/AsyncReadStream.html - // - template - void async_read_some (MutableBufferSequence const& buffers, - BOOST_ASIO_MOVE_ARG(ReadHandler) handler) - { - return async_read_some (MutableBuffers (buffers), - newReadHandler (BOOST_ASIO_MOVE_CAST(ReadHandler)(handler))); - } - - virtual void async_read_some (MutableBuffers const& buffers, SharedHandlerPtr handler) + virtual void async_read_some (mutable_buffers buffers, + transfer_handler handler) BEAST_SOCKET_VIRTUAL; - // AsyncWriteStream - // http://www.boost.org/doc/libs/1_54_0/doc/html/boost_asio/reference/AsyncWriteStream.html - // - template - void async_write_some (ConstBufferSequence const& buffers, - BOOST_ASIO_MOVE_ARG(WriteHandler) handler) - { - return async_write_some (ConstBuffers (buffers), - newWriteHandler (BOOST_ASIO_MOVE_CAST(WriteHandler)(handler))); - } - - virtual void async_write_some (ConstBuffers const& buffers, SharedHandlerPtr handler) + virtual void async_write_some (const_buffers buffers, + transfer_handler handler) BEAST_SOCKET_VIRTUAL; //-------------------------------------------------------------------------- // // ssl::stream // + //-------------------------------------------------------------------------- /** Retrieve the next layer object. @@ -279,32 +305,32 @@ class Socket exception is thrown if trying to acquire a reference. */ /** @{ */ - template + template Object& next_layer () { Object* object (this->next_layer_ptr ()); if (object == nullptr) - Throw (std::bad_cast (), __FILE__, __LINE__); + throw std::bad_cast (); return *object; } - template + template Object const& next_layer () const { Object const* object (this->next_layer_ptr ()); if (object == nullptr) - Throw (std::bad_cast (), __FILE__, __LINE__); + throw std::bad_cast (); return *object; } - template + template Object* next_layer_ptr () { return static_cast ( this->next_layer_ptr (typeid (Object).name ())); } - template + template Object const* next_layer_ptr () const { return static_cast ( @@ -330,107 +356,49 @@ class Socket virtual bool needs_handshake () BEAST_SOCKET_VIRTUAL; - // http://www.boost.org/doc/libs/1_54_0/doc/html/boost_asio/reference/ssl__verify_mode.html - // - virtual void set_verify_mode (int verify_mode) = 0; + virtual void set_verify_mode (int verify_mode) + BEAST_SOCKET_VIRTUAL; - // ssl::stream::handshake (1 of 4) - // http://www.boost.org/doc/libs/1_54_0/doc/html/boost_asio/reference/ssl__stream/handshake/overload1.html - // void handshake (handshake_type type) { error_code ec; - throw_error (handshake (type, ec), __FILE__, __LINE__); + handshake (type, ec); + throw_if (ec); } - // ssl::stream::handshake (2 of 4) - // http://www.boost.org/doc/libs/1_54_0/doc/html/boost_asio/reference/ssl__stream/handshake/overload2.html - // virtual error_code handshake (handshake_type type, error_code& ec) BEAST_SOCKET_VIRTUAL; - // ssl::stream::async_handshake (1 of 2) - // http://www.boost.org/doc/libs/1_54_0/doc/html/boost_asio/reference/ssl__stream/async_handshake/overload1.html - // - template - void async_handshake (handshake_type type, BOOST_ASIO_MOVE_ARG(HandshakeHandler) handler) - { - return async_handshake (type, - newHandshakeHandler (BOOST_ASIO_MOVE_CAST(HandshakeHandler)(handler))); - } - - virtual void async_handshake (handshake_type type, SharedHandlerPtr handler) + virtual void async_handshake (handshake_type type, error_handler handler) BEAST_SOCKET_VIRTUAL; //-------------------------------------------------------------------------- -#if BEAST_ASIO_HAS_BUFFEREDHANDSHAKE - // ssl::stream::handshake (3 of 4) - // http://www.boost.org/doc/libs/1_54_0/doc/html/boost_asio/reference/ssl__stream/handshake/overload3.html - // - template - void handshake (handshake_type type, ConstBufferSequence const& buffers) - { - error_code ec; - throw_error (handshake (type, buffers, ec), __FILE__, __LINE__); - } - - // ssl::stream::handshake (4 of 4) - // http://www.boost.org/doc/libs/1_54_0/doc/html/boost_asio/reference/ssl__stream/handshake/overload4.html - // - template - error_code handshake (handshake_type type, - ConstBufferSequence const& buffers, error_code& ec) - { - return handshake (type, ConstBuffers (buffers), ec); - } - virtual error_code handshake (handshake_type type, - ConstBuffers const& buffers, error_code& ec) - BEAST_SOCKET_VIRTUAL; - - // ssl::stream::async_handshake (2 of 2) - // http://www.boost.org/doc/libs/1_54_0/doc/html/boost_asio/reference/ssl__stream/async_handshake/overload2.html - // - template - void async_handshake (handshake_type type, ConstBufferSequence const& buffers, - BOOST_ASIO_MOVE_ARG(BufferedHandshakeHandler) handler) - { - return async_handshake (type, ConstBuffers (buffers), - newBufferedHandshakeHandler (BOOST_ASIO_MOVE_CAST(BufferedHandshakeHandler)(handler))); - } + const_buffers buffers, error_code& ec) + BEAST_SOCKET_VIRTUAL; - virtual void async_handshake (handshake_type type, ConstBuffers const& buffers, - SharedHandlerPtr handler) - BEAST_SOCKET_VIRTUAL; -#endif + virtual void async_handshake (handshake_type type, + const_buffers buffers, transfer_handler handler) + BEAST_SOCKET_VIRTUAL; //-------------------------------------------------------------------------- - // ssl::stream::shutdown - // http://www.boost.org/doc/libs/1_54_0/doc/html/boost_asio/reference/ssl__stream/shutdown.html - // void shutdown () { error_code ec; - throw_error (shutdown (ec), __FILE__, __LINE__); + shutdown (ec); + throw_if (ec); } virtual error_code shutdown (error_code& ec) BEAST_SOCKET_VIRTUAL; - // ssl::stream::async_shutdown - // http://www.boost.org/doc/libs/1_54_0/doc/html/boost_asio/reference/ssl__stream/async_shutdown.html - // - template - void async_shutdown (BOOST_ASIO_MOVE_ARG(ShutdownHandler) handler) - { - return async_shutdown ( - newShutdownHandler (BOOST_ASIO_MOVE_CAST(ShutdownHandler)(handler))); - } - - virtual void async_shutdown (SharedHandlerPtr handler) + virtual void async_shutdown (error_handler handler) BEAST_SOCKET_VIRTUAL; }; +} +} + #endif diff --git a/src/beast/beast/asio/bind_handler.h b/src/beast/beast/asio/bind_handler.h new file mode 100644 index 00000000000..d2ce51f1e2c --- /dev/null +++ b/src/beast/beast/asio/bind_handler.h @@ -0,0 +1,163 @@ +//------------------------------------------------------------------------------ +/* + This file is part of Beast: https://github.com/vinniefalco/Beast + Copyright 2013, Vinnie Falco + + Permission to use, copy, modify, and/or distribute this software for any + purpose with or without fee is hereby granted, provided that the above + copyright notice and this permission notice appear in all copies. + + THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +*/ +//============================================================================== + +#ifndef BEAST_ASIO_BIND_HANDLER_H_INCLUDED +#define BEAST_ASIO_BIND_HANDLER_H_INCLUDED + +#include +#include +#include + +#include +#include "../cxx14/type_traits.h" // +#include "../cxx14/utility.h" // + +namespace beast { +namespace asio { + +namespace detail { + +/** Nullary handler that calls Handler with bound arguments. + The rebound handler provides the same io_service execution + guarantees as the original handler. +*/ +template +class bound_handler +{ +private: + typedef std::tuple ...> args_type; + + std::decay_t m_handler; + args_type m_args; + + template + static void invoke (Handler& h, Tuple& args, + std::index_sequence ) + { + h (std::get (args)...); + } + +public: + typedef void result_type; + + bound_handler (DeducedHandler&& handler, Args&&... args) + : m_handler (std::forward (handler)) + , m_args (std::forward (args)...) + { + } + + void + operator() () + { + invoke (m_handler, m_args, + std::index_sequence_for ()); + } + + void + operator() () const + { + invoke (m_handler, m_args, + std::index_sequence_for ()); + } + + template + friend + void + asio_handler_invoke (Function& f, bound_handler* h) + { + boost_asio_handler_invoke_helpers:: + invoke (f, h->m_handler); + } + + template + friend + void + asio_handler_invoke (Function const& f, bound_handler* h) + { + boost_asio_handler_invoke_helpers:: + invoke (f, h->m_handler); + } + + friend + void* + asio_handler_allocate (std::size_t size, bound_handler* h) + { + return boost_asio_handler_alloc_helpers:: + allocate (size, h->m_handler); + } + + friend + void + asio_handler_deallocate (void* p, std::size_t size, bound_handler* h) + { + boost_asio_handler_alloc_helpers:: + deallocate (p, size, h->m_handler); + } + + friend + bool + asio_handler_is_continuation (bound_handler* h) + { + return boost_asio_handler_cont_helpers:: + is_continuation (h->m_handler); + } +}; + +} + +//------------------------------------------------------------------------------ + +/** Binds parameters to a handler to produce a nullary functor. + The returned handler provides the same io_service execution guarantees + as the original handler. This is designed to use as a replacement for + io_service::wrap, to ensure that the handler will not be invoked + immediately by the calling function. +*/ +template +detail::bound_handler +bind_handler (DeducedHandler&& handler, Args&&... args) +{ + return detail::bound_handler ( + std::forward (handler), + std::forward (args)...); +} + +} +} + +//------------------------------------------------------------------------------ + +namespace std { + +template +void bind (beast::asio::detail::bound_handler < + Handler, Args...>, ...) = delete; + +#if 0 +template +struct is_bind_expression < + beast::asio::detail::bound_handler +> : std::true_type +{ +}; +#endif + +} + +#endif diff --git a/src/beast/beast/asio/buffer_sequence.h b/src/beast/beast/asio/buffer_sequence.h new file mode 100644 index 00000000000..b392e1ed5f6 --- /dev/null +++ b/src/beast/beast/asio/buffer_sequence.h @@ -0,0 +1,110 @@ +//------------------------------------------------------------------------------ +/* + This file is part of Beast: https://github.com/vinniefalco/Beast + Copyright 2013, Vinnie Falco + + Permission to use, copy, modify, and/or distribute this software for any + purpose with or without fee is hereby granted, provided that the above + copyright notice and this permission notice appear in all copies. + + THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +*/ +//============================================================================== + +#ifndef BEAST_ASIO_BUFFER_SEQUENCE_H_INCLUDED +#define BEAST_ASIO_BUFFER_SEQUENCE_H_INCLUDED + +#include + +#include +#include +#include "../cxx14/type_traits.h" // +#include + +namespace beast { +namespace asio { + +template +class buffer_sequence +{ +private: + typedef std::vector sequence_type; + +public: + typedef Buffer value_type; + typedef typename sequence_type::const_iterator const_iterator; + +private: + sequence_type m_buffers; + + template + void assign (FwdIter first, FwdIter last) + { + m_buffers.clear(); + m_buffers.reserve (std::distance (first, last)); + for (;first != last; ++first) + m_buffers.push_back (*first); + } + +public: + buffer_sequence () + { + } + + template < + class BufferSequence, + class = std::enable_if_t ::value> + > + buffer_sequence (BufferSequence const& s) + { + assign (std::begin (s), std::end (s)); + } + + template < + class FwdIter, + class = std::enable_if_t ::value_type>::value> + > + buffer_sequence (FwdIter first, FwdIter last) + { + assign (first, last); + } + + template + std::enable_if_t ::value, + buffer_sequence& + > + operator= (BufferSequence const& s) + { + return assign (s); + } + + const_iterator + begin () const noexcept + { + return m_buffers.begin (); + } + + const_iterator + end () const noexcept + { + return m_buffers.end (); + } +}; + +typedef buffer_sequence const_buffers; +typedef buffer_sequence mutable_buffers; + +} +} + +#endif diff --git a/src/beast/modules/beast_asio/async/SharedHandler.cpp b/src/beast/beast/asio/placeholders.h similarity index 55% rename from src/beast/modules/beast_asio/async/SharedHandler.cpp rename to src/beast/beast/asio/placeholders.h index cf4cea5ca7d..03633b9f343 100644 --- a/src/beast/modules/beast_asio/async/SharedHandler.cpp +++ b/src/beast/beast/asio/placeholders.h @@ -17,31 +17,25 @@ */ //============================================================================== -void SharedHandler::operator() () -{ - pure_virtual_called (__FILE__, __LINE__); -} +#ifndef BEAST_ASIO_PLACEHOLDERS_H_INCLUDED +#define BEAST_ASIO_PLACEHOLDERS_H_INCLUDED -void SharedHandler::operator() (error_code const&) -{ - pure_virtual_called (__FILE__, __LINE__); -} +#include + +namespace beast { +namespace asio { -void SharedHandler::operator() (error_code const&, std::size_t) -{ - pure_virtual_called (__FILE__, __LINE__); +namespace placeholders { +// asio placeholders that work with std::bind +namespace { +static auto const error (std::placeholders::_1); +static auto const bytes_transferred (std::placeholders::_2); +static auto const iterator (std::placeholders::_2); +static auto const signal_number (std::placeholders::_2); +} } -void SharedHandler::pure_virtual_called (char const* fileName, int lineNumber) -{ - // These shouldn't be getting called. But since the object returned - // by most implementations of bind have operator() up to high arity - // levels, it is not generally possible to write a traits test that - // works in all scenarios for detecting a particular signature of a - // handler. - // - // We use Throw here so beast has a chance to dump the stack BEFORE - // the stack is unwound. - // - Throw (std::runtime_error ("pure virtual called"), fileName, lineNumber); } +} + +#endif diff --git a/src/beast/beast/asio/shared_handler.h b/src/beast/beast/asio/shared_handler.h new file mode 100644 index 00000000000..21a9c4aaf66 --- /dev/null +++ b/src/beast/beast/asio/shared_handler.h @@ -0,0 +1,472 @@ +//------------------------------------------------------------------------------ +/* + This file is part of Beast: https://github.com/vinniefalco/Beast + Copyright 2013, Vinnie Falco + + Permission to use, copy, modify, and/or distribute this software for any + purpose with or without fee is hereby granted, provided that the above + copyright notice and this permission notice appear in all copies. + + THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +*/ +//============================================================================== + +#ifndef BEAST_ASIO_SHARED_HANDLER_H_INCLUDED +#define BEAST_ASIO_SHARED_HANDLER_H_INCLUDED + +#include "../mpl/IsCallPossible.h" + +#include +#include +#include "../cxx14/type_traits.h" // + +#include + +#include +#include +#include + +#ifndef BEAST_ASIO_NO_ALLOCATE_SHARED +#define BEAST_ASIO_NO_ALLOCATE_SHARED 0 +#endif + +#ifndef BEAST_ASIO_NO_HANDLER_RESULT_OF +#define BEAST_ASIO_NO_HANDLER_RESULT_OF 1 +#endif + +namespace beast { +namespace asio { + +class shared_handler_wrapper_base +{ +public: + virtual ~shared_handler_wrapper_base() + { + } + + virtual void invoke (std::function f) = 0; + virtual void* allocate (std::size_t size) = 0; + virtual void deallocate (void* p, std::size_t size) = 0; + virtual bool is_continuation () = 0; +}; + +//------------------------------------------------------------------------------ + +template +class shared_handler_wrapper_func + : public shared_handler_wrapper_base +{ +private: + std::function m_func; + +public: + template + explicit shared_handler_wrapper_func (Handler&& handler) + : m_func (std::ref (std::forward (handler))) + { + } + + template +#if BEAST_ASIO_NO_HANDLER_RESULT_OF + void +#else + std::result_of_t (Args...)> +#endif + operator() (Args&&... args) const + { + return m_func (std::forward (args)...); + } +}; + +//------------------------------------------------------------------------------ + +namespace detail { + +#ifdef _MSC_VER +#pragma warning (push) +#pragma warning (disable: 4512) // assignment operator could not be generated +#endif + +template +class shared_handler_wrapper + : private boost::base_from_member + , public shared_handler_wrapper_func +{ +private: + typedef boost::base_from_member Base; + + BEAST_DEFINE_IS_CALL_POSSIBLE(has_is_continuation, is_continuation); + +public: + shared_handler_wrapper (Handler&& handler) + : boost::base_from_member (std::move (handler)) + , shared_handler_wrapper_func (Base::member) + { + } + + shared_handler_wrapper (Handler const& handler) + : boost::base_from_member (handler) + , shared_handler_wrapper_func (Base::member) + { + } + +private: + void + invoke (std::function f) override + { + return boost_asio_handler_invoke_helpers:: + invoke (f, Base::member); + } + + void* + allocate (std::size_t size) override + { + return boost_asio_handler_alloc_helpers:: + allocate (size, Base::member); + } + + void + deallocate (void* p, std::size_t size) override + { + boost_asio_handler_alloc_helpers:: + deallocate (p, size, Base::member); + } + + bool + is_continuation () override + { + return is_continuation (std::integral_constant ::value>()); + } + + bool + is_continuation (std::true_type) + { + return Base::member.is_continuation(); + } + + bool + is_continuation (std::false_type) + { + return boost_asio_handler_cont_helpers:: + is_continuation (Base::member); + } +}; + +#ifdef _MSC_VER +#pragma warning (pop) +#endif + +template +struct is_shared_handler : public std::false_type +{ +}; + +//------------------------------------------------------------------------------ + +template +class handler_allocator +{ +private: + // We want a partial template specialization as a friend + // but that isn't allowed so we friend all versions. This + // should produce a compile error if Handler is not constructible + // from H. + // + template + friend class handler_allocator; + + Handler m_handler; + +public: + typedef T value_type; + typedef T* pointer; + + template + struct rebind + { + public: + typedef handler_allocator other; + }; + + handler_allocator() = delete; + + handler_allocator (Handler const& handler) + : m_handler (handler) + { + } + + template + handler_allocator ( + handler_allocator const& other) + : m_handler (other.m_handler) + { + } + + handler_allocator& + operator= (handler_allocator const&) = delete; + + pointer + allocate (std::ptrdiff_t n) + { + auto const size (n * sizeof (T)); + return static_cast ( + boost_asio_handler_alloc_helpers::allocate ( + size, m_handler)); + } + + void + deallocate (pointer p, std::ptrdiff_t n) + { + auto const size (n * sizeof (T)); + boost_asio_handler_alloc_helpers::deallocate ( + p, size, m_handler); + } + + // Work-around for MSVC not using allocator_traits + // in the implementation of shared_ptr + // +#ifdef _MSC_VER + void + destroy (T* t) + { + t->~T(); + } +#endif + + friend + bool + operator== (handler_allocator const& lhs, handler_allocator const& rhs) + { + return true; + } + + friend + bool + operator!= (handler_allocator const& lhs, handler_allocator const& rhs) + { + return ! (lhs == rhs); + } +}; + +} + +//------------------------------------------------------------------------------ + +/** Handler shared reference that provides io_service execution guarantees. */ +template < + class Signature +> +class shared_handler +{ +private: + template + friend class shared_handler_allocator; + + typedef shared_handler_wrapper_func < + Signature> wrapper_type; + + typedef std::shared_ptr ptr_type; + + ptr_type m_ptr; + +public: + shared_handler() + { + } + + template < + class DeducedHandler, + class = std::enable_if_t < + ! detail::is_shared_handler < + std::decay_t >::value && + std::is_constructible , + std::decay_t >::value + > + > + shared_handler (DeducedHandler&& handler) + { + typedef std::remove_reference_t Handler; + + #if BEAST_ASIO_NO_ALLOCATE_SHARED + m_ptr = std::make_shared > (std::forward (handler)); + #else + m_ptr = std::allocate_shared > (detail::handler_allocator ( + handler), std::forward (handler)); + #endif + } + + shared_handler (shared_handler&& other) + : m_ptr (std::move (other.m_ptr)) + { + } + + shared_handler (shared_handler const& other) + : m_ptr (other.m_ptr) + { + } + + shared_handler& + operator= (std::nullptr_t) + { + m_ptr = nullptr; + } + + shared_handler& + operator= (shared_handler const& rhs) + { + m_ptr = rhs.m_ptr; + return *this; + } + + bool + empty() const + { + return ! m_ptr.operator bool(); + } + + operator bool() const + { + return !empty(); + } + + void + reset() + { + m_ptr.reset(); + } + + template +#if BEAST_ASIO_NO_HANDLER_RESULT_OF + void +#else + std::result_of_t (Args...)> +#endif + operator() (Args&&... args) const + { + return (*m_ptr)(std::forward (args)...); + } + + template + friend + void + asio_handler_invoke (Function&& f, shared_handler* h) + { + return h->m_ptr->invoke (f); + } + + friend + void* + asio_handler_allocate ( + std::size_t size, shared_handler* h) + { + return h->m_ptr->allocate (size); + } + + friend + void + asio_handler_deallocate ( + void* p, std::size_t size, shared_handler* h) + { + return h->m_ptr->deallocate (p, size); + } + + friend + bool + asio_handler_is_continuation ( + shared_handler* h) + { + return h->m_ptr->is_continuation (); + } +}; + +//------------------------------------------------------------------------------ + +namespace detail { + +template < + class Signature +> +struct is_shared_handler < + shared_handler +> : public std::true_type +{ +}; + +} + +//------------------------------------------------------------------------------ + +template +class shared_handler_allocator +{ +private: + template + friend class shared_handler_allocator; + + std::shared_ptr m_ptr; + +public: + typedef T value_type; + typedef T* pointer; + + shared_handler_allocator() = delete; + + template + shared_handler_allocator ( + shared_handler const& handler) + : m_ptr (handler.m_ptr) + { + } + + template + shared_handler_allocator ( + shared_handler_allocator const& other) + : m_ptr (other.m_ptr) + { + } + + pointer + allocate (std::ptrdiff_t n) + { + auto const size (n * sizeof (T)); + return static_cast ( + m_ptr->allocate (size)); + } + + void + deallocate (pointer p, std::ptrdiff_t n) + { + auto const size (n * sizeof (T)); + m_ptr->deallocate (p, size); + } + + friend + bool + operator== (shared_handler_allocator const& lhs, + shared_handler_allocator const& rhs) + { + return lhs.m_ptr == rhs.m_ptr; + } + + friend + bool + operator!= (shared_handler_allocator const& lhs, + shared_handler_allocator const& rhs) + { + return ! (lhs == rhs); + } +}; + +} +} + +#endif diff --git a/src/beast/modules/beast_asio/sockets/SocketWrapper.h b/src/beast/beast/asio/socket_wrapper.h similarity index 59% rename from src/beast/modules/beast_asio/sockets/SocketWrapper.h rename to src/beast/beast/asio/socket_wrapper.h index 7c80eff28ab..9182943c598 100644 --- a/src/beast/modules/beast_asio/sockets/SocketWrapper.h +++ b/src/beast/beast/asio/socket_wrapper.h @@ -17,8 +17,14 @@ */ //============================================================================== -#ifndef BEAST_ASIO_SOCKETS_SOCKETWRAPPER_H_INCLUDED -#define BEAST_ASIO_SOCKETS_SOCKETWRAPPER_H_INCLUDED +#ifndef BEAST_ASIO_SOCKET_WRAPPER_H_INCLUDED +#define BEAST_ASIO_SOCKET_WRAPPER_H_INCLUDED + +#include "abstract_socket.h" +#include "bind_handler.h" + +namespace beast { +namespace asio { /** Wraps a reference to any object and exports all availble interfaces. @@ -35,7 +41,7 @@ asio::ssl::stream asio::ssl::stream explain arg must be an io_context - explain SocketWrapper will create and take ownership of the tcp::socket + explain socket_wrapper will create and take ownership of the tcp::socket explain this_layer_type will be tcp::socket explain next_layer () returns a asio::ip::tcp::socket& explain lowest_layer () returns a asio::ip::tcp::socket& @@ -43,112 +49,27 @@ asio::ssl::stream > > This makes my head explode */ - -//------------------------------------------------------------------------------ - -namespace detail -{ - -namespace SocketWrapperMemberChecks -{ - BEAST_DEFINE_IS_CALL_POSSIBLE(has_get_io_service, get_io_service); - - BEAST_DEFINE_IS_CALL_POSSIBLE(has_lowest_layer, lowest_layer); - BEAST_DEFINE_IS_CALL_POSSIBLE(has_cancel, cancel); - BEAST_DEFINE_IS_CALL_POSSIBLE(has_shutdown, shutdown); - BEAST_DEFINE_IS_CALL_POSSIBLE(has_close, close); - - BEAST_DEFINE_IS_CALL_POSSIBLE(has_accept, accept); - BEAST_DEFINE_IS_CALL_POSSIBLE(has_async_accept, async_accept); - - BEAST_DEFINE_IS_CALL_POSSIBLE(has_read_some, read_some); - BEAST_DEFINE_IS_CALL_POSSIBLE(has_write_some, write_some); - BEAST_DEFINE_IS_CALL_POSSIBLE(has_async_read_some, async_read_some); - BEAST_DEFINE_IS_CALL_POSSIBLE(has_async_write_some, async_write_some); - - BEAST_DEFINE_IS_CALL_POSSIBLE(has_set_verify_mode, set_verify_mode); - BEAST_DEFINE_IS_CALL_POSSIBLE(has_handshake, handshake); - BEAST_DEFINE_IS_CALL_POSSIBLE(has_async_handshake, async_handshake); - BEAST_DEFINE_IS_CALL_POSSIBLE(has_async_shutdown, async_shutdown); - - // Extracts the underlying socket type from the protocol of another asio object - template - struct native_socket - { - typedef void* socket_type; - inline native_socket (Socket&) - : m_socket (nullptr) - { - SocketBase::pure_virtual_called (__FILE__, __LINE__); - } - inline socket_type& get () - { - SocketBase::pure_virtual_called (__FILE__, __LINE__); - return m_socket; - } - inline socket_type& operator-> () - { - return get (); - } - private: - socket_type m_socket; - }; - - // Enabled if T::protocol_type::socket exists as a type - template - struct native_socket >::type> - { - typedef typename T::protocol_type::socket socket_type; - inline native_socket (Socket& peer) - : m_socket_ptr (&peer.this_layer ()) - { - } - inline socket_type& get () noexcept - { - return *m_socket_ptr; - } - inline socket_type& operator-> () noexcept - { - return get (); - } - private: - socket_type* m_socket_ptr; - }; -} - -} - -//------------------------------------------------------------------------------ - template -class SocketWrapper - : public Socket - , public Uncopyable +class socket_wrapper : public abstract_socket { -public: - // Converts a static bool constexpr member named 'value' into - // an IntegralConstant for SFINAE overload resolution. - // - template - struct Enabled : public IntegralConstant { }; +private: + Object m_object; - template - explicit SocketWrapper (Arg& arg) - : m_object (arg) +public: + template + explicit socket_wrapper (Args&&... args) + : m_object (std::forward (args)...) { } - template - SocketWrapper (Arg1& arg1, Arg2& arg2) - : m_object (arg1, arg2) - { - } + socket_wrapper (socket_wrapper const&) = delete; + socket_wrapper& operator= (socket_wrapper const&) = delete; //-------------------------------------------------------------------------- // - // SocketWrapper + // socket_wrapper // + //-------------------------------------------------------------------------- /** The type of the object being wrapped. */ typedef typename boost::remove_reference ::type this_layer_type; @@ -167,10 +88,11 @@ class SocketWrapper //-------------------------------------------------------------------------- // - // Socket + // abstract_socket // + //-------------------------------------------------------------------------- - void* this_layer_ptr (char const* type_name) const + void* this_layer_ptr (char const* type_name) const override { char const* const name (typeid (this_layer_type).name ()); if (strcmp (name, type_name) == 0) @@ -178,10 +100,43 @@ class SocketWrapper return nullptr; } +private: + BEAST_DEFINE_IS_CALL_POSSIBLE(has_get_io_service, get_io_service); + + BEAST_DEFINE_IS_CALL_POSSIBLE(has_lowest_layer, lowest_layer); + BEAST_DEFINE_IS_CALL_POSSIBLE(has_cancel, cancel); + BEAST_DEFINE_IS_CALL_POSSIBLE(has_shutdown, shutdown); + BEAST_DEFINE_IS_CALL_POSSIBLE(has_close, close); + + BEAST_DEFINE_IS_CALL_POSSIBLE(has_accept, accept); + BEAST_DEFINE_IS_CALL_POSSIBLE(has_async_accept, async_accept); + + BEAST_DEFINE_IS_CALL_POSSIBLE(has_read_some, read_some); + BEAST_DEFINE_IS_CALL_POSSIBLE(has_write_some, write_some); + BEAST_DEFINE_IS_CALL_POSSIBLE(has_async_read_some, async_read_some); + BEAST_DEFINE_IS_CALL_POSSIBLE(has_async_write_some, async_write_some); + + BEAST_DEFINE_IS_CALL_POSSIBLE(has_set_verify_mode, set_verify_mode); + BEAST_DEFINE_IS_CALL_POSSIBLE(has_handshake, handshake); + BEAST_DEFINE_IS_CALL_POSSIBLE(has_async_handshake, async_handshake); + BEAST_DEFINE_IS_CALL_POSSIBLE(has_async_shutdown, async_shutdown); + + //-------------------------------------------------------------------------- + // + // Implementation + // + //-------------------------------------------------------------------------- + + template + struct Enabled : public std::integral_constant + { + }; + //-------------------------------------------------------------------------- // // native_handle // + //-------------------------------------------------------------------------- #if 0 // This is a potential work-around for the problem with @@ -203,17 +158,20 @@ class SocketWrapper typedef struct {char dummy[2];} no; template static yes f(typename C::native_handle_type*); template static no f(...); -#ifdef _MSC_VER + #ifdef _MSC_VER static bool const value = sizeof(f(0)) == 1; -#else + #else // This line fails to compile under Visual Studio 2012 - static bool const value = sizeof(has_type_native_handle_type::f(0)) == 1; -#endif + static bool const value = sizeof( + has_type_native_handle_type::f(0)) == 1; + #endif }; #endif - template ::value > + template ::value + > struct extract_native_handle_type { typedef typename T::native_handle_type type; @@ -226,22 +184,26 @@ class SocketWrapper }; // This will be void if native_handle_type doesn't exist in Object - typedef typename extract_native_handle_type ::type native_handle_type; + typedef typename extract_native_handle_type < + this_layer_type>::type native_handle_type; + + //-------------------------------------------------------------------------- - bool native_handle (char const* type_name, void* dest) + bool native_handle (char const* type_name, void* dest) override { - using namespace detail::SocketWrapperMemberChecks; return native_handle (type_name, dest, Enabled > ()); } bool native_handle (char const* type_name, void* dest, - TrueType) + std::true_type) { - char const* const name (typeid (typename this_layer_type::native_handle_type).name ()); + char const* const name (typeid ( + typename this_layer_type::native_handle_type).name ()); if (strcmp (name, type_name) == 0) { - native_handle_type* const p (reinterpret_cast (dest)); + native_handle_type* const p (reinterpret_cast < + native_handle_type*> (dest)); *p = m_object.native_handle (); return true; } @@ -249,9 +211,9 @@ class SocketWrapper } bool native_handle (char const*, void*, - FalseType) + std::false_type) { - pure_virtual_called (__FILE__, __LINE__); + pure_virtual_called(); return false; } @@ -259,30 +221,30 @@ class SocketWrapper // // basic_io_object // + //-------------------------------------------------------------------------- - boost::asio::io_service& get_io_service () + boost::asio::io_service& get_io_service () override { #if 0 // Apparently has_get_io_service always results in false - using namespace detail::SocketWrapperMemberChecks; return get_io_service ( Enabled > ()); #else - return get_io_service (TrueType ()); + return get_io_service (std::true_type ()); #endif } boost::asio::io_service& get_io_service ( - TrueType) + std::true_type) { return m_object.get_io_service (); } boost::asio::io_service& get_io_service ( - FalseType) + std::false_type) { - pure_virtual_called (__FILE__, __LINE__); + pure_virtual_called(); return *static_cast (nullptr); } @@ -290,6 +252,7 @@ class SocketWrapper // // basic_socket // + //-------------------------------------------------------------------------- /* To forward the lowest_layer_type type, we need to make sure it @@ -330,15 +293,16 @@ class SocketWrapper // This will be void if lowest_layer_type doesn't exist in Object typedef typename extract_lowest_layer_type ::type lowest_layer_type; - void* lowest_layer_ptr (char const* type_name) const + //-------------------------------------------------------------------------- + + void* lowest_layer_ptr (char const* type_name) const override { - using namespace detail::SocketWrapperMemberChecks; return lowest_layer_ptr (type_name, Enabled > ()); } void* lowest_layer_ptr (char const* type_name, - TrueType) const + std::true_type) const { char const* const name (typeid (typename this_layer_type::lowest_layer_type).name ()); if (strcmp (name, type_name) == 0) @@ -347,39 +311,37 @@ class SocketWrapper } void* lowest_layer_ptr (char const*, - FalseType) const + std::false_type) const { - pure_virtual_called (__FILE__, __LINE__); + pure_virtual_called(); return nullptr; } //-------------------------------------------------------------------------- - error_code cancel (error_code& ec) + error_code cancel (error_code& ec) override { - using namespace detail::SocketWrapperMemberChecks; return cancel (ec, Enabled > ()); } error_code cancel (error_code& ec, - TrueType) + std::true_type) { return m_object.cancel (ec); } error_code cancel (error_code& ec, - FalseType) + std::false_type) { - return pure_virtual_error (ec, __FILE__, __LINE__); + return pure_virtual_error (ec); } //-------------------------------------------------------------------------- - error_code shutdown (shutdown_type what, error_code& ec) + error_code shutdown (shutdown_type what, error_code& ec) override { - using namespace detail::SocketWrapperMemberChecks; return shutdown (what, ec, Enabled > ()); @@ -387,208 +349,249 @@ class SocketWrapper error_code shutdown (shutdown_type what, error_code& ec, - TrueType) + std::true_type) { return m_object.shutdown (what, ec); } error_code shutdown (shutdown_type, error_code& ec, - FalseType) + std::false_type) { - return pure_virtual_error (ec, __FILE__, __LINE__); + return pure_virtual_error (ec); } //-------------------------------------------------------------------------- - error_code close (error_code& ec) + error_code close (error_code& ec) override { - using namespace detail::SocketWrapperMemberChecks; return close (ec, Enabled > ()); } error_code close (error_code& ec, - TrueType) + std::true_type) { return m_object.close (ec); } error_code close (error_code& ec, - FalseType) + std::false_type) { - return pure_virtual_error (ec, __FILE__, __LINE__); + return pure_virtual_error (ec); } //-------------------------------------------------------------------------- // // basic_socket_acceptor // + //-------------------------------------------------------------------------- - error_code accept (Socket& peer, error_code& ec) + // Extracts the underlying socket type from the protocol of another asio object + template + struct native_socket + { + typedef void* socket_type; + inline native_socket (abstract_socket&) + : m_socket (nullptr) + { + abstract_socket::pure_virtual_called(); + } + inline socket_type& get () + { + abstract_socket::pure_virtual_called(); + return m_socket; + } + inline socket_type& operator-> () + { + return get (); + } + private: + socket_type m_socket; + }; + + // Enabled if T::protocol_type::socket exists as a type + template + struct native_socket >::type> + { + typedef typename T::protocol_type::socket socket_type; + inline native_socket (abstract_socket& peer) + : m_socket_ptr (&peer.this_layer ()) + { + } + inline socket_type& get () noexcept + { + return *m_socket_ptr; + } + inline socket_type& operator-> () noexcept + { + return get (); + } + private: + socket_type* m_socket_ptr; + }; + + //-------------------------------------------------------------------------- + + error_code accept (abstract_socket& peer, error_code& ec) override { - using namespace detail::SocketWrapperMemberChecks; typedef typename native_socket ::socket_type socket_type; return accept (peer, ec, Enabled > ()); } - error_code accept (Socket& peer, error_code& ec, - TrueType) + error_code accept (abstract_socket& peer, error_code& ec, + std::true_type) { - using namespace detail::SocketWrapperMemberChecks; return m_object.accept ( native_socket (peer).get (), ec); } - error_code accept (Socket&, error_code& ec, - FalseType) + error_code accept (abstract_socket&, error_code& ec, + std::false_type) { - return pure_virtual_error (ec, __FILE__, __LINE__); + return pure_virtual_error (ec); } //-------------------------------------------------------------------------- - void async_accept (Socket& peer, SharedHandlerPtr handler) + void async_accept (abstract_socket& peer, error_handler handler) override { - using namespace detail::SocketWrapperMemberChecks; typedef typename native_socket ::socket_type socket_type; - async_accept (peer, BOOST_ASIO_MOVE_CAST(SharedHandlerPtr)(handler), + async_accept (peer, handler, Enabled > ()); + void (socket_type&, error_handler)> > ()); } - void async_accept (Socket& peer, BOOST_ASIO_MOVE_ARG(SharedHandlerPtr) handler, - TrueType) + void async_accept (abstract_socket& peer, error_handler const& handler, + std::true_type) { - using namespace detail::SocketWrapperMemberChecks; m_object.async_accept ( - native_socket (peer).get (), - BOOST_ASIO_MOVE_CAST(SharedHandlerPtr)(handler)); + native_socket (peer).get (), handler); } - void async_accept (Socket&, BOOST_ASIO_MOVE_ARG(SharedHandlerPtr) handler, - FalseType) + void async_accept (abstract_socket&, error_handler const& handler, + std::false_type) { - get_io_service ().wrap ( - BOOST_ASIO_MOVE_CAST(SharedHandlerPtr)(handler)) - (pure_virtual_error ()); + get_io_service ().post (bind_handler ( + handler, pure_virtual_error())); } //-------------------------------------------------------------------------- // // basic_stream_socket // + //-------------------------------------------------------------------------- - std::size_t read_some (MutableBuffers const& buffers, error_code& ec) + std::size_t + read_some (mutable_buffers buffers, error_code& ec) override { - using namespace detail::SocketWrapperMemberChecks; return read_some (buffers, ec, Enabled > ()); + std::size_t (mutable_buffers const&, error_code&)> > ()); } - template - std::size_t read_some (MutableBufferSequence const& buffers, error_code& ec, - TrueType) + std::size_t + read_some (mutable_buffers const& buffers, error_code& ec, + std::true_type) { return m_object.read_some (buffers, ec); } - template - std::size_t read_some (MutableBufferSequence const&, error_code& ec, - FalseType) + std::size_t read_some (mutable_buffers const&, error_code& ec, + std::false_type) { - pure_virtual_called (__FILE__, __LINE__); ec = pure_virtual_error (); return 0; } //-------------------------------------------------------------------------- - std::size_t write_some (ConstBuffers const& buffers, error_code& ec) + std::size_t + write_some (const_buffers buffers, error_code& ec) override { - using namespace detail::SocketWrapperMemberChecks; return write_some (buffers, ec, Enabled > ()); + std::size_t (const_buffers const&, error_code&)> > ()); } - template - std::size_t write_some (ConstBufferSequence const& buffers, error_code& ec, - TrueType) + std::size_t + write_some (const_buffers const& buffers, error_code& ec, + std::true_type) { return m_object.write_some (buffers, ec); } - template - std::size_t write_some (ConstBufferSequence const&, error_code& ec, - FalseType) + std::size_t + write_some (const_buffers const&, error_code& ec, + std::false_type) { - pure_virtual_called (__FILE__, __LINE__); ec = pure_virtual_error (); return 0; } //-------------------------------------------------------------------------- - void async_read_some (MutableBuffers const& buffers, SharedHandlerPtr handler) + void async_read_some (mutable_buffers buffers, + transfer_handler handler) override { - using namespace detail::SocketWrapperMemberChecks; - async_read_some (buffers, BOOST_ASIO_MOVE_CAST(SharedHandlerPtr)(handler), + async_read_some (buffers, handler, Enabled > ()); + void (mutable_buffers const&, transfer_handler const&)> > ()); } - void async_read_some (MutableBuffers const& buffers, - BOOST_ASIO_MOVE_ARG(SharedHandlerPtr) handler, - TrueType) + void + async_read_some (mutable_buffers const& buffers, + transfer_handler const& handler, + std::true_type) { - m_object.async_read_some (buffers, - BOOST_ASIO_MOVE_CAST(SharedHandlerPtr)(handler)); + m_object.async_read_some (buffers, handler); } - void async_read_some (MutableBuffers const&, - BOOST_ASIO_MOVE_ARG(SharedHandlerPtr) handler, - FalseType) + void + async_read_some (mutable_buffers const&, + transfer_handler const& handler, + std::false_type) { - get_io_service ().wrap ( - BOOST_ASIO_MOVE_CAST(SharedHandlerPtr)(handler)) - (pure_virtual_error (), 0); + get_io_service ().post (bind_handler ( + handler, pure_virtual_error(), 0)); } //-------------------------------------------------------------------------- - void async_write_some (ConstBuffers const& buffers, SharedHandlerPtr handler) + void + async_write_some (const_buffers buffers, + transfer_handler handler) override { - using namespace detail::SocketWrapperMemberChecks; - async_write_some (buffers, BOOST_ASIO_MOVE_CAST(SharedHandlerPtr)(handler), + async_write_some (buffers, handler, Enabled > ()); + void (const_buffers const&, transfer_handler const&)> > ()); } - void async_write_some (ConstBuffers const& buffers, - BOOST_ASIO_MOVE_ARG(SharedHandlerPtr) handler, - TrueType) + void + async_write_some (const_buffers const& buffers, + transfer_handler const& handler, + std::true_type) { - m_object.async_write_some (buffers, - BOOST_ASIO_MOVE_CAST(SharedHandlerPtr)(handler)); + m_object.async_write_some (buffers, handler); } - void async_write_some (ConstBuffers const&, - BOOST_ASIO_MOVE_ARG(SharedHandlerPtr) handler, - FalseType) + void + async_write_some (const_buffers const&, + transfer_handler const& handler, + std::false_type) { - get_io_service ().wrap ( - BOOST_ASIO_MOVE_CAST(SharedHandlerPtr)(handler)) - (pure_virtual_error (), 0); + get_io_service ().post (bind_handler ( + handler, pure_virtual_error(), 0)); } //-------------------------------------------------------------------------- // // ssl::stream // + //-------------------------------------------------------------------------- template struct has_type_next_layer_type @@ -597,12 +600,12 @@ class SocketWrapper typedef struct {char dummy[2];} no; template static yes f(typename C::next_layer_type*); template static no f(...); -#ifdef _MSC_VER + #ifdef _MSC_VER static bool const value = sizeof(f(0)) == 1; -#else + #else // This line fails to compile under Visual Studio 2012 static bool const value = sizeof(has_type_next_layer_type::f(0)) == 1; -#endif + #endif }; template ::value > @@ -620,15 +623,16 @@ class SocketWrapper // This will be void if next_layer_type doesn't exist in Object typedef typename extract_next_layer_type ::type next_layer_type; - void* next_layer_ptr (char const* type_name) const + //-------------------------------------------------------------------------- + + void* next_layer_ptr (char const* type_name) const override { - using namespace detail::SocketWrapperMemberChecks; return next_layer_ptr (type_name, Enabled > ()); } void* next_layer_ptr (char const* type_name, - TrueType) const + std::true_type) const { char const* const name (typeid (typename this_layer_type::next_layer_type).name ()); if (strcmp (name, type_name) == 0) @@ -637,29 +641,27 @@ class SocketWrapper } void* next_layer_ptr (char const*, - FalseType) const + std::false_type) const { - pure_virtual_called (__FILE__, __LINE__); + pure_virtual_called(); return nullptr; } //-------------------------------------------------------------------------- - bool needs_handshake () + bool needs_handshake () override { - using namespace detail::SocketWrapperMemberChecks; return has_handshake ::value || has_async_handshake ::value; + void (handshake_type, error_handler)>::value; } //-------------------------------------------------------------------------- - void set_verify_mode (int verify_mode) + void set_verify_mode (int verify_mode) override { - using namespace detail::SocketWrapperMemberChecks; set_verify_mode (verify_mode, Enabled > ()); @@ -667,172 +669,161 @@ class SocketWrapper } void set_verify_mode (int verify_mode, - TrueType) + std::true_type) { m_object.set_verify_mode (verify_mode); } void set_verify_mode (int, - FalseType) + std::false_type) { - pure_virtual_called (__FILE__, __LINE__); + pure_virtual_called(); } //-------------------------------------------------------------------------- - error_code handshake (handshake_type type, error_code& ec) + error_code + handshake (handshake_type type, error_code& ec) override { - using namespace detail::SocketWrapperMemberChecks; return handshake (type, ec, Enabled > ()); } - error_code handshake (handshake_type type, error_code& ec, - TrueType) + error_code + handshake (handshake_type type, error_code& ec, + std::true_type) { return m_object.handshake (type, ec); } - error_code handshake (handshake_type, error_code& ec, - FalseType) + error_code + handshake (handshake_type, error_code& ec, + std::false_type) { - return pure_virtual_error (ec, __FILE__, __LINE__); + return pure_virtual_error (ec); } //-------------------------------------------------------------------------- - void async_handshake (handshake_type type, SharedHandlerPtr handler) + void async_handshake (handshake_type type, error_handler handler) override { - using namespace detail::SocketWrapperMemberChecks; - async_handshake (type, BOOST_ASIO_MOVE_CAST(SharedHandlerPtr)(handler), + async_handshake (type, handler, Enabled > ()); + void (handshake_type, error_handler)> > ()); } - void async_handshake (handshake_type type, - BOOST_ASIO_MOVE_ARG(SharedHandlerPtr) handler, - TrueType) + void async_handshake (handshake_type type, error_handler const& handler, + std::true_type) { - m_object.async_handshake (type, - BOOST_ASIO_MOVE_CAST(SharedHandlerPtr)(handler)); + m_object.async_handshake (type, handler); } - void async_handshake (handshake_type, BOOST_ASIO_MOVE_ARG(SharedHandlerPtr) handler, - FalseType) + void async_handshake (handshake_type, error_handler const& handler, + std::false_type) { - get_io_service ().wrap ( - BOOST_ASIO_MOVE_CAST(SharedHandlerPtr)(handler)) - (pure_virtual_error ()); + get_io_service ().post (bind_handler ( + handler, pure_virtual_error())); } //-------------------------------------------------------------------------- -#if BEAST_ASIO_HAS_BUFFEREDHANDSHAKE - - error_code handshake (handshake_type type, - ConstBuffers const& buffers, error_code& ec) + error_code + handshake (handshake_type type, const_buffers buffers, + error_code& ec) override { - using namespace detail::SocketWrapperMemberChecks; return handshake (type, buffers, ec, Enabled > ()); + error_code (handshake_type, const_buffers const&, error_code&)> > ()); } - error_code handshake (handshake_type type, - ConstBuffers const& buffers, error_code& ec, - TrueType) + error_code + handshake (handshake_type type, const_buffers const& buffers, + error_code& ec, + std::true_type) { return m_object.handshake (type, buffers, ec); } - error_code handshake (handshake_type, ConstBuffers const&, error_code& ec, - FalseType) + error_code + handshake (handshake_type, const_buffers const&, + error_code& ec, + std::false_type) { - return pure_virtual_error (ec, __FILE__, __LINE__); + return pure_virtual_error (ec); } //-------------------------------------------------------------------------- void async_handshake (handshake_type type, - ConstBuffers const& buffers, SharedHandlerPtr handler) + const_buffers buffers, transfer_handler handler) override { - using namespace detail::SocketWrapperMemberChecks; - async_handshake (type, buffers, - BOOST_ASIO_MOVE_CAST(SharedHandlerPtr)(handler), - Enabled > ()); + async_handshake (type, buffers, handler, + Enabled > ()); } - void async_handshake (handshake_type type, ConstBuffers const& buffers, - BOOST_ASIO_MOVE_ARG(SharedHandlerPtr) handler, - TrueType) + void async_handshake (handshake_type type, const_buffers const& buffers, + transfer_handler const& handler, + std::true_type) { - m_object.async_handshake (type, buffers, - BOOST_ASIO_MOVE_CAST(SharedHandlerPtr)(handler)); + m_object.async_handshake (type, buffers, handler); } - void async_handshake (handshake_type, ConstBuffers const&, - BOOST_ASIO_MOVE_ARG(SharedHandlerPtr) handler, - FalseType) + void async_handshake (handshake_type, const_buffers const&, + transfer_handler const& handler, + std::false_type) { - get_io_service ().wrap ( - BOOST_ASIO_MOVE_CAST(SharedHandlerPtr)(handler)) - (pure_virtual_error (), 0); + get_io_service ().post (bind_handler ( + handler, pure_virtual_error(), 0)); } -#endif - //-------------------------------------------------------------------------- - error_code shutdown (error_code& ec) + error_code shutdown (error_code& ec) override { - using namespace detail::SocketWrapperMemberChecks; return shutdown (ec, Enabled > ()); } error_code shutdown (error_code& ec, - TrueType) + std::true_type) { return m_object.shutdown (ec); } error_code shutdown (error_code& ec, - FalseType) + std::false_type) { - return pure_virtual_error (ec, __FILE__, __LINE__); + return pure_virtual_error (ec); } //-------------------------------------------------------------------------- - void async_shutdown (SharedHandlerPtr handler) + void async_shutdown (error_handler handler) override { - using namespace detail::SocketWrapperMemberChecks; - async_shutdown (BOOST_ASIO_MOVE_CAST(SharedHandlerPtr)(handler), + async_shutdown (handler, Enabled > ()); + void (error_handler)> > ()); } - void async_shutdown (BOOST_ASIO_MOVE_ARG(SharedHandlerPtr) handler, - TrueType) + void async_shutdown (error_handler const& handler, + std::true_type) { - m_object.async_shutdown ( - BOOST_ASIO_MOVE_CAST(SharedHandlerPtr)(handler)); + m_object.async_shutdown (handler); } - void async_shutdown (BOOST_ASIO_MOVE_ARG(SharedHandlerPtr) handler, - FalseType) + void async_shutdown (error_handler const& handler, + std::false_type) { - get_io_service ().wrap ( - BOOST_ASIO_MOVE_CAST(SharedHandlerPtr)(handler)) - (pure_virtual_error ()); + get_io_service ().post (bind_handler ( + handler, pure_virtual_error())); } - -private: - Object m_object; }; +} +} + #endif diff --git a/src/beast/modules/beast_asio/sockets/SocketBase.h b/src/beast/beast/asio/tests/bind_handler_tests.cpp similarity index 50% rename from src/beast/modules/beast_asio/sockets/SocketBase.h rename to src/beast/beast/asio/tests/bind_handler_tests.cpp index 2504df37f3f..e24ed35d1ed 100644 --- a/src/beast/modules/beast_asio/sockets/SocketBase.h +++ b/src/beast/beast/asio/tests/bind_handler_tests.cpp @@ -17,33 +17,42 @@ */ //============================================================================== -#ifndef BEAST_ASIO_SOCKETS_SOCKETBASE_H_INCLUDED -#define BEAST_ASIO_SOCKETS_SOCKETBASE_H_INCLUDED +#include "BeastConfig.h" -/** Common implementation details for Socket and related classes. - Normally you wont need to use this. -*/ -struct SocketBase +#include "../../../modules/beast_core/beast_core.h" // for UnitTest + +#include "../bind_handler.h" + +#include + +namespace beast { +namespace asio { + +class bind_handler_Tests : public UnitTest { public: - typedef boost::system::error_code error_code; + static void foo (int) + { + } + + void runTest() + { + beginTestCase ("call"); - /** The error returned when a pure virtual is called. - This is mostly academic since a pure virtual call generates - a fatal error but in case that gets disabled, this will at - least return a suitable error code. - */ - static error_code pure_virtual_error (); + auto f (bind_handler (std::bind (&foo, std::placeholders::_1), + 42)); - /** Convenience for taking a reference and returning the error_code. */ - static error_code pure_virtual_error (error_code& ec, - char const* fileName, int lineNumber); + f(); - /** Called when a function doesn't support the interface. */ - static void pure_virtual_called (char const* fileName, int lineNumber); + pass(); + } - /** Called when synchronous functions without error parameters get an error. */ - static void throw_error (error_code const& ec, char const* fileName, int lineNumber); + bind_handler_Tests() : UnitTest ("bind_handler", "beast", runManual) + { + } }; -#endif +static bind_handler_Tests bind_handler_tests; + +} +} diff --git a/src/beast/beast/asio/tests/shared_handler_tests.cpp b/src/beast/beast/asio/tests/shared_handler_tests.cpp new file mode 100644 index 00000000000..18613847f7b --- /dev/null +++ b/src/beast/beast/asio/tests/shared_handler_tests.cpp @@ -0,0 +1,239 @@ +//------------------------------------------------------------------------------ +/* + This file is part of Beast: https://github.com/vinniefalco/Beast + Copyright 2013, Vinnie Falco + + Permission to use, copy, modify, and/or distribute this software for any + purpose with or without fee is hereby granted, provided that the above + copyright notice and this permission notice appear in all copies. + + THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +*/ +//============================================================================== + +#include "BeastConfig.h" + +#include "../../../modules/beast_core/beast_core.h" // for UnitTest + +#include "../shared_handler.h" + +// Disables is_constructible tests for std::function +// Visual Studio std::function fails the is_constructible tests +#ifndef BEAST_NO_STD_FUNCTION_CONSTRUCTIBLE +# ifdef _MSC_VER +# define BEAST_NO_STD_FUNCTION_CONSTRUCTIBLE 1 +# else +# define BEAST_NO_STD_FUNCTION_CONSTRUCTIBLE 0 +# endif +#endif + +namespace beast { + +class shared_handler_Tests : public UnitTest +{ +public: + struct test_results + { + bool call; + bool invoke; + bool alloc; + bool dealloc; + bool cont; + + test_results () + : call (false) + , invoke (false) + , alloc (false) + , dealloc (false) + , cont (false) + { + } + }; + + struct test_handler + { + std::reference_wrapper results; + + explicit test_handler (test_results& results_) + : results (results_) + { + } + + void operator() () + { + results.get().call = true; + } + + template + friend void asio_handler_invoke ( + Function& f, test_handler* h) + { + h->results.get().invoke = true; + f(); + } + + template + friend void asio_handler_invoke ( + Function const& f, test_handler* h) + { + h->results.get().invoke = true; + f(); + } + + friend void* asio_handler_allocate ( + std::size_t size, test_handler* h) + { + h->results.get().alloc = true; + return boost::asio::asio_handler_allocate (size); + } + + friend void asio_handler_deallocate ( + void* p, std::size_t size, test_handler* h) + { + h->results.get().dealloc = true; + boost::asio::asio_handler_deallocate (p, size); + } + + friend bool asio_handler_is_continuation ( + test_handler* h) + { + h->results.get().cont = true; + return true; + } + }; + + struct test_invokable + { + bool call; + + test_invokable () + : call (false) + { + } + + void operator() () + { + call = true; + } + }; + + template + bool async_op (Handler&& handler) + { + void* const p (boost_asio_handler_alloc_helpers::allocate (32, handler)); + handler(); + boost_asio_handler_alloc_helpers::deallocate (p, 32, handler); + return boost_asio_handler_cont_helpers::is_continuation (handler); + } + + void virtual_async_op (asio::shared_handler handler) + { + async_op (handler); + } + + void runTest() + { + beginTestCase ("hooks"); + + #if ! BEAST_NO_STD_FUNCTION_CONSTRUCTIBLE + static_assert (! std::is_constructible < + std::function , int&&>::value, + "Cannot construct std::function from int&&"); + + static_assert (! std::is_constructible < + std::function , int>::value, + "Cannot construct std::function from int"); + + static_assert (! std::is_constructible < + asio::shared_handler , int>::value, + "Cannot construct shared_handler from int"); + #endif + + static_assert (std::is_constructible < + asio::shared_handler , + asio::shared_handler >::value, + "Should construct from "); + + static_assert (! std::is_constructible < + asio::shared_handler , + asio::shared_handler >::value, + "Can't construct from "); + + // Hooks called when using the raw handler + { + test_results r; + test_handler h (r); + + async_op (h); + expect (r.call); + expect (r.alloc); + expect (r.dealloc); + expect (r.cont); + + test_invokable f; + boost_asio_handler_invoke_helpers::invoke (std::ref (f), h); + expect (r.invoke); + expect (f.call); + } + + // Use of std::function shows the hooks not getting called + { + test_results r; + std::function fh ((test_handler) (r)); + + async_op (fh); + expect (r.call); + unexpected (r.alloc); + unexpected (r.dealloc); + unexpected (r.cont); + + test_invokable f; + boost_asio_handler_invoke_helpers::invoke (std::ref (f), fh); + unexpected (r.invoke); + expect (f.call); + } + + // Make sure shared_handler calls the hooks + { + test_results r; + asio::shared_handler sh ((test_handler)(r)); + + async_op (sh); + expect (r.call); + expect (r.alloc); + expect (r.dealloc); + expect (r.cont); + + test_invokable f; + boost_asio_handler_invoke_helpers::invoke (std::ref (f), sh); + expect (r.invoke); + expect (f.call); + } + + // Make sure shared_handler via implicit conversion calls hooks + { + test_results r; + test_handler h (r); + + virtual_async_op ((test_handler) (r)); + expect (r.call); + expect (r.alloc); + expect (r.dealloc); + expect (r.cont); + } + } + + shared_handler_Tests() : UnitTest ("shared_handler", "beast") + { + } +}; + +static shared_handler_Tests shared_handler_tests; + +} diff --git a/src/beast/beast/asio/tests/wrap_handler_tests.cpp b/src/beast/beast/asio/tests/wrap_handler_tests.cpp new file mode 100644 index 00000000000..7ccc2b39842 --- /dev/null +++ b/src/beast/beast/asio/tests/wrap_handler_tests.cpp @@ -0,0 +1,287 @@ +//------------------------------------------------------------------------------ +/* + This file is part of Beast: https://github.com/vinniefalco/Beast + Copyright 2013, Vinnie Falco + + Permission to use, copy, modify, and/or distribute this software for any + purpose with or without fee is hereby granted, provided that the above + copyright notice and this permission notice appear in all copies. + + THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +*/ +//============================================================================== + +#include "BeastConfig.h" + +#include "../../../modules/beast_core/beast_core.h" // for UnitTest + +#include "../wrap_handler.h" + +#include + +#include +#include +#include + +namespace beast { +namespace asio { + +//------------------------------------------------------------------------------ + +// Displays the order of destruction of parameters in the bind wrapper +// +class boost_bind_Tests : public UnitTest +{ +public: + struct Result + { + std::string text; + + void push_back (std::string const& s) + { + if (! text.empty()) + text += ", "; + text += s; + } + }; + + struct Payload + { + std::reference_wrapper m_result; + std::string m_name; + + explicit Payload (Result& result, std::string const& name) + : m_result (result) + , m_name (name) + { + } + + ~Payload () + { + m_result.get().push_back (m_name); + } + }; + + struct Arg + { + std::shared_ptr m_payload; + + Arg (Result& result, std::string const& name) + : m_payload (std::make_shared (result, name)) + { + } + }; + + static void foo (Arg const&, Arg const&, Arg const&) + { + } + + void runTest() + { + beginTestCase ("order"); + + { + Result r; + { + boost::bind (&foo, + Arg (r, "one"), + Arg (r, "two"), + Arg (r, "three")); + } + logMessage (std::string ("boost::bind (") + r.text + ")"); + } + + { + Result r; + { + std::bind (&foo, + Arg (r, "one"), + Arg (r, "two"), + Arg (r, "three")); + } + logMessage (std::string ("std::bind (") + r.text + ")"); + } + + pass(); + } + + boost_bind_Tests() : UnitTest ("bind", "beast", runManual) + { + } +}; + +static boost_bind_Tests boost_bind_tests; + +//------------------------------------------------------------------------------ + +class wrap_handler_handler_Tests : public UnitTest +{ +public: + struct test_results + { + bool call; + bool invoke; + bool alloc; + bool dealloc; + bool cont; + + test_results () + : call (false) + , invoke (false) + , alloc (false) + , dealloc (false) + , cont (false) + { + } + }; + + struct test_handler + { + std::reference_wrapper results; + + explicit test_handler (test_results& results_) + : results (results_) + { + } + + void operator() () + { + results.get().call = true; + } + + template + friend void asio_handler_invoke ( + Function& f, test_handler* h) + { + h->results.get().invoke = true; + f(); + } + + template + friend void asio_handler_invoke ( + Function const& f, test_handler* h) + { + h->results.get().invoke = true; + f(); + } + + friend void* asio_handler_allocate ( + std::size_t, test_handler* h) + { + h->results.get().alloc = true; + return nullptr; + } + + friend void asio_handler_deallocate ( + void*, std::size_t, test_handler* h) + { + h->results.get().dealloc = true; + } + + friend bool asio_handler_is_continuation ( + test_handler* h) + { + h->results.get().cont = true; + return true; + } + }; + + struct test_invokable + { + bool call; + + test_invokable () + : call (false) + { + } + + void operator() () + { + call = true; + } + }; + + template + bool async_op (Handler&& handler) + { + void* const p (boost_asio_handler_alloc_helpers::allocate (32, handler)); + (handler)(); + boost_asio_handler_alloc_helpers::deallocate (p, 32, handler); + return boost_asio_handler_cont_helpers::is_continuation (handler); + } + + void runTest() + { + beginTestCase ("hooks"); + + // Hooks called when using the raw handler + { + test_results r; + test_handler h (r); + + async_op (h); + expect (r.call); + expect (r.alloc); + expect (r.dealloc); + expect (r.cont); + + test_invokable f; + boost_asio_handler_invoke_helpers::invoke (std::ref (f), h); + expect (r.invoke); + expect (f.call); + } + + // Use of boost::bind shows the hooks not getting called + { + test_results r; + test_handler h (r); + auto b (std::bind (&test_handler::operator(), &h)); + + async_op (b); + expect (r.call); + unexpected (r.alloc); + unexpected (r.dealloc); + unexpected (r.cont); + + test_invokable f; + boost_asio_handler_invoke_helpers::invoke (std::ref (f), b); + unexpected (r.invoke); + expect (f.call); + } + + // Make sure the wrapped handler calls the hooks + { + test_results r; + test_handler h (r); + auto w (wrap_handler ( + std::bind (&test_handler::operator(), test_handler(r)), h)); + + async_op (w); + expect (r.call); + expect (r.alloc); + expect (r.dealloc); + expect (r.cont); + + test_invokable f; + boost_asio_handler_invoke_helpers::invoke (std::ref (f), w); + expect (r.invoke); + expect (f.call); + } + } + + wrap_handler_handler_Tests() : UnitTest ("wrap_handler", "beast") + { + } +}; + +static wrap_handler_handler_Tests wrap_handler_handler_tests; + +} +} + diff --git a/src/beast/beast/asio/wrap_handler.h b/src/beast/beast/asio/wrap_handler.h new file mode 100644 index 00000000000..8665ec8e05b --- /dev/null +++ b/src/beast/beast/asio/wrap_handler.h @@ -0,0 +1,176 @@ +//------------------------------------------------------------------------------ +/* + This file is part of Beast: https://github.com/vinniefalco/Beast + Copyright 2013, Vinnie Falco + + Permission to use, copy, modify, and/or distribute this software for any + purpose with or without fee is hereby granted, provided that the above + copyright notice and this permission notice appear in all copies. + + THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +*/ +//============================================================================== + +#ifndef BEAST_ASIO_WRAP_HANDLER_H_INCLUDED +#define BEAST_ASIO_WRAP_HANDLER_H_INCLUDED + +#include +#include +#include + +#include +#include + +namespace beast { +namespace asio { + +#ifdef _MSC_VER +#pragma warning (push) +#pragma warning (disable: 4512) // assignment operator could not be generated +#endif + +namespace detail { + +/** A handler which wraps another handler using a specfic context. + The handler is invoked with the same io_service execution guarantees + as the provided context. + @note A copy of Context is made. +*/ +template +class wrapped_handler +{ +private: + Handler m_handler; + Context m_context; + bool m_continuation; + + // If this goes off, consider carefully what the intent is. + static_assert (! std::is_reference ::value, + "Handler should not be a reference type"); + +public: + wrapped_handler (bool continuation, Handler&& handler, Context context) + : m_handler (std::move (handler)) + , m_context (context) + , m_continuation (continuation ? true : + boost_asio_handler_cont_helpers::is_continuation (context)) + { + } + + wrapped_handler (bool continuation, Handler const& handler, Context context) + : m_handler (handler) + , m_context (context) + , m_continuation (continuation ? true : + boost_asio_handler_cont_helpers::is_continuation (context)) + { + } + + template + void + operator() (Args&&... args) + { + m_handler (std::forward (args)...); + } + + template + void + operator() (Args&&... args) const + { + m_handler (std::forward (args)...); + } + + template + friend + void + asio_handler_invoke (Function& f, wrapped_handler* h) + { + boost_asio_handler_invoke_helpers:: + invoke (f, h->m_context); + } + + template + friend + void + asio_handler_invoke (Function const& f, wrapped_handler* h) + { + boost_asio_handler_invoke_helpers:: + invoke (f, h->m_context); + } + + friend + void* + asio_handler_allocate (std::size_t size, wrapped_handler* h) + { + return boost_asio_handler_alloc_helpers:: + allocate (size, h->m_context); + } + + friend + void + asio_handler_deallocate (void* p, std::size_t size, wrapped_handler* h) + { + boost_asio_handler_alloc_helpers:: + deallocate (p, size, h->m_context); + } + + friend + bool + asio_handler_is_continuation (wrapped_handler* h) + { + return h->m_continuation; + } +}; + +} + +//------------------------------------------------------------------------------ + +// Tag for dispatching wrap_handler with is_continuation == true +enum continuation_t +{ + continuation +}; + +/** Returns a wrapped handler so it executes within another context. + The handler is invoked with the same io_service execution guarantees + as the provided context. The handler will be copied if necessary. + @note A copy of Context is made. +*/ +/** @{ */ +template +detail::wrapped_handler < + std::remove_reference_t , + Context +> +wrap_handler (DeducedHandler&& handler, Context const& context, + bool continuation = false) +{ + typedef std::remove_reference_t Handler; + return detail::wrapped_handler (continuation, + std::forward (handler), context); +} + +template +detail::wrapped_handler < + std::remove_reference_t , + Context +> +wrap_handler (continuation_t, DeducedHandler&& handler, + Context const& context) +{ + typedef std::remove_reference_t Handler; + return detail::wrapped_handler (true, + std::forward (handler), context); +} +/** @} */ + +} +} + +#endif diff --git a/src/beast/modules/beast_asio/sockets/SocketBase.cpp b/src/beast/beast/boost/get_pointer.h similarity index 60% rename from src/beast/modules/beast_asio/sockets/SocketBase.cpp rename to src/beast/beast/boost/get_pointer.h index 4ca14e478ad..bbc2e5b8a5b 100644 --- a/src/beast/modules/beast_asio/sockets/SocketBase.cpp +++ b/src/beast/beast/boost/get_pointer.h @@ -17,26 +17,30 @@ */ //============================================================================== -boost::system::error_code SocketBase::pure_virtual_error () -{ - return boost::system::errc::make_error_code ( - boost::system::errc::function_not_supported); -} +#ifndef BEAST_BOOST_GET_POINTER_H_INCLUDED +#define BEAST_BOOST_GET_POINTER_H_INCLUDED -boost::system::error_code SocketBase::pure_virtual_error (error_code& ec, - char const* fileName, int lineNumber) -{ - pure_virtual_called (fileName, lineNumber); - return ec = pure_virtual_error (); -} +#include -void SocketBase::pure_virtual_called (char const* fileName, int lineNumber) +// Boost 1.55 incorrectly defines BOOST_NO_CXX11_SMART_PTR +// when building with clang 3.4 and earlier. This workaround +// gives beast its own overloads. + +#ifdef BOOST_NO_CXX11_SMART_PTR +#include +namespace beast { +template +T* get_pointer (std::unique_ptr const& p) { - Throw (std::runtime_error ("pure virtual called"), fileName, lineNumber); + return p.get(); } -void SocketBase::throw_error (error_code const& ec, char const* fileName, int lineNumber) +template +T* get_pointer (std::shared_ptr const& p) { - if (ec) - Throw (boost::system::system_error (ec), fileName, lineNumber); + return p.get(); +} } +#endif + +#endif diff --git a/src/beast/beast/cxx14/memory.h b/src/beast/beast/cxx14/memory.h index 6c92471cc66..38430cd2e58 100644 --- a/src/beast/beast/cxx14/memory.h +++ b/src/beast/beast/cxx14/memory.h @@ -27,13 +27,11 @@ namespace std { #if ! BEAST_NO_CXX14_MAKE_UNIQUE - template std::unique_ptr make_unique (Args&&... args) { return std::unique_ptr (new T (std::forward (args)...)); } - #endif } diff --git a/src/beast/beast/http/impl/ParsedURL.cpp b/src/beast/beast/http/impl/ParsedURL.cpp index 1393b6e1630..ee103d779b6 100644 --- a/src/beast/beast/http/impl/ParsedURL.cpp +++ b/src/beast/beast/http/impl/ParsedURL.cpp @@ -19,10 +19,10 @@ #include "../ParsedURL.h" -#include "http-parser/http_parser.h" - #include "../../../modules/beast_core/beast_core.h" // for UnitTest +#include "http_parser.h" + namespace beast { ParsedURL::ParsedURL () diff --git a/src/beast/beast/http/impl/http_parser.cpp b/src/beast/beast/http/impl/http_parser.cpp index 42b5b8eb245..cfc751b872a 100644 --- a/src/beast/beast/http/impl/http_parser.cpp +++ b/src/beast/beast/http/impl/http_parser.cpp @@ -24,13 +24,13 @@ namespace beast { #ifdef _MSC_VER -#pragma warning (push) -#pragma warning (disable: 4127) // conditional expression is constant -#pragma warning (disable: 4244) // integer conversion, possible loss of data +# pragma warning (push) +# pragma warning (disable: 4127) // conditional expression is constant +# pragma warning (disable: 4244) // integer conversion, possible loss of data #endif #include "http-parser/http_parser.c" #ifdef _MSC_VER -#pragma warning (pop) +# pragma warning (pop) #endif } diff --git a/src/beast/beast/http/impl/http_parser.h b/src/beast/beast/http/impl/http_parser.h new file mode 100644 index 00000000000..9b0fb196872 --- /dev/null +++ b/src/beast/beast/http/impl/http_parser.h @@ -0,0 +1,33 @@ +//------------------------------------------------------------------------------ +/* + This file is part of Beast: https://github.com/vinniefalco/Beast + Copyright 2013, Vinnie Falco + + Permission to use, copy, modify, and/or distribute this software for any + purpose with or without fee is hereby granted, provided that the above + copyright notice and this permission notice appear in all copies. + + THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +*/ +//============================================================================== + +#ifndef BEAST_HTTP_HTTP_PARSER_H_INCLUDED +#define BEAST_HTTP_HTTP_PARSER_H_INCLUDED + +#include "BeastConfig.h" + +// Wraps the C-language joyent http parser header in our namespace + +namespace beast { + +#include "http-parser/http_parser.h" + +} + +#endif diff --git a/src/beast/beast/mpl/IsCallPossible.h b/src/beast/beast/mpl/IsCallPossible.h index d6a6ffb108d..bc85184aeee 100644 --- a/src/beast/beast/mpl/IsCallPossible.h +++ b/src/beast/beast/mpl/IsCallPossible.h @@ -62,7 +62,7 @@ namespace is_call_possible_detail } #define BEAST_DEFINE_HAS_MEMBER_FUNCTION(trait_name, member_function_name) \ -template class trait_name; \ +template class trait_name; \ \ template \ class trait_name \ @@ -160,7 +160,7 @@ struct trait_name##_detail BEAST_DEFINE_HAS_MEMBER_FUNCTION(has_member, member_function_name); \ }; \ \ -template \ +template \ struct trait_name \ { \ private: \ @@ -261,7 +261,8 @@ struct trait_name }; \ \ public: \ - static const bool value = impl::value, Signature>::value; \ + static const bool value = impl::value, \ + IsCallPossibleSignature>::value; \ } } diff --git a/src/beast/modules/beast_asio/async/AbstractHandler.h b/src/beast/modules/beast_asio/async/AbstractHandler.h deleted file mode 100644 index 7a92f5bf224..00000000000 --- a/src/beast/modules/beast_asio/async/AbstractHandler.h +++ /dev/null @@ -1,712 +0,0 @@ -//------------------------------------------------------------------------------ -/* - This file is part of Beast: https://github.com/vinniefalco/Beast - Copyright 2013, Vinnie Falco - - Permission to use, copy, modify, and/or distribute this software for any - purpose with or without fee is hereby granted, provided that the above - copyright notice and this permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -*/ -//============================================================================== - -#ifndef BEAST_ASIO_ABSTRACTHANDLER_H_INCLUDED -#define BEAST_ASIO_ABSTRACTHANDLER_H_INCLUDED - -namespace beast { - -namespace detail { - -struct AbstractHandlerCallBase : SharedObject -{ - //typedef SharedFunction > invoked_type; - - typedef SharedFunction invoked_type; - - virtual void* allocate (std::size_t size) = 0; - virtual void deallocate (void* p, std::size_t size) = 0; - virtual bool is_continuation () = 0; - virtual void invoke (invoked_type& invoked) = 0; - - template - void invoke (BEAST_MOVE_ARG(Function) f) - { - invoked_type invoked (BEAST_MOVE_CAST(Function)(f) - //, AbstractHandlerAllocator(this) - ); - invoke (invoked); - } -}; - -/* -template -struct AbstractHandlerAllocator -{ - typedef T value_type; - typedef T* pointer; - typedef T& reference; - typedef T const* const_pointer; - typedef T const& const_reference; - typedef std::size_t size_type; - typedef std::ptrdiff_t difference_type; - - AbstractHandlerAllocator (AbstractHandler* handler) noexcept - : m_ptr (handler) - { - } - - AbstractHandlerAllocator (SharedPtr const& ptr) noexcept - : m_ptr (ptr) - { - } - - template - AbstractHandlerAllocator (AbstractHandlerAllocator const& other) - : m_ptr (other.m_ptr) - { - } - - template - struct rebind - { - typedef AbstractHandlerAllocator other; - }; - - pointer address (reference x) const - { - return &x; - } - - const_pointer address (const_reference x) const - { - return &x; - } - - pointer allocate (size_type n) const - { - size_type const bytes = n * sizeof (value_type); - return static_cast (m_ptr->allocate (bytes)); - } - - void deallocate (pointer p, size_type n) const - { - size_type const bytes = n * sizeof (value_type); - m_ptr->deallocate (p, bytes); - } - - size_type max_size () const noexcept - { - return std::numeric_limits ::max () / sizeof (value_type); - } - - void construct (pointer p, const_reference val) const - { - new ((void *)p) value_type (val); - } - - void destroy (pointer p) const - { - p->~value_type (); - } - -private: - template - friend struct AbstractHandlerAllocator; - friend class AbstractHandler; - - SharedPtr m_ptr; -}; -*/ - -} - -/** A reference counted, abstract completion handler. */ -template > -struct AbstractHandler; - -//------------------------------------------------------------------------------ - -// arity 0 -template -struct AbstractHandler -{ - typedef R result_type; - struct Call : detail::AbstractHandlerCallBase - { virtual R operator() () = 0; }; - - template - struct CallType : public Call - { - typedef typename A:: template rebind >::other Allocator; - CallType (BEAST_MOVE_ARG(H) h, A a = A ()) - : m_h (BEAST_MOVE_CAST(H)(h)), m_alloc (a) - { } - R operator()() - { return (m_h)(); } - R operator()() const - { return (m_h)(); } - void* allocate (std::size_t size) - { return boost_asio_handler_alloc_helpers::allocate(size, m_h); } - void deallocate (void* pointer, std::size_t size) - { boost_asio_handler_alloc_helpers::deallocate( pointer, size, m_h); } - bool is_continuation () -#if BEAST_ASIO_HAS_CONTINUATION_HOOKS - { return boost_asio_handler_cont_helpers::is_continuation(m_h); } -#else - { return false; } -#endif - void invoke (typename detail::AbstractHandlerCallBase::invoked_type& invoked) - { boost_asio_handler_invoke_helpers::invoke < - typename detail::AbstractHandlerCallBase::invoked_type, H> (invoked, m_h); } - private: - H m_h; - Allocator m_alloc; - }; - - template - AbstractHandler (BEAST_MOVE_ARG(H) h, A a = A ()) - : m_call (new ( - typename A:: template rebind >::other (a) - .allocate (1)) CallType (BEAST_MOVE_CAST(H)(h), a)) - { } - R operator() () - { return (*m_call)(); } - R operator() () const - { return (*m_call)(); } - void* allocate (std::size_t size) const { return m_call->allocate(size); } - void deallocate (void* pointer, std::size_t size) const { m_call->deallocate(pointer,size); } - bool is_continuation () const { return m_call->is_continuation(); } - template - void invoke (Function& function) const - { - m_call->invoke(function); - } - template - void invoke (Function const& function) const - { - m_call->invoke(function); - } - -private: - SharedPtr m_call; -}; - -template -void* asio_handler_allocate (std::size_t size, - AbstractHandler * handler) -{ - return handler->allocate (size); -} - -template -void asio_handler_deallocate (void* pointer, std::size_t size, - AbstractHandler * handler) -{ - handler->deallocate (pointer, size); -} - -template -bool asio_handler_is_continuation( - AbstractHandler * handler) -{ - return handler->is_continuation(); -} - -template -void asio_handler_invoke (BEAST_MOVE_ARG(Function) function, - AbstractHandler * handler) -{ - handler->invoke (BEAST_MOVE_CAST(Function)(function)); -} - -//------------------------------------------------------------------------------ - -// arity 1 -template -struct AbstractHandler -{ - typedef R result_type; - struct Call : detail::AbstractHandlerCallBase - { virtual R operator() (P1) = 0; }; - - template - struct CallType : public Call - { - typedef typename A:: template rebind >::other Allocator; - CallType (H h, A a = A ()) - : m_h (h) - , m_alloc (a) - { - } - - R operator()(P1 p1) - { return (m_h)(p1); } - R operator()(P1 p1) const - { return (m_h)(p1); } - void* allocate (std::size_t size) - { return boost_asio_handler_alloc_helpers::allocate(size, m_h); } - void deallocate (void* pointer, std::size_t size) - { boost_asio_handler_alloc_helpers::deallocate( pointer, size, m_h); } - bool is_continuation () -#if BEAST_ASIO_HAS_CONTINUATION_HOOKS - { return boost_asio_handler_cont_helpers::is_continuation(m_h); } -#else - { return false; } -#endif - void invoke (typename detail::AbstractHandlerCallBase::invoked_type& invoked) - { boost_asio_handler_invoke_helpers::invoke < - typename detail::AbstractHandlerCallBase::invoked_type, H> (invoked, m_h); } - private: - H m_h; - Allocator m_alloc; - }; - - template - AbstractHandler (H h, A a = A ()) - : m_call (new ( - typename A:: template rebind >::other (a) - .allocate (1)) CallType (h, a)) - { - } - - R operator() (P1 p1) - { return (*m_call)(p1); } - R operator() (P1 p1) const - { return (*m_call)(p1); } - void* allocate (std::size_t size) const { return m_call->allocate(size); } - void deallocate (void* pointer, std::size_t size) const { m_call->deallocate(pointer,size); } - bool is_continuation () const { return m_call->is_continuation(); } - template - void invoke (Function& function) const - { - m_call->invoke(function); - } - template - void invoke (Function const& function) const - { - m_call->invoke(function); - } - -private: - SharedPtr m_call; -}; - -template -void* asio_handler_allocate (std::size_t size, - AbstractHandler * handler) -{ - return handler->allocate (size); -} - -template -void asio_handler_deallocate (void* pointer, std::size_t size, - AbstractHandler * handler) -{ - handler->deallocate (pointer, size); -} - -template -bool asio_handler_is_continuation( - AbstractHandler * handler) -{ - return handler->is_continuation(); -} - -template -void asio_handler_invoke (BEAST_MOVE_ARG(Function) function, - AbstractHandler * handler) -{ - handler->invoke (BEAST_MOVE_CAST(Function)(function)); -} - -//------------------------------------------------------------------------------ - -// arity 2 -template -struct AbstractHandler -{ - typedef R result_type; - struct Call : detail::AbstractHandlerCallBase - { virtual R operator() (P1, P2) = 0; }; - - template - struct CallType : public Call - { - typedef typename A:: template rebind >::other Allocator; - CallType (BEAST_MOVE_ARG(H) h, A a = A ()) - : m_h (BEAST_MOVE_CAST(H)(h)), m_alloc (a) - { } - R operator()(P1 p1, P2 p2) - { return (m_h)(p1, p2); } - R operator()(P1 p1, P2 p2) const - { return (m_h)(p1, p2); } - void* allocate (std::size_t size) - { return boost_asio_handler_alloc_helpers::allocate(size, m_h); } - void deallocate (void* pointer, std::size_t size) - { boost_asio_handler_alloc_helpers::deallocate( pointer, size, m_h); } - bool is_continuation () -#if BEAST_ASIO_HAS_CONTINUATION_HOOKS - { return boost_asio_handler_cont_helpers::is_continuation(m_h); } -#else - { return false; } -#endif - void invoke (typename detail::AbstractHandlerCallBase::invoked_type& invoked) - { boost_asio_handler_invoke_helpers::invoke < - typename detail::AbstractHandlerCallBase::invoked_type, H> (invoked, m_h); } - private: - H m_h; - Allocator m_alloc; - }; - - template - AbstractHandler (BEAST_MOVE_ARG(H) h, A a = A ()) - : m_call (new ( - typename A:: template rebind >::other (a) - .allocate (1)) CallType (BEAST_MOVE_CAST(H)(h), a)) - { } - R operator() (P1 p1, P2 p2) - { return (*m_call)(p1, p2); } - R operator() (P1 p1, P2 p2) const - { return (*m_call)(p1, p2); } - void* allocate (std::size_t size) const { return m_call->allocate(size); } - void deallocate (void* pointer, std::size_t size) const { m_call->deallocate(pointer,size); } - bool is_continuation () const { return m_call->is_continuation(); } - template - void invoke (Function& function) const - { - m_call->invoke(function); - } - template - void invoke (Function const& function) const - { - m_call->invoke(function); - } - -private: - SharedPtr m_call; -}; - -template -void* asio_handler_allocate (std::size_t size, - AbstractHandler * handler) -{ - return handler->allocate (size); -} - -template -void asio_handler_deallocate (void* pointer, std::size_t size, - AbstractHandler * handler) -{ - handler->deallocate (pointer, size); -} - -template -bool asio_handler_is_continuation( - AbstractHandler * handler) -{ - return handler->is_continuation(); -} - -template -void asio_handler_invoke (BEAST_MOVE_ARG(Function) function, - AbstractHandler * handler) -{ - handler->invoke (BEAST_MOVE_CAST(Function)(function)); -} - -//------------------------------------------------------------------------------ - -// arity 3 -template -struct AbstractHandler -{ - typedef R result_type; - struct Call : detail::AbstractHandlerCallBase - { virtual R operator() (P1, P2, P3) = 0; }; - - template - struct CallType : public Call - { - typedef typename A:: template rebind >::other Allocator; - CallType (BEAST_MOVE_ARG(H) h, A a = A ()) - : m_h (BEAST_MOVE_CAST(H)(h)), m_alloc (a) - { } - R operator()(P1 p1, P2 p2, P3 p3) - { return (m_h)(p1, p2, p3); } - R operator()(P1 p1, P2 p2, P3 p3) const - { return (m_h)(p1, p2, p3); } - void* allocate (std::size_t size) - { return boost_asio_handler_alloc_helpers::allocate(size, m_h); } - void deallocate (void* pointer, std::size_t size) - { boost_asio_handler_alloc_helpers::deallocate( pointer, size, m_h); } - bool is_continuation () -#if BEAST_ASIO_HAS_CONTINUATION_HOOKS - { return boost_asio_handler_cont_helpers::is_continuation(m_h); } -#else - { return false; } -#endif - void invoke (typename detail::AbstractHandlerCallBase::invoked_type& invoked) - { boost_asio_handler_invoke_helpers::invoke < - typename detail::AbstractHandlerCallBase::invoked_type, H> (invoked, m_h); } - private: - H m_h; - Allocator m_alloc; - }; - - template - AbstractHandler (BEAST_MOVE_ARG(H) h, A a = A ()) - : m_call (new ( - typename A:: template rebind >::other (a) - .allocate (1)) CallType (BEAST_MOVE_CAST(H)(h), a)) - { } - R operator() (P1 p1, P2 p2, P3 p3) - { return (*m_call)(p1, p2, p3); } - R operator() (P1 p1, P2 p2, P3 p3) const - { return (*m_call)(p1, p2, p3); } - void* allocate (std::size_t size) const { return m_call->allocate(size); } - void deallocate (void* pointer, std::size_t size) const { m_call->deallocate(pointer,size); } - bool is_continuation () const { return m_call->is_continuation(); } - template - void invoke (Function& function) const - { - m_call->invoke(function); - } - template - void invoke (Function const& function) const - { - m_call->invoke(function); - } - -private: - SharedPtr m_call; -}; - -template -void* asio_handler_allocate (std::size_t size, - AbstractHandler * handler) -{ - return handler->allocate (size); -} - -template -void asio_handler_deallocate (void* pointer, std::size_t size, - AbstractHandler * handler) -{ - handler->deallocate (pointer, size); -} - -template -bool asio_handler_is_continuation( - AbstractHandler * handler) -{ - return handler->is_continuation(); -} - -template -void asio_handler_invoke (BEAST_MOVE_ARG(Function) function, - AbstractHandler * handler) -{ - handler->invoke (BEAST_MOVE_CAST(Function)(function)); -} - -//------------------------------------------------------------------------------ - -// arity 4 -template -struct AbstractHandler -{ - typedef R result_type; - struct Call : detail::AbstractHandlerCallBase - { virtual R operator() (P1, P2, P3, P4) = 0; }; - - template - struct CallType : public Call - { - typedef typename A:: template rebind >::other Allocator; - CallType (BEAST_MOVE_ARG(H) h, A a = A ()) - : m_h (BEAST_MOVE_CAST(H)(h)), m_alloc (a) - { } - R operator()(P1 p1, P2 p2, P3 p3, P4 p4) - { return (m_h)(p1, p2, p3, p4); } - R operator()(P1 p1, P2 p2, P3 p3, P4 p4) const - { return (m_h)(p1, p2, p3, p4); } - void* allocate (std::size_t size) - { return boost_asio_handler_alloc_helpers::allocate(size, m_h); } - void deallocate (void* pointer, std::size_t size) - { boost_asio_handler_alloc_helpers::deallocate( pointer, size, m_h); } - bool is_continuation () -#if BEAST_ASIO_HAS_CONTINUATION_HOOKS - { return boost_asio_handler_cont_helpers::is_continuation(m_h); } -#else - { return false; } -#endif - void invoke (typename detail::AbstractHandlerCallBase::invoked_type& invoked) - { boost_asio_handler_invoke_helpers::invoke < - typename detail::AbstractHandlerCallBase::invoked_type, H> (invoked, m_h); } - private: - H m_h; - Allocator m_alloc; - }; - - template - AbstractHandler (BEAST_MOVE_ARG(H) h, A a = A ()) - : m_call (new ( - typename A:: template rebind >::other (a) - .allocate (1)) CallType (BEAST_MOVE_CAST(H)(h), a)) - { } - R operator() (P1 p1, P2 p2, P3 p3, P4 p4) - { return (*m_call)(p1, p2, p3, p4); } - R operator() (P1 p1, P2 p2, P3 p3, P4 p4) const - { return (*m_call)(p1, p2, p3, p4); } - void* allocate (std::size_t size) const { return m_call->allocate(size); } - void deallocate (void* pointer, std::size_t size) const { m_call->deallocate(pointer,size); } - bool is_continuation () const { return m_call->is_continuation(); } - template - void invoke (Function& function) const - { - m_call->invoke(function); - } - template - void invoke (Function const& function) const - { - m_call->invoke(function); - } - -private: - SharedPtr m_call; -}; - -template -void* asio_handler_allocate (std::size_t size, - AbstractHandler * handler) -{ - return handler->allocate (size); -} - -template -void asio_handler_deallocate (void* pointer, std::size_t size, - AbstractHandler * handler) -{ - handler->deallocate (pointer, size); -} - -template -bool asio_handler_is_continuation( - AbstractHandler * handler) -{ - return handler->is_continuation(); -} - -template -void asio_handler_invoke (BEAST_MOVE_ARG(Function) function, - AbstractHandler * handler) -{ - handler->invoke (BEAST_MOVE_CAST(Function)(function)); -} - -//------------------------------------------------------------------------------ - -// arity 5 -template -struct AbstractHandler -{ - typedef R result_type; - struct Call : detail::AbstractHandlerCallBase - { virtual R operator() (P1, P2, P3, P4, P5) = 0; }; - - template - struct CallType : public Call - { - typedef typename A:: template rebind >::other Allocator; - CallType (BEAST_MOVE_ARG(H) h, A a = A ()) - : m_h (BEAST_MOVE_CAST(H)(h)), m_alloc (a) - { } - R operator()(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5) - { return (m_h)(p1, p2, p3, p4, p5); } - R operator()(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5) const - { return (m_h)(p1, p2, p3, p4, p5); } - void* allocate (std::size_t size) - { return boost_asio_handler_alloc_helpers::allocate(size, m_h); } - void deallocate (void* pointer, std::size_t size) - { boost_asio_handler_alloc_helpers::deallocate( pointer, size, m_h); } - bool is_continuation () -#if BEAST_ASIO_HAS_CONTINUATION_HOOKS - { return boost_asio_handler_cont_helpers::is_continuation(m_h); } -#else - { return false; } -#endif - void invoke (typename detail::AbstractHandlerCallBase::invoked_type& invoked) - { boost_asio_handler_invoke_helpers::invoke < - typename detail::AbstractHandlerCallBase::invoked_type, H> (invoked, m_h); } - private: - H m_h; - Allocator m_alloc; - }; - - template - AbstractHandler (BEAST_MOVE_ARG(H) h, A a = A ()) - : m_call (new ( - typename A:: template rebind >::other (a) - .allocate (1)) CallType (BEAST_MOVE_CAST(H)(h), a)) - { } - R operator() (P1 p1, P2 p2, P3 p3, P4 p4, P5 p5) - { return (*m_call)(p1, p2, p3, p4, p5); } - R operator() (P1 p1, P2 p2, P3 p3, P4 p4, P5 p5) const - { return (*m_call)(p1, p2, p3, p4, p5); } - void* allocate (std::size_t size) const { return m_call->allocate(size); } - void deallocate (void* pointer, std::size_t size) const { m_call->deallocate(pointer,size); } - bool is_continuation () const { return m_call->is_continuation(); } - template - void invoke (Function& function) const - { - m_call->invoke(function); - } - template - void invoke (Function const& function) const - { - m_call->invoke(function); - } - -private: - SharedPtr m_call; -}; - -template -void* asio_handler_allocate (std::size_t size, - AbstractHandler * handler) -{ - return handler->allocate (size); -} - -template -void asio_handler_deallocate (void* pointer, std::size_t size, - AbstractHandler * handler) -{ - handler->deallocate (pointer, size); -} - -template -bool asio_handler_is_continuation( - AbstractHandler * handler) -{ - return handler->is_continuation(); -} - -template -void asio_handler_invoke (BEAST_MOVE_ARG(Function) function, - AbstractHandler * handler) -{ - handler->invoke (BEAST_MOVE_CAST(Function)(function)); -} - -} - -#endif diff --git a/src/beast/modules/beast_asio/async/AsyncObject.h b/src/beast/modules/beast_asio/async/AsyncObject.h index 3488f8f3c5a..ef4ef175836 100644 --- a/src/beast/modules/beast_asio/async/AsyncObject.h +++ b/src/beast/modules/beast_asio/async/AsyncObject.h @@ -20,6 +20,9 @@ #ifndef BEAST_ASIO_ASYNCOBJECT_H_INCLUDED #define BEAST_ASIO_ASYNCOBJECT_H_INCLUDED +namespace beast { +namespace asio { + /** Mix-in to track when all pending I/O is complete. Derived classes must be callable with this signature: void asyncHandlersComplete() @@ -80,4 +83,7 @@ class AsyncObject Atomic m_pending; }; +} +} + #endif diff --git a/src/beast/modules/beast_asio/async/ComposedAsyncOperation.h b/src/beast/modules/beast_asio/async/ComposedAsyncOperation.h deleted file mode 100644 index e1583712431..00000000000 --- a/src/beast/modules/beast_asio/async/ComposedAsyncOperation.h +++ /dev/null @@ -1,98 +0,0 @@ -//------------------------------------------------------------------------------ -/* - This file is part of Beast: https://github.com/vinniefalco/Beast - Copyright 2013, Vinnie Falco - - Permission to use, copy, modify, and/or distribute this software for any - purpose with or without fee is hereby granted, provided that the above - copyright notice and this permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -*/ -//============================================================================== - -#ifndef BEAST_ASIO_ASYNC_COMPOSEDASYNCOPERATION_H_INCLUDED -#define BEAST_ASIO_ASYNC_COMPOSEDASYNCOPERATION_H_INCLUDED - -/** Base class for creating composed asynchronous operations. - The composed operation will have its operator() overloads called with - the same context and execution safety guarantees as the original - SharedHandler. -*/ -class ComposedAsyncOperation : public SharedHandler -{ -protected: - /** Construct the composed operation. - The composed operation will execute in the context of the - SharedHandler. A reference to the SharedHandler is maintained - for the lifetime of the composed operation. - */ - explicit ComposedAsyncOperation (SharedHandlerPtr const& ptr) - : m_ptr (ptr) - { - // Illegal to do anything with handler here, because - // usually it hasn't been assigned by the derived class yet. - } - - ~ComposedAsyncOperation () - { - } - - void invoke (invoked_type& invoked) - { - boost_asio_handler_invoke_helpers:: - invoke (invoked, *m_ptr); - } - - void* allocate (std::size_t size) - { - return boost_asio_handler_alloc_helpers:: - allocate (size, *m_ptr); - } - - void deallocate (void* p, std::size_t size) - { - boost_asio_handler_alloc_helpers:: - deallocate (p, size, *m_ptr); - } - - /** Override this function as needed. - Usually you will logical-and your own continuation condition. In - the following example, isContinuing is a derived class member: - - @code - - bool derived::is_continuation () - { - bool const ourResult = this->isContinuing () - return ourResult || ComposedAsyncOperation ::is_contiation (); - } - - @endcode - */ - bool is_continuation () - { -#if BEAST_ASIO_HAS_CONTINUATION_HOOKS - return boost_asio_handler_cont_helpers:: - is_continuation (*m_ptr); -#else - return false; -#endif - } - - void destroy () const - { - delete this; - } - -private: - SharedHandlerPtr const m_ptr; -}; - -#endif diff --git a/src/beast/modules/beast_asio/async/SharedHandler.h b/src/beast/modules/beast_asio/async/SharedHandler.h deleted file mode 100644 index ea962655325..00000000000 --- a/src/beast/modules/beast_asio/async/SharedHandler.h +++ /dev/null @@ -1,108 +0,0 @@ -//------------------------------------------------------------------------------ -/* - This file is part of Beast: https://github.com/vinniefalco/Beast - Copyright 2013, Vinnie Falco - - Permission to use, copy, modify, and/or distribute this software for any - purpose with or without fee is hereby granted, provided that the above - copyright notice and this permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -*/ -//============================================================================== - -#ifndef BEAST_ASIO_ASYNC_SHAREDHANDLER_H_INCLUDED -#define BEAST_ASIO_ASYNC_SHAREDHANDLER_H_INCLUDED - -template -struct SharedHandlerAllocator; - -/** Reference counted wrapper that can hold any other boost::asio handler. - - This object will match these signatures: - - @code - - void (void) - void (system::error_code) - void (system::error_code, std::size_t) - - @endcode - - If the underlying implementation does not support the signature, - undefined behavior will result. - - Supports these concepts: - Destructible -*/ -class SharedHandler : public SharedObject -{ -protected: - typedef boost::system::error_code error_code; - - typedef SharedFunction > invoked_type; - - SharedHandler () noexcept { } - -public: - // For asio::async_result<> - typedef void result_type; - - typedef SharedPtr Ptr; - - virtual void operator() (); - virtual void operator() (error_code const&); - virtual void operator() (error_code const&, std::size_t); - - template - void invoke (BEAST_MOVE_ARG(Function) f); - - virtual void invoke (invoked_type& invoked) = 0; - virtual void* allocate (std::size_t size) = 0; - virtual void deallocate (void* p, std::size_t size) = 0; - virtual bool is_continuation () = 0; - - static void pure_virtual_called (char const* fileName, int lineNumber); - -private: - template - friend void asio_handler_invoke (BOOST_ASIO_MOVE_ARG(Function) f, SharedHandler*); - friend void* asio_handler_allocate (std::size_t, SharedHandler*); - friend void asio_handler_deallocate (void*, std::size_t, SharedHandler*); - friend bool asio_handler_is_continuation (SharedHandler*); -}; - -//-------------------------------------------------------------------------- -// -// Context execution guarantees -// - -template -void asio_handler_invoke (BOOST_ASIO_MOVE_ARG(Function) f, SharedHandler* handler) -{ - handler->invoke (BOOST_ASIO_MOVE_CAST(Function)(f)); -} - -inline void* asio_handler_allocate (std::size_t size, SharedHandler* handler) -{ - return handler->allocate (size); -} - -inline void asio_handler_deallocate (void* p, std::size_t size, SharedHandler* handler) -{ - handler->deallocate (p, size); -} - -inline bool asio_handler_is_continuation (SharedHandler* handler) -{ - return handler->is_continuation (); -} - -#endif diff --git a/src/beast/modules/beast_asio/async/SharedHandlerAllocator.h b/src/beast/modules/beast_asio/async/SharedHandlerAllocator.h deleted file mode 100644 index 787beebbffc..00000000000 --- a/src/beast/modules/beast_asio/async/SharedHandlerAllocator.h +++ /dev/null @@ -1,123 +0,0 @@ -//------------------------------------------------------------------------------ -/* - This file is part of Beast: https://github.com/vinniefalco/Beast - Copyright 2013, Vinnie Falco - - Permission to use, copy, modify, and/or distribute this software for any - purpose with or without fee is hereby granted, provided that the above - copyright notice and this permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -*/ -//============================================================================== - -#ifndef BEAST_ASIO_ASYNC_SHAREDHANDLERALLOCATOR_H_INCLUDED -#define BEAST_ASIO_ASYNC_SHAREDHANDLERALLOCATOR_H_INCLUDED - -/** Custom Allocator using the allocation hooks from the Handler. - - This class is compatible with std::allocator and can be used in any - boost interface which takes a template parameter of type Allocator. - This includes std::function and especially boost::asio::streambuf - and relatives. This is vastly more efficient in a variety of situations - especially during an upcall and when using stackful coroutines. - - The Allocator holds a reference to the underlying SharedHandler. The - SharedHandler will not be destroyed as long as any Allocator is still - using it. -*/ -template -struct SharedHandlerAllocator -{ - typedef T value_type; - typedef T* pointer; - typedef T& reference; - typedef T const* const_pointer; - typedef T const& const_reference; - typedef std::size_t size_type; - typedef std::ptrdiff_t difference_type; - - SharedHandlerAllocator (SharedHandler* handler) noexcept - : m_ptr (handler) - { - } - - SharedHandlerAllocator (SharedHandlerPtr const& handler) noexcept - : m_ptr (handler) - { - } - - template - SharedHandlerAllocator (SharedHandlerAllocator const& other) - : m_ptr (other.m_ptr) - { - } - - template - struct rebind - { - typedef SharedHandlerAllocator other; - }; - - pointer address (reference x) const - { - return &x; - } - - const_pointer address (const_reference x) const - { - return &x; - } - - pointer allocate (size_type n) const - { - size_type const bytes = n * sizeof (value_type); - return static_cast (m_ptr->allocate (bytes)); - } - - void deallocate (pointer p, size_type n) const - { - size_type const bytes = n * sizeof (value_type); - m_ptr->deallocate (p, bytes); - } - - size_type max_size () const noexcept - { - return std::numeric_limits ::max () / sizeof (value_type); - } - - void construct (pointer p, const_reference val) const - { - new ((void *)p) value_type (val); - } - - void destroy (pointer p) const - { - p->~value_type (); - } - -private: - template - friend struct SharedHandlerAllocator; - friend class SharedHandler; - - SharedHandlerPtr m_ptr; -}; - -//------------------------------------------------------------------------------ -template -void SharedHandler::invoke (BEAST_MOVE_ARG(Function) f) -{ - // The allocator will hold a reference to the SharedHandler - // so that we can safely destroy the function object. - invoked_type invoked (f,SharedHandlerAllocator (this)); - invoke (invoked); -} - -#endif diff --git a/src/beast/modules/beast_asio/async/SharedHandlerPtr.h b/src/beast/modules/beast_asio/async/SharedHandlerPtr.h deleted file mode 100644 index b2ef86e441c..00000000000 --- a/src/beast/modules/beast_asio/async/SharedHandlerPtr.h +++ /dev/null @@ -1,326 +0,0 @@ -//------------------------------------------------------------------------------ -/* - This file is part of Beast: https://github.com/vinniefalco/Beast - Copyright 2013, Vinnie Falco - - Permission to use, copy, modify, and/or distribute this software for any - purpose with or without fee is hereby granted, provided that the above - copyright notice and this permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -*/ -//============================================================================== - -#ifndef BEAST_ASIO_ASYNC_SHAREDHANDLERPTR_H_INCLUDED -#define BEAST_ASIO_ASYNC_SHAREDHANDLERPTR_H_INCLUDED - -/** RAII container for a SharedHandler. - - This object behaves exactly like a SharedHandler except that it - merely contains a shared pointer to the underlying SharedHandler. - All calls are forwarded to the underlying SharedHandler, and all - of the execution safety guarantees are met by forwarding them through - to the underlying SharedHandler. -*/ -class SharedHandlerPtr -{ -protected: - typedef boost::system::error_code error_code; - -public: - // For asio::async_result<> - typedef void result_type; - - /** Construct a null handler. - A null handler cannot be called. It can, however, be checked - for validity by calling isNull, and later assigned. - - @see isNull, isNotNull - */ - inline SharedHandlerPtr () - { - } - - /** Construct from an existing SharedHandler. - Ownership of the handler is transferred to the container. - */ - inline SharedHandlerPtr (SharedHandler* handler) - : m_ptr (handler) - { - } - - /** Construct a reference from an existing container. */ - inline SharedHandlerPtr (SharedHandlerPtr const& other) - : m_ptr (other.m_ptr) - { - } - - /** Assign a reference from an existing container. */ - inline SharedHandlerPtr& operator= (SharedHandlerPtr const& other) - { - m_ptr = other.m_ptr; - return *this; - } - -#if BEAST_COMPILER_SUPPORTS_MOVE_SEMANTICS - /** Move-construct a reference from an existing container. - The other container is set to a null handler. - */ - inline SharedHandlerPtr (SharedHandlerPtr&& other) - : m_ptr (other.m_ptr) - { - other.m_ptr = nullptr; - } - - /** Move-assign a reference from an existing container. - The other container is set to a null handler. - */ - inline SharedHandlerPtr& operator= (SharedHandlerPtr&& other) - { - m_ptr = other.m_ptr; - other.m_ptr = nullptr; - return *this; - } -#endif - - /** Returns true if the handler is a null handler. */ - inline bool isNull () const - { - return m_ptr == nullptr; - } - - /** Returns true if the handler is not a null handler. */ - inline bool isNotNull () const - { - return m_ptr != nullptr; - } - - /** Dereference the container. - This returns a reference to the underlying SharedHandler object. - */ - inline SharedHandler& operator* () const - { - return *m_ptr; - } - - /** SharedHandler member access. - This lets you call functions directly on the SharedHandler. - */ - inline SharedHandler* operator-> () const - { - return m_ptr.get (); - } - - /** Retrieve the SharedHandler as a Context. - - This can be used for invoking functions in the context: - - @code - - template - void callOnHandler (Function f, SharedHandlerPtr ptr) - { - boost::asio_handler_invoke (f, ptr.get ()); - } - - @endcode - */ - inline SharedHandler* get () const - { - return m_ptr.get (); - } - - /** Invoke the SharedHandler with signature void(void) - Normally this is called by a dispatcher, you shouldn't call it directly. - */ - inline void operator() () const - { - (*m_ptr)(); - } - - /** Invoke the SharedHandler with signature void(error_code) - Normally this is called by a dispatcher, you shouldn't call it directly. - */ - inline void operator() (error_code const& ec) const - { - (*m_ptr)(ec); - } - - /** Invoke the SharedHandler with signature void(error_code, size_t) - Normally this is called by a dispatcher, you shouldn't call it directly. - */ - inline void operator() (error_code const& ec, std::size_t bytes_transferred) const - { - (*m_ptr)(ec, bytes_transferred); - } - -private: - // These ensure that SharedHandlerPtr invocations adhere to - // the asio::io_service execution guarantees of the underlying SharedHandler. - // - template - friend void asio_handler_invoke (BOOST_ASIO_MOVE_ARG(Function) f, SharedHandlerPtr*); - friend void* asio_handler_allocate (std::size_t, SharedHandlerPtr*); - friend void asio_handler_deallocate (void*, std::size_t, SharedHandlerPtr*); - friend bool asio_handler_is_continuation (SharedHandlerPtr*); - - SharedHandler::Ptr m_ptr; -}; - -//-------------------------------------------------------------------------- -// -// Context execution guarantees -// - -template -void asio_handler_invoke (BOOST_ASIO_MOVE_ARG(Function) f, SharedHandlerPtr* ptr) -{ - boost_asio_handler_invoke_helpers:: - invoke - (BOOST_ASIO_MOVE_CAST(Function)(f), *ptr->get ()); -} - -inline void* asio_handler_allocate (std::size_t size, SharedHandlerPtr* ptr) -{ - return boost_asio_handler_alloc_helpers:: - allocate (size, *ptr->get ()); -} - -inline void asio_handler_deallocate (void* p, std::size_t size, SharedHandlerPtr* ptr) -{ - boost_asio_handler_alloc_helpers:: - deallocate (p, size, *ptr->get ()); -} - -inline bool asio_handler_is_continuation (SharedHandlerPtr* ptr) -{ -#if BEAST_ASIO_HAS_CONTINUATION_HOOKS - return boost_asio_handler_cont_helpers:: - is_continuation (*ptr->get ()); -#else - return false; -#endif -} - -//-------------------------------------------------------------------------- -// -// Helpers -// -//-------------------------------------------------------------------------- - -// void(error_code) -template -SharedHandlerPtr newErrorHandler ( - BOOST_ASIO_MOVE_ARG(Handler) handler) -{ - return newSharedHandlerContainer ( - BOOST_ASIO_MOVE_CAST(Handler)(handler)); -} - -// void(error_code, size_t) -template -SharedHandlerPtr newTransferHandler ( - BOOST_ASIO_MOVE_ARG(Handler) handler) -{ - return newSharedHandlerContainer ( - BOOST_ASIO_MOVE_CAST(Handler)(handler)); -} - -//-------------------------------------------------------------------------- - -// CompletionHandler -// -// http://www.boost.org/doc/libs/1_54_0/doc/html/boost_asio/reference/CompletionHandler.html -// -template -SharedHandlerPtr newCompletionHandler ( - BOOST_ASIO_MOVE_ARG(CompletionHandler) handler) -{ - return newSharedHandlerContainer ( - BOOST_ASIO_MOVE_CAST(CompletionHandler)(handler)); -} - -// AcceptHandler -// http://www.boost.org/doc/libs/1_54_0/doc/html/boost_asio/reference/AcceptHandler.html -// -template -SharedHandlerPtr newAcceptHandler ( - BOOST_ASIO_MOVE_ARG(AcceptHandler) handler) -{ - return newSharedHandlerContainer ( - BOOST_ASIO_MOVE_CAST(AcceptHandler)(handler)); -} - -// ConnectHandler -// http://www.boost.org/doc/libs/1_54_0/doc/html/boost_asio/reference/ConnectHandler.html -// -template -SharedHandlerPtr newConnectHandler ( - BOOST_ASIO_MOVE_ARG(ConnectHandler) handler) -{ - return newSharedHandlerContainer ( - BOOST_ASIO_MOVE_CAST(ConnectHandler)(handler)); -} - -// ShutdownHandler -// http://www.boost.org/doc/libs/1_54_0/doc/html/boost_asio/reference/ShutdownHandler.html -// -template -SharedHandlerPtr newShutdownHandler( - BOOST_ASIO_MOVE_ARG(ShutdownHandler) handler) -{ - return newSharedHandlerContainer ( - BOOST_ASIO_MOVE_CAST(ShutdownHandler)(handler)); -} - -// HandshakeHandler -// http://www.boost.org/doc/libs/1_54_0/doc/html/boost_asio/reference/HandshakeHandler.html -// -template -SharedHandlerPtr newHandshakeHandler( - BOOST_ASIO_MOVE_ARG(HandshakeHandler) handler) -{ - return newSharedHandlerContainer ( - BOOST_ASIO_MOVE_CAST(HandshakeHandler)(handler)); -} - -// ReadHandler -// http://www.boost.org/doc/libs/1_54_0/doc/html/boost_asio/reference/ReadHandler.html -// -template -SharedHandlerPtr newReadHandler( - BOOST_ASIO_MOVE_ARG(ReadHandler) handler) -{ - return newSharedHandlerContainer ( - BOOST_ASIO_MOVE_CAST(ReadHandler)(handler)); -} - -// WriteHandler -// http://www.boost.org/doc/libs/1_54_0/doc/html/boost_asio/reference/WriteHandler.html -// -template -SharedHandlerPtr newWriteHandler( - BOOST_ASIO_MOVE_ARG(WriteHandler) handler) -{ - return newSharedHandlerContainer ( - BOOST_ASIO_MOVE_CAST(WriteHandler)(handler)); -} - -// BufferedHandshakeHandler -// http://www.boost.org/doc/libs/1_54_0/doc/html/boost_asio/reference/BufferedHandshakeHandler.html -// -template -SharedHandlerPtr newBufferedHandshakeHandler( - BOOST_ASIO_MOVE_ARG(BufferedHandshakeHandler) handler) -{ - return newSharedHandlerContainer ( - BOOST_ASIO_MOVE_CAST(BufferedHandshakeHandler)(handler)); -} - -#endif diff --git a/src/beast/modules/beast_asio/async/SharedHandlerType.h b/src/beast/modules/beast_asio/async/SharedHandlerType.h deleted file mode 100644 index 7ff937962c9..00000000000 --- a/src/beast/modules/beast_asio/async/SharedHandlerType.h +++ /dev/null @@ -1,211 +0,0 @@ -//------------------------------------------------------------------------------ -/* - This file is part of Beast: https://github.com/vinniefalco/Beast - Copyright 2013, Vinnie Falco - - Permission to use, copy, modify, and/or distribute this software for any - purpose with or without fee is hereby granted, provided that the above - copyright notice and this permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -*/ -//============================================================================== - -#ifndef BEAST_ASIO_ASYNC_SHAREDHANDLERTYPE_H_INCLUDED -#define BEAST_ASIO_ASYNC_SHAREDHANDLERTYPE_H_INCLUDED - -/** An instance of SharedHandler that wraps an existing Handler. - The wrapped handler will meet all the execution guarantees of - the original Handler object. -*/ -template -class SharedHandlerType : public SharedHandler -{ -protected: - SharedHandlerType (std::size_t size, - BOOST_ASIO_MOVE_ARG(Handler) handler) - : m_size (size) - , m_handler (BOOST_ASIO_MOVE_CAST(Handler)(handler)) - { - } - - ~SharedHandlerType () - { - - } - - void invoke (invoked_type& invoked) - { - boost_asio_handler_invoke_helpers:: - invoke (invoked, m_handler); - } - - void* allocate (std::size_t size) - { - return boost_asio_handler_alloc_helpers:: - allocate (size, m_handler); - } - - void deallocate (void* p, std::size_t size) - { - boost_asio_handler_alloc_helpers:: - deallocate (p, size, m_handler); - } - - bool is_continuation () - { -#if BEAST_ASIO_HAS_CONTINUATION_HOOKS - return boost_asio_handler_cont_helpers:: - is_continuation (m_handler); -#else - return false; -#endif - } - - // Called by SharedObject hook to destroy the object. We need - // this because we allocated it using a custom allocator. - // Destruction is tricky, the algorithm is as follows: - // - // First we move-assign the handler to our stack. If the build - // doesn't support move-assignment it will be a copy, still ok. - // We convert 'this' to a pointer to the polymorphic base, to - // ensure that the following direct destructor call will reach - // the most derived class. Finally, we deallocate the memory - // using the handler that is local to the stack. - // - // For this to work we need to make sure regular operator delete - // is never called for our object (it's private). We also need - // the size from the original allocation, which we saved at - // the time of construction. - // - void destroy () const - { - Handler local (BOOST_ASIO_MOVE_CAST(Handler)(m_handler)); - std::size_t const size (m_size); - SharedHandler* const shared ( - const_cast ( - static_cast (this))); - shared->~SharedHandler (); - boost_asio_handler_alloc_helpers:: - deallocate (shared, size, local); - } - -protected: - std::size_t const m_size; - Handler mutable m_handler; -}; - -//-------------------------------------------------------------------------- -// -// A SharedHandlerType for this signature: -// void(void) -// -template -class PostSharedHandlerType : public SharedHandlerType -{ -public: - PostSharedHandlerType (std::size_t size, - BOOST_ASIO_MOVE_ARG(Handler) handler) - : SharedHandlerType (size, - BOOST_ASIO_MOVE_CAST(Handler)(handler)) - { - } - -protected: - void operator() () - { - this->m_handler (); - } -}; - -//-------------------------------------------------------------------------- -// -// A SharedHandlerType for this signature: -// void(error_code) -// -template -class ErrorSharedHandlerType : public SharedHandlerType -{ -public: - ErrorSharedHandlerType (std::size_t size, - BOOST_ASIO_MOVE_ARG(Handler) handler) - : SharedHandlerType (size, - BOOST_ASIO_MOVE_CAST(Handler)(handler)) - { - } - -protected: - void operator() (boost::system::error_code const& ec) - { - this->m_handler (ec); - } -}; - -//-------------------------------------------------------------------------- -// -// A SharedHandlerType for this signature: -// void(error_code, size_t) -// -template -class TransferSharedHandlerType : public SharedHandlerType -{ -public: - TransferSharedHandlerType (std::size_t size, - BOOST_ASIO_MOVE_ARG(Handler) handler) - : SharedHandlerType (size, - BOOST_ASIO_MOVE_CAST(Handler)(handler)) - { - } - -protected: - void operator() (boost::system::error_code const& ec, - std::size_t bytes_transferred) - { - this->m_handler (ec, bytes_transferred); - } -}; - -//-------------------------------------------------------------------------- -// -// These specializations will make sure we don't do -// anything silly like wrap ourselves in our own wrapper... -// -#if 1 -template <> -class PostSharedHandlerType -{ -}; - -template <> -class ErrorSharedHandlerType -{ -}; -template <> -class TransferSharedHandlerType -{ -}; -#endif - - -//-------------------------------------------------------------------------- - -/** Construct a wrapped handler using the context's allocation hooks. -*/ -template