diff options
author | Muxi Yan <mxyan@google.com> | 2018-01-19 12:20:15 -0800 |
---|---|---|
committer | Muxi Yan <mxyan@google.com> | 2018-01-19 12:20:15 -0800 |
commit | fb061c329ac5086b62619b118191574f3fd27a79 (patch) | |
tree | 6a855770d7218425a2cd53bc378800c30d6c8525 /include/grpc++ | |
parent | 032e9b32dc5978a042bdda5c3031ae6cbd928973 (diff) | |
parent | 9813858908da2e7deaa58d91f4030e6881e364e3 (diff) |
Merge remote-tracking branch 'upstream/master' into fix-stream-compression-config-interface
Diffstat (limited to 'include/grpc++')
-rw-r--r-- | include/grpc++/impl/codegen/client_unary_call.h | 1 | ||||
-rw-r--r-- | include/grpc++/impl/codegen/method_handler_impl.h | 37 |
2 files changed, 34 insertions, 4 deletions
diff --git a/include/grpc++/impl/codegen/client_unary_call.h b/include/grpc++/impl/codegen/client_unary_call.h index 256dd859d3..543e54b972 100644 --- a/include/grpc++/impl/codegen/client_unary_call.h +++ b/include/grpc++/impl/codegen/client_unary_call.h @@ -65,6 +65,7 @@ class BlockingUnaryCallImpl { context->initial_metadata_flags()); ops.RecvInitialMetadata(context); ops.RecvMessage(result); + ops.AllowNoMessage(); ops.ClientSendClose(); ops.ClientRecvStatus(context, &status_); call.PerformOps(&ops); diff --git a/include/grpc++/impl/codegen/method_handler_impl.h b/include/grpc++/impl/codegen/method_handler_impl.h index c0af4ca130..daf090f86c 100644 --- a/include/grpc++/impl/codegen/method_handler_impl.h +++ b/include/grpc++/impl/codegen/method_handler_impl.h @@ -27,6 +27,27 @@ namespace grpc { namespace internal { + +// Invoke the method handler, fill in the status, and +// return whether or not we finished safely (without an exception). +// Note that exception handling is 0-cost in most compiler/library +// implementations (except when an exception is actually thrown), +// so this process doesn't require additional overhead in the common case. +// Additionally, we don't need to return if we caught an exception or not; +// the handling is the same in either case. +template <class Callable> +Status CatchingFunctionHandler(Callable&& handler) { +#if GRPC_ALLOW_EXCEPTIONS + try { + return handler(); + } catch (...) { + return Status(StatusCode::UNKNOWN, "Unexpected error in RPC handling"); + } +#else // GRPC_ALLOW_EXCEPTIONS + return handler(); +#endif // GRPC_ALLOW_EXCEPTIONS +} + /// A wrapper class of an application provided rpc method handler. template <class ServiceType, class RequestType, class ResponseType> class RpcMethodHandler : public MethodHandler { @@ -43,7 +64,9 @@ class RpcMethodHandler : public MethodHandler { param.request.bbuf_ptr(), &req); ResponseType rsp; if (status.ok()) { - status = func_(service_, param.server_context, &req, &rsp); + status = CatchingFunctionHandler([this, ¶m, &req, &rsp] { + return func_(service_, param.server_context, &req, &rsp); + }); } GPR_CODEGEN_ASSERT(!param.server_context->sent_initial_metadata_); @@ -86,7 +109,9 @@ class ClientStreamingHandler : public MethodHandler { void RunHandler(const HandlerParameter& param) final { ServerReader<RequestType> reader(param.call, param.server_context); ResponseType rsp; - Status status = func_(service_, param.server_context, &reader, &rsp); + Status status = CatchingFunctionHandler([this, ¶m, &reader, &rsp] { + return func_(service_, param.server_context, &reader, &rsp); + }); GPR_CODEGEN_ASSERT(!param.server_context->sent_initial_metadata_); CallOpSet<CallOpSendInitialMetadata, CallOpSendMessage, @@ -130,7 +155,9 @@ class ServerStreamingHandler : public MethodHandler { if (status.ok()) { ServerWriter<ResponseType> writer(param.call, param.server_context); - status = func_(service_, param.server_context, &req, &writer); + status = CatchingFunctionHandler([this, ¶m, &req, &writer] { + return func_(service_, param.server_context, &req, &writer); + }); } CallOpSet<CallOpSendInitialMetadata, CallOpServerSendStatus> ops; @@ -172,7 +199,9 @@ class TemplatedBidiStreamingHandler : public MethodHandler { void RunHandler(const HandlerParameter& param) final { Streamer stream(param.call, param.server_context); - Status status = func_(param.server_context, &stream); + Status status = CatchingFunctionHandler([this, ¶m, &stream] { + return func_(param.server_context, &stream); + }); CallOpSet<CallOpSendInitialMetadata, CallOpServerSendStatus> ops; if (!param.server_context->sent_initial_metadata_) { |