aboutsummaryrefslogtreecommitdiffhomepage
path: root/include/grpcpp/impl/codegen/callback_common.h
diff options
context:
space:
mode:
authorGravatar Vijay Pai <vpai@google.com>2018-12-03 09:52:28 -0800
committerGravatar GitHub <noreply@github.com>2018-12-03 09:52:28 -0800
commit6bca0313d870a45bdbfa016acb1d60588aaeaa5c (patch)
tree2f7b5e76efd392b2868a7b281946aa9bb2bf8469 /include/grpcpp/impl/codegen/callback_common.h
parent6fd003fc24cc344cb2ee9b6669c15affeacd3b5f (diff)
parent09ba4b40472e50a55bb56b069420d74ad5472d37 (diff)
Merge pull request #17144 from vjpai/server_streaming
C++ callback API for streaming servers
Diffstat (limited to 'include/grpcpp/impl/codegen/callback_common.h')
-rw-r--r--include/grpcpp/impl/codegen/callback_common.h19
1 files changed, 18 insertions, 1 deletions
diff --git a/include/grpcpp/impl/codegen/callback_common.h b/include/grpcpp/impl/codegen/callback_common.h
index f7a24204dc..a3c8c41246 100644
--- a/include/grpcpp/impl/codegen/callback_common.h
+++ b/include/grpcpp/impl/codegen/callback_common.h
@@ -32,6 +32,8 @@ namespace grpc {
namespace internal {
/// An exception-safe way of invoking a user-specified callback function
+// TODO(vjpai): decide whether it is better for this to take a const lvalue
+// parameter or an rvalue parameter, or if it even matters
template <class Func, class... Args>
void CatchingCallback(Func&& func, Args&&... args) {
#if GRPC_ALLOW_EXCEPTIONS
@@ -45,6 +47,20 @@ void CatchingCallback(Func&& func, Args&&... args) {
#endif // GRPC_ALLOW_EXCEPTIONS
}
+template <class ReturnType, class Func, class... Args>
+ReturnType* CatchingReactorCreator(Func&& func, Args&&... args) {
+#if GRPC_ALLOW_EXCEPTIONS
+ try {
+ return func(std::forward<Args>(args)...);
+ } catch (...) {
+ // fail the RPC, don't crash the library
+ return nullptr;
+ }
+#else // GRPC_ALLOW_EXCEPTIONS
+ return func(std::forward<Args>(args)...);
+#endif // GRPC_ALLOW_EXCEPTIONS
+}
+
// The contract on these tags is that they are single-shot. They must be
// constructed and then fired at exactly one point. There is no expectation
// that they can be reused without reconstruction.
@@ -185,8 +201,9 @@ class CallbackWithSuccessTag
void* ignored = ops_;
// Allow a "false" return value from FinalizeResult to silence the
// callback, just as it silences a CQ tag in the async cases
+ auto* ops = ops_;
bool do_callback = ops_->FinalizeResult(&ignored, &ok);
- GPR_CODEGEN_ASSERT(ignored == ops_);
+ GPR_CODEGEN_ASSERT(ignored == ops);
if (do_callback) {
CatchingCallback(func_, ok);