};
#define CONTINUATION_DECL(C, F, ...) \
- std::unique_ptr<CtFun<C, ##__VA_ARGS__>> F##_cont_ = \
- std::make_unique<CtFun<C, ##__VA_ARGS__>>(&C::F); \
- CtFun<C, ##__VA_ARGS__> *F##_cont = F##_cont_.get()
+ CtFun<C, ##__VA_ARGS__> F##_cont { (&C::F) };
-#define CONTINUATION_PARAM(V, C, ...) CtFun<C, ##__VA_ARGS__> *V##_cont
+#define CONTINUATION_PARAM(V, C, ...) CtFun<C, ##__VA_ARGS__> &V##_cont
#define CONTINUATION(F) F##_cont
-#define CONTINUE(F, ...) F##_cont->setParams(__VA_ARGS__), F##_cont
+#define CONTINUE(F, ...) (F##_cont.setParams(__VA_ARGS__), &F##_cont)
#define CONTINUATION_RUN(CT) \
{ \
- Ct<std::remove_reference<decltype(*this)>::type> *_cont = CT; \
- while (_cont) { \
+ Ct<std::remove_reference<decltype(*this)>::type> *_cont = &CT;\
+ do { \
_cont = _cont->call(this); \
- } \
+ } while (_cont); \
}
#define READ_HANDLER_CONTINUATION_DECL(C, F) \
return !out_q.empty() || connection->is_queued();
}
-void ProtocolV1::run_continuation(CtPtr continuation) {
- CONTINUATION_RUN(continuation);
+void ProtocolV1::run_continuation(CtPtr pcontinuation) {
+ if (pcontinuation) {
+ CONTINUATION_RUN(*pcontinuation);
+ }
}
CtPtr ProtocolV1::read(CONTINUATION_PARAM(next, ProtocolV1, char *, int),
buffer = temp_buffer;
}
ssize_t r = connection->read(len, buffer,
- [CONTINUATION(next), this](char *buffer, int r) {
- CONTINUATION(next)->setParams(buffer, r);
+ [&CONTINUATION(next), this](char *buffer, int r) {
+ CONTINUATION(next).setParams(buffer, r);
CONTINUATION_RUN(CONTINUATION(next));
});
if (r <= 0) {
CtPtr ProtocolV1::write(CONTINUATION_PARAM(next, ProtocolV1, int),
bufferlist &buffer) {
- ssize_t r = connection->write(buffer, [CONTINUATION(next), this](int r) {
- CONTINUATION(next)->setParams(r);
+ ssize_t r = connection->write(buffer, [&CONTINUATION(next), this](int r) {
+ CONTINUATION(next).setParams(r);
CONTINUATION_RUN(CONTINUATION(next));
});
if (r <= 0) {
State state;
- void run_continuation(CtPtr continuation);
+ void run_continuation(CtPtr pcontinuation);
CtPtr read(CONTINUATION_PARAM(next, ProtocolV1, char *, int), int len,
char *buffer = nullptr);
CtPtr write(CONTINUATION_PARAM(next, ProtocolV1, int), bufferlist &bl);
using namespace ceph::msgr::v2;
using CtPtr = Ct<ProtocolV2> *;
+using CtRef = Ct<ProtocolV2> &;
-void ProtocolV2::run_continuation(CtPtr continuation) {
+void ProtocolV2::run_continuation(CtPtr pcontinuation) {
+ if (pcontinuation) {
+ run_continuation(*pcontinuation);
+ }
+}
+
+void ProtocolV2::run_continuation(CtRef continuation) {
try {
CONTINUATION_RUN(continuation)
} catch (const buffer::error &e) {
buffer = temp_buffer;
}
ssize_t r = connection->read(len, buffer,
- [CONTINUATION(next), this](char *buffer, int r) {
- CONTINUATION(next)->setParams(buffer, r);
+ [&CONTINUATION(next), this](char *buffer, int r) {
+ CONTINUATION(next).setParams(buffer, r);
run_continuation(CONTINUATION(next));
});
if (r <= 0) {
CONTINUATION_PARAM(next, ProtocolV2),
bufferlist &buffer) {
ssize_t r =
- connection->write(buffer, [CONTINUATION(next), desc, this](int r) {
+ connection->write(buffer, [&CONTINUATION(next), desc, this](int r) {
if (r < 0) {
ldout(cct, 1) << __func__ << " " << desc << " write failed r=" << r
<< " (" << cpp_strerror(r) << ")" << dendl;
global_seq = messenger->get_global_seq();
- return _banner_exchange(CONTINUATION(post_client_banner_exchange));
+ return _banner_exchange(&CONTINUATION(post_client_banner_exchange));
}
CtPtr ProtocolV2::post_client_banner_exchange() {
state = BANNER_ACCEPTING;
- return _banner_exchange(CONTINUATION(post_server_banner_exchange));
+ return _banner_exchange(&CONTINUATION(post_server_banner_exchange));
}
CtPtr ProtocolV2::post_server_banner_exchange() {
bool keepalive;
ostream &_conn_prefix(std::ostream *_dout);
- void run_continuation(Ct<ProtocolV2> *continuation);
+ void run_continuation(Ct<ProtocolV2> *pcontinuation);
+ void run_continuation(Ct<ProtocolV2> &continuation);
Ct<ProtocolV2> *read(CONTINUATION_PARAM(next, ProtocolV2, char *, int),
int len, char *buffer = nullptr);