aboutsummaryrefslogtreecommitdiffhomepage
path: root/include/grpcpp/impl/codegen/client_callback.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/grpcpp/impl/codegen/client_callback.h')
-rw-r--r--include/grpcpp/impl/codegen/client_callback.h32
1 files changed, 23 insertions, 9 deletions
diff --git a/include/grpcpp/impl/codegen/client_callback.h b/include/grpcpp/impl/codegen/client_callback.h
index 4d9579fd6a..66cf9b7754 100644
--- a/include/grpcpp/impl/codegen/client_callback.h
+++ b/include/grpcpp/impl/codegen/client_callback.h
@@ -255,10 +255,12 @@ class ClientCallbackReaderWriterImpl
void MaybeFinish() {
if (--callbacks_outstanding_ == 0) {
- reactor_->OnDone(finish_status_);
+ Status s = std::move(finish_status_);
+ auto* reactor = reactor_;
auto* call = call_.call();
this->~ClientCallbackReaderWriterImpl();
g_core_codegen_interface->grpc_call_unref(call);
+ reactor->OnDone(s);
}
}
@@ -268,6 +270,7 @@ class ClientCallbackReaderWriterImpl
// 2. Any read backlog
// 3. Recv trailing metadata, on_completion callback
// 4. Any write backlog
+ // 5. See if the call can finish (if other callbacks were triggered already)
started_ = true;
start_tag_.Set(call_.call(),
@@ -318,6 +321,7 @@ class ClientCallbackReaderWriterImpl
if (writes_done_ops_at_start_) {
call_.PerformOps(&writes_done_ops_);
}
+ MaybeFinish();
}
void Read(Response* msg) override {
@@ -410,8 +414,8 @@ class ClientCallbackReaderWriterImpl
CallbackWithSuccessTag read_tag_;
bool read_ops_at_start_{false};
- // Minimum of 2 outstanding callbacks to pre-register for start and finish
- std::atomic_int callbacks_outstanding_{2};
+ // Minimum of 3 callbacks to pre-register for StartCall, start, and finish
+ std::atomic_int callbacks_outstanding_{3};
bool started_{false};
};
@@ -450,10 +454,12 @@ class ClientCallbackReaderImpl
void MaybeFinish() {
if (--callbacks_outstanding_ == 0) {
- reactor_->OnDone(finish_status_);
+ Status s = std::move(finish_status_);
+ auto* reactor = reactor_;
auto* call = call_.call();
this->~ClientCallbackReaderImpl();
g_core_codegen_interface->grpc_call_unref(call);
+ reactor->OnDone(s);
}
}
@@ -462,6 +468,7 @@ class ClientCallbackReaderImpl
// 1. Send initial metadata (unless corked) + recv initial metadata
// 2. Any backlog
// 3. Recv trailing metadata, on_completion callback
+ // 4. See if the call can finish (if other callbacks were triggered already)
started_ = true;
start_tag_.Set(call_.call(),
@@ -493,6 +500,8 @@ class ClientCallbackReaderImpl
finish_ops_.ClientRecvStatus(context_, &finish_status_);
finish_ops_.set_core_cq_tag(&finish_tag_);
call_.PerformOps(&finish_ops_);
+
+ MaybeFinish();
}
void Read(Response* msg) override {
@@ -536,8 +545,8 @@ class ClientCallbackReaderImpl
CallbackWithSuccessTag read_tag_;
bool read_ops_at_start_{false};
- // Minimum of 2 outstanding callbacks to pre-register for start and finish
- std::atomic_int callbacks_outstanding_{2};
+ // Minimum of 3 callbacks to pre-register for StartCall, start, and finish
+ std::atomic_int callbacks_outstanding_{3};
bool started_{false};
};
@@ -576,10 +585,12 @@ class ClientCallbackWriterImpl
void MaybeFinish() {
if (--callbacks_outstanding_ == 0) {
- reactor_->OnDone(finish_status_);
+ Status s = std::move(finish_status_);
+ auto* reactor = reactor_;
auto* call = call_.call();
this->~ClientCallbackWriterImpl();
g_core_codegen_interface->grpc_call_unref(call);
+ reactor->OnDone(s);
}
}
@@ -588,6 +599,7 @@ class ClientCallbackWriterImpl
// 1. Send initial metadata (unless corked) + recv initial metadata
// 2. Recv trailing metadata, on_completion callback
// 3. Any backlog
+ // 4. See if the call can finish (if other callbacks were triggered already)
started_ = true;
start_tag_.Set(call_.call(),
@@ -627,6 +639,8 @@ class ClientCallbackWriterImpl
if (writes_done_ops_at_start_) {
call_.PerformOps(&writes_done_ops_);
}
+
+ MaybeFinish();
}
void Write(const Request* msg, WriteOptions options) override {
@@ -708,8 +722,8 @@ class ClientCallbackWriterImpl
CallbackWithSuccessTag writes_done_tag_;
bool writes_done_ops_at_start_{false};
- // Minimum of 2 outstanding callbacks to pre-register for start and finish
- std::atomic_int callbacks_outstanding_{2};
+ // Minimum of 3 callbacks to pre-register for StartCall, start, and finish
+ std::atomic_int callbacks_outstanding_{3};
bool started_{false};
};