Skip to content

Commit 713d192

Browse files
committed
Support CompletionToken instead of CompletionHandler
1 parent d426258 commit 713d192

File tree

4 files changed

+42
-89
lines changed

4 files changed

+42
-89
lines changed

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ Boost::ASIO low-level redis client (connector),
1919
- works on linux (clang, gcc) and windows (msvc)
2020
- synchronous & asynchronous interface
2121
- inspired by [beast](https://github.com/vinniefalco/Beast)
22-
- requirements: boost `v1.69` minimum
22+
- requirements: boost `v1.70` minimum
2323

2424
## Changelog
2525

@@ -781,6 +781,7 @@ MIT
781781
- [Ronny Nowak](https://github.com/dargun)
782782
- [Stephen Chisholm](https://github.com/sbchisholm)
783783
- [amensel](https://github.com/amensel)
784+
- [Usevalad Sauta](https://github.com/VsevolodSauta)
784785

785786
## See also
786787
- https://github.com/Cylix/cpp_redis

include/bredis/Connection.hpp

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -44,19 +44,19 @@ template <typename NextLayer> class Connection {
4444
inline const NextLayer &next_layer() const { return stream_; }
4545

4646
/* asynchronous interface */
47-
template <typename DynamicBuffer, typename WriteCallback>
48-
BOOST_ASIO_INITFN_RESULT_TYPE(WriteCallback,
47+
template <typename DynamicBuffer, typename CompletionToken>
48+
BOOST_ASIO_INITFN_RESULT_TYPE(CompletionToken,
4949
void(boost::system::error_code, std::size_t))
5050
async_write(DynamicBuffer &tx_buff, const command_wrapper_t &command,
51-
WriteCallback &&write_callback);
51+
CompletionToken &&completion_token);
5252

53-
template <typename DynamicBuffer, typename ReadCallback,
53+
template <typename DynamicBuffer, typename CompletionToken,
5454
typename Policy = bredis::parsing_policy::keep_result>
55-
BOOST_ASIO_INITFN_RESULT_TYPE(ReadCallback,
55+
BOOST_ASIO_INITFN_RESULT_TYPE(CompletionToken,
5656
void(boost::system::error_code,
5757
BREDIS_PARSE_RESULT(DynamicBuffer,
5858
Policy)))
59-
async_read(DynamicBuffer &rx_buff, ReadCallback &&read_callback,
59+
async_read(DynamicBuffer &rx_buff, CompletionToken &&completion_token,
6060
std::size_t replies_count = 1, Policy policy = Policy{});
6161

6262
/* synchronous interface */

include/bredis/impl/async_op.ipp

Lines changed: 23 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -111,16 +111,19 @@ struct result_visitor_t<Iterator, parsing_policy::keep_result>
111111
}
112112
};
113113

114-
template <typename DynamicBuffer, typename Policy> struct async_read_op_impl {
114+
template <typename NextLayer, typename DynamicBuffer, typename Policy> struct async_read_op_impl {
115+
NextLayer &stream_;
115116
DynamicBuffer &rx_buff_;
116117
std::size_t replies_count_;
118+
enum class state_t { init, read, done } state_ = state_t::init;
117119

118-
async_read_op_impl(DynamicBuffer &rx_buff, std::size_t replies_count)
119-
: rx_buff_{rx_buff}, replies_count_{replies_count} {}
120120
using Iterator = typename to_iterator<DynamicBuffer>::iterator_t;
121121
using ResultVisitor = result_visitor_t<Iterator, Policy>;
122122
using positive_result_t = parse_result_mapper_t<Iterator, Policy>;
123123

124+
async_read_op_impl(NextLayer &stream, DynamicBuffer &rx_buff, std::size_t replies_count) :
125+
stream_(stream), rx_buff_(rx_buff), replies_count_(replies_count) {}
126+
124127
positive_result_t op(boost::system::error_code &error_code,
125128
std::size_t /*bytes_transferred*/) {
126129

@@ -149,53 +152,25 @@ template <typename DynamicBuffer, typename Policy> struct async_read_op_impl {
149152
}
150153
return result;
151154
}
152-
};
153-
154-
template <typename NextLayer, typename DynamicBuffer, typename ReadCallback,
155-
typename Policy>
156-
class async_read_op {
157-
NextLayer &stream_;
158-
DynamicBuffer &rx_buff_;
159-
std::size_t replies_count_;
160-
ReadCallback callback_;
161-
162-
public:
163-
async_read_op(async_read_op &&) = default;
164-
async_read_op(const async_read_op &) = default;
165-
166-
template <class DeducedHandler>
167-
async_read_op(DeducedHandler &&deduced_handler, NextLayer &stream,
168-
DynamicBuffer &rx_buff, std::size_t replies_count)
169-
: stream_(stream), rx_buff_(rx_buff), replies_count_(replies_count),
170-
callback_(std::forward<ReadCallback>(deduced_handler)) {}
171155

172-
void operator()(boost::system::error_code, std::size_t bytes_transferred);
173-
174-
friend bool asio_handler_is_continuation(async_read_op *op) {
175-
using boost::asio::asio_handler_is_continuation;
176-
return asio_handler_is_continuation(std::addressof(op->callback_));
177-
}
178-
179-
boost::asio::associated_allocator_t<ReadCallback> get_allocator() const noexcept
180-
{
181-
return boost::asio::get_associated_allocator(callback_);
182-
}
183-
184-
boost::asio::associated_executor_t<ReadCallback> get_executor() const noexcept
185-
{
186-
return boost::asio::get_associated_executor(callback_);
156+
template<typename Self>
157+
void operator()(Self& self, boost::system::error_code error_code = {}, std::size_t bytes_transferred = {}) {
158+
switch (state_) {
159+
case state_t::init:
160+
state_ = state_t::read;
161+
async_read_until(stream_, rx_buff_, MatchResult<Iterator>(replies_count_), std::move(self));
162+
break;
163+
case state_t::read:
164+
{
165+
state_ = state_t::done;
166+
auto result = op(error_code, bytes_transferred); // Do not inline! We are sequencing computations
167+
self.complete(error_code, result);
168+
break;
169+
}
170+
default:
171+
assert(false && "We are in unexpected state");
172+
}
187173
}
188174
};
189175

190-
template <typename NextLayer, typename DynamicBuffer, typename ReadCallback,
191-
typename Policy>
192-
void async_read_op<NextLayer, DynamicBuffer, ReadCallback, Policy>::
193-
operator()(boost::system::error_code error_code,
194-
std::size_t bytes_transferred) {
195-
using op_impl = async_read_op_impl<DynamicBuffer, Policy>;
196-
callback_(
197-
error_code,
198-
op_impl(rx_buff_, replies_count_).op(error_code, bytes_transferred));
199-
}
200-
201176
} // namespace bredis

include/bredis/impl/connection.ipp

Lines changed: 11 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -18,60 +18,37 @@
1818
namespace bredis {
1919

2020
template <typename NextLayer>
21-
template <typename DynamicBuffer, typename WriteCallback>
22-
BOOST_ASIO_INITFN_RESULT_TYPE(WriteCallback,
21+
template <typename DynamicBuffer, typename CompletionToken>
22+
BOOST_ASIO_INITFN_RESULT_TYPE(CompletionToken,
2323
void(boost::system::error_code, std::size_t))
2424
Connection<NextLayer>::async_write(DynamicBuffer &tx_buff,
2525
const command_wrapper_t &command,
26-
WriteCallback &&write_callback) {
26+
CompletionToken &&write_callback) {
2727
namespace asio = boost::asio;
2828
namespace sys = boost::system;
2929

3030
using boost::asio::async_write;
31-
using Signature = void(boost::system::error_code, std::size_t);
32-
using Callback = boost::decay_t<WriteCallback>;
33-
using AsyncResult = asio::async_result<Callback, Signature>;
34-
using CompletionHandler = typename AsyncResult::completion_handler_type;
3531
using serializer_t = command_serializer_visitor<DynamicBuffer>;
3632

3733
boost::apply_visitor(serializer_t(tx_buff), command);
38-
39-
CompletionHandler handler(std::forward<WriteCallback>(write_callback));
40-
AsyncResult result(handler);
41-
async_write(stream_, tx_buff, std::move(handler));
42-
return result.get();
34+
return async_write(stream_, tx_buff, std::forward<CompletionToken>(write_callback));
4335
}
4436

4537
template <typename NextLayer>
46-
template <typename DynamicBuffer, typename ReadCallback, typename Policy>
47-
BOOST_ASIO_INITFN_RESULT_TYPE(ReadCallback,
48-
void(const boost::system::error_code,
38+
template <typename DynamicBuffer, typename CompletionToken, typename Policy>
39+
BOOST_ASIO_INITFN_RESULT_TYPE(CompletionToken,
40+
void(boost::system::error_code,
4941
BREDIS_PARSE_RESULT(DynamicBuffer, Policy)))
5042
Connection<NextLayer>::async_read(DynamicBuffer &rx_buff,
51-
ReadCallback &&read_callback,
43+
CompletionToken &&completion_token,
5244
std::size_t replies_count, Policy) {
53-
54-
namespace asio = boost::asio;
55-
namespace sys = boost::system;
56-
5745
using boost::asio::async_read_until;
58-
using Iterator = typename to_iterator<DynamicBuffer>::iterator_t;
5946
using ParseResult = BREDIS_PARSE_RESULT(DynamicBuffer, Policy);
6047
using Signature = void(boost::system::error_code, ParseResult);
61-
using Callback = boost::decay_t<ReadCallback>;
62-
using AsyncResult = asio::async_result<Callback, Signature>;
63-
using CompletionHandler = typename AsyncResult::completion_handler_type;
64-
using ReadOp =
65-
async_read_op<NextLayer, DynamicBuffer, CompletionHandler, Policy>;
66-
67-
CompletionHandler handler(std::forward<ReadCallback>(read_callback));
68-
AsyncResult result(handler);
69-
70-
ReadOp async_op(std::move(handler), stream_, rx_buff, replies_count);
7148

72-
async_read_until(stream_, rx_buff, MatchResult<Iterator>(replies_count),
73-
std::move(async_op));
74-
return result.get();
49+
return boost::asio::async_compose<CompletionToken, Signature>(
50+
async_read_op_impl<NextLayer, DynamicBuffer, Policy>{stream_, rx_buff, replies_count},
51+
completion_token, stream_);
7552
}
7653

7754
template <typename NextLayer>

0 commit comments

Comments
 (0)