Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

boost::beast::ssl_stream::async_handshake() doesn't accept cti::use_continuable #52

Open
Spongman opened this issue Sep 3, 2022 · 4 comments
Labels

Comments

@Spongman
Copy link

Spongman commented Sep 3, 2022

@Naios

boost::beast::ssl_stream<boost::beast::tcp_stream>* stream;
const auto f = stream->async_handshake(boost::asio::ssl::stream_base::client, boost::asio::use_future); // compiles
const auto g = stream->async_handshake(boost::asio::ssl::stream_base::client, cti::use_continuable); // error
---
error: no matching function for call to 'boost::beast::ssl_stream<boost::beast::basic_stream<boost::asio::ip::tcp, boost::asio::any_io_executor, boost::beast::unlimited_rate_policy> >::async_handshake(boost::asio::ssl::stream_base::handshake_type, const cti::use_continuable_t<>&)'
  143 |    const auto g = stream->async_handshake(boost::asio::ssl::stream_base::client, cti::use_continuable);

it works fine with other boost & beast APIs.

Commit Hash

6bffb44 (4.1.0 release)

  • OS: CentOS7
  • Compiler and version: gcc (GCC) 10.2.1 20210130 (Red Hat 10.2.1-11)
  • boost 1.77.0 release
@Spongman Spongman changed the title boost::beast::ssl_stream doesn't accept cti::use_continuable boost::beast::ssl_stream::async_handshake() doesn't accept cti::use_continuable Sep 3, 2022
@Spongman
Copy link
Author

Spongman commented Sep 3, 2022

I notice that the deduction for async_handshake is different than that for, say, async_connect

    template<class HandshakeHandler>
    BOOST_ASIO_INITFN_RESULT_TYPE(HandshakeHandler, void(boost::system::error_code))
    async_handshake(handshake_type type,
        BOOST_ASIO_MOVE_ARG(HandshakeHandler) handler)

vs.

template <typename Protocol, typename Executor, typename Iterator,
    BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
      Iterator)) IteratorConnectHandler>
inline BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(IteratorConnectHandler,
    void (boost::system::error_code, Iterator))
async_connect(basic_socket<Protocol, Executor>& s, Iterator begin, Iterator end,
    BOOST_ASIO_MOVE_ARG(IteratorConnectHandler) handler)

that's all a little beyond me.

that doesn't explain, however, why it works for use_future and not use_continuable.

@Naios Naios added the bug label Sep 3, 2022
@Naios
Copy link
Owner

Naios commented Sep 3, 2022

Thank your for your report. I was able to reproduce this issue (on boost 1.80). I'm not entirely sure yet, what is causing this.

@Naios
Copy link
Owner

Naios commented Sep 3, 2022

I found the reason for this issue:

Since boost:::asio 1.72 or asio (standalone) 1.16 the async_result trait used for creating the promise type does not require a fixed type anymore. Before that we had to return a fixed type independent of the promise initiation. This makes it possible to return a non-allocating continuable that depends on the promise Initiation.

See

template <typename Signature, typename Matcher>
class async_result<cti::use_continuable_t<Matcher>, Signature> {
public:
#if defined(CTI_DETAIL_ASIO_HAS_EXPLICIT_RET_TYPE_INTEGRATION)
  using return_type = typename cti::detail::asio::initiate_make_continuable<
      Signature>::erased_return_type;
#endif

The async_handshake method uses BOOST_ASIO_INITFN_RESULT_TYPE for deducing the promise type. As far as I know this should be replaced with BOOST_ASIO_INITFN_AUTO_RESULT_TYPE to auto-deduce the result. Asio only keeps the old explicit define for backwards compatibility: https://github.com/boostorg/asio/search?q=BOOST_ASIO_INITFN_RESULT_TYPE .

I would suggest that you ask at boostorg/beast whether they can auto-replace BOOST_ASIO_INITFN_RESULT_TYPE by BOOST_ASIO_INITFN_AUTO_RESULT_TYPE or if there is a reason why they are still using the old define.
If this is not possible I might consider implementing an alternative token.

As workaround you can temporarily define CTI_DETAIL_ASIO_HAS_EXPLICIT_RET_TYPE_INTEGRATION that enables the asyn_result<>::return_type, but this leads to performance disadvantages.


For reference see:

template <typename Signature, typename Matcher>
class async_result<cti::use_continuable_t<Matcher>, Signature> {
public:
#if defined(CTI_DETAIL_ASIO_HAS_EXPLICIT_RET_TYPE_INTEGRATION)
using return_type = typename cti::detail::asio::initiate_make_continuable<
Signature>::erased_return_type;
#endif
template <typename Initiation, typename... Args>
static auto initiate(Initiation initiation,
cti::use_continuable_t<Matcher> token, Args... args) {
return cti::detail::asio::initiate_make_continuable<Signature>{}(
[initiation = std::move(initiation), token = std::move(token),
init_args = std::make_tuple(std::move(args)...)](
auto&& promise) mutable {
cti::detail::traits::unpack(
[initiation = std::move(initiation),
handler = cti::detail::asio::promise_resolver_handler(
std::forward<decltype(promise)>(promise), std::move(token))](
auto&&... args) mutable {
std::move(initiation)(std::move(handler),
std::forward<decltype(args)>(args)...);
},
std::move(init_args));
});
}
};

@uohmak4fvpqe
Copy link

I am having seemingly the same issue, both with async_connect and (ssl) async_handshake.
I am prone to ask the beast guys if you need me to do it but isn't that possible that you do it instead as you probably know better how tell them propery ?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants