diff options
author | 2018-09-14 14:31:48 -0700 | |
---|---|---|
committer | 2018-09-14 16:56:19 -0700 | |
commit | 73d89a66f90eb8cf5e9b8939690ebf7347fba147 (patch) | |
tree | 981d4116a945ee6cf2d81f44ca65a1ed5c87c05e /src | |
parent | ff449831884eedb2519b43008c6ee13caf4d1853 (diff) |
Catch exceptions in user callbacks
Diffstat (limited to 'src')
-rw-r--r-- | src/cpp/common/callback_common.cc | 28 |
1 files changed, 23 insertions, 5 deletions
diff --git a/src/cpp/common/callback_common.cc b/src/cpp/common/callback_common.cc index ae47901f1b..fa586286d1 100644 --- a/src/cpp/common/callback_common.cc +++ b/src/cpp/common/callback_common.cc @@ -26,8 +26,21 @@ namespace grpc { namespace internal { - namespace { + +template <class Func, class Arg> +void CatchingCallback(Func&& func, Arg&& arg) { +#if GRPC_ALLOW_EXCEPTIONS + try { + func(arg); + } catch (...) { + // nothing to return or change here, just don't crash the library + } +#else // GRPC_ALLOW_EXCEPTIONS + func(arg); +#endif // GRPC_ALLOW_EXCEPTIONS +} + class CallbackWithSuccessImpl : public grpc_core::CQCallbackInterface { public: static void operator delete(void* ptr, std::size_t size) { @@ -52,8 +65,11 @@ class CallbackWithSuccessImpl : public grpc_core::CQCallbackInterface { bool new_ok = ok; GPR_ASSERT(parent_->ops()->FinalizeResult(&ignored, &new_ok)); GPR_ASSERT(ignored == parent_->ops()); - func_(ok); - func_ = nullptr; // release the function + + // Last use of func_ or ok, so ok to move them out for rvalue call above + CatchingCallback(std::move(func_), std::move(ok)); + + func_ = nullptr; // reset to clear this out for sure grpc_call_unref(call_); } @@ -88,8 +104,10 @@ class CallbackWithStatusImpl : public grpc_core::CQCallbackInterface { GPR_ASSERT(parent_->ops()->FinalizeResult(&ignored, &ok)); GPR_ASSERT(ignored == parent_->ops()); - func_(status_); - func_ = nullptr; // release the function + // Last use of func_ or status_, so ok to move them out + CatchingCallback(std::move(func_), std::move(status_)); + + func_ = nullptr; // reset to clear this out for sure grpc_call_unref(call_); } Status* status_ptr() { return &status_; } |