diff options
Diffstat (limited to 'include/grpcpp/impl')
-rw-r--r-- | include/grpcpp/impl/codegen/byte_buffer.h | 4 | ||||
-rw-r--r-- | include/grpcpp/impl/codegen/client_unary_call.h | 4 | ||||
-rw-r--r-- | include/grpcpp/impl/codegen/completion_queue.h | 12 | ||||
-rw-r--r-- | include/grpcpp/impl/codegen/method_handler_impl.h | 17 | ||||
-rw-r--r-- | include/grpcpp/impl/codegen/server_context.h | 8 | ||||
-rw-r--r-- | include/grpcpp/impl/codegen/service_type.h | 37 | ||||
-rw-r--r-- | include/grpcpp/impl/codegen/sync_stream.h | 12 |
7 files changed, 64 insertions, 30 deletions
diff --git a/include/grpcpp/impl/codegen/byte_buffer.h b/include/grpcpp/impl/codegen/byte_buffer.h index 86c047ebe7..8cc5158115 100644 --- a/include/grpcpp/impl/codegen/byte_buffer.h +++ b/include/grpcpp/impl/codegen/byte_buffer.h @@ -45,6 +45,8 @@ template <class ServiceType, class RequestType, class ResponseType> class RpcMethodHandler; template <class ServiceType, class RequestType, class ResponseType> class ServerStreamingHandler; +template <StatusCode code> +class ErrorMethodHandler; template <class R> class DeserializeFuncType; class GrpcByteBufferPeer; @@ -144,6 +146,8 @@ class ByteBuffer final { friend class internal::RpcMethodHandler; template <class ServiceType, class RequestType, class ResponseType> friend class internal::ServerStreamingHandler; + template <StatusCode code> + friend class internal::ErrorMethodHandler; template <class R> friend class internal::DeserializeFuncType; friend class ProtoBufferReader; diff --git a/include/grpcpp/impl/codegen/client_unary_call.h b/include/grpcpp/impl/codegen/client_unary_call.h index a37a81b75b..e4e8364e07 100644 --- a/include/grpcpp/impl/codegen/client_unary_call.h +++ b/include/grpcpp/impl/codegen/client_unary_call.h @@ -50,8 +50,8 @@ class BlockingUnaryCallImpl { ClientContext* context, const InputMessage& request, OutputMessage* result) { CompletionQueue cq(grpc_completion_queue_attributes{ - GRPC_CQ_CURRENT_VERSION, GRPC_CQ_PLUCK, - GRPC_CQ_DEFAULT_POLLING}); // Pluckable completion queue + GRPC_CQ_CURRENT_VERSION, GRPC_CQ_PLUCK, GRPC_CQ_DEFAULT_POLLING, + nullptr}); // Pluckable completion queue Call call(channel->CreateCall(method, context, &cq)); CallOpSet<CallOpSendInitialMetadata, CallOpSendMessage, CallOpRecvInitialMetadata, CallOpRecvMessage<OutputMessage>, diff --git a/include/grpcpp/impl/codegen/completion_queue.h b/include/grpcpp/impl/codegen/completion_queue.h index 5819e068ba..6c8428ebde 100644 --- a/include/grpcpp/impl/codegen/completion_queue.h +++ b/include/grpcpp/impl/codegen/completion_queue.h @@ -78,9 +78,10 @@ template <class ServiceType, class RequestType, class ResponseType> class ServerStreamingHandler; template <class ServiceType, class RequestType, class ResponseType> class BidiStreamingHandler; -class UnknownMethodHandler; template <class Streamer, bool WriteNeeded> class TemplatedBidiStreamingHandler; +template <StatusCode code> +class ErrorMethodHandler; template <class InputMessage, class OutputMessage> class BlockingUnaryCallImpl; } // namespace internal @@ -97,7 +98,8 @@ class CompletionQueue : private GrpcLibraryCodegen { /// instance. CompletionQueue() : CompletionQueue(grpc_completion_queue_attributes{ - GRPC_CQ_CURRENT_VERSION, GRPC_CQ_NEXT, GRPC_CQ_DEFAULT_POLLING}) {} + GRPC_CQ_CURRENT_VERSION, GRPC_CQ_NEXT, GRPC_CQ_DEFAULT_POLLING, + nullptr}) {} /// Wrap \a take, taking ownership of the instance. /// @@ -264,7 +266,8 @@ class CompletionQueue : private GrpcLibraryCodegen { friend class ::grpc::internal::ServerStreamingHandler; template <class Streamer, bool WriteNeeded> friend class ::grpc::internal::TemplatedBidiStreamingHandler; - friend class ::grpc::internal::UnknownMethodHandler; + template <StatusCode code> + friend class ::grpc::internal::ErrorMethodHandler; friend class ::grpc::Server; friend class ::grpc::ServerContext; friend class ::grpc::ServerInterface; @@ -376,11 +379,12 @@ class ServerCompletionQueue : public CompletionQueue { /// frequently polled. ServerCompletionQueue(grpc_cq_polling_type polling_type) : CompletionQueue(grpc_completion_queue_attributes{ - GRPC_CQ_CURRENT_VERSION, GRPC_CQ_NEXT, polling_type}), + GRPC_CQ_CURRENT_VERSION, GRPC_CQ_NEXT, polling_type, nullptr}), polling_type_(polling_type) {} grpc_cq_polling_type polling_type_; friend class ServerBuilder; + friend class Server; }; } // namespace grpc diff --git a/include/grpcpp/impl/codegen/method_handler_impl.h b/include/grpcpp/impl/codegen/method_handler_impl.h index 851aa2a024..53117f941b 100644 --- a/include/grpcpp/impl/codegen/method_handler_impl.h +++ b/include/grpcpp/impl/codegen/method_handler_impl.h @@ -272,12 +272,14 @@ class SplitServerStreamingHandler ServerSplitStreamer<RequestType, ResponseType>, false>(func) {} }; -/// Handle unknown method by returning UNIMPLEMENTED error. -class UnknownMethodHandler : public MethodHandler { +/// General method handler class for errors that prevent real method use +/// e.g., handle unknown method by returning UNIMPLEMENTED error. +template <StatusCode code> +class ErrorMethodHandler : public MethodHandler { public: template <class T> static void FillOps(ServerContext* context, T* ops) { - Status status(StatusCode::UNIMPLEMENTED, ""); + Status status(code, ""); if (!context->sent_initial_metadata_) { ops->SendInitialMetadata(context->initial_metadata_, context->initial_metadata_flags()); @@ -294,9 +296,18 @@ class UnknownMethodHandler : public MethodHandler { FillOps(param.server_context, &ops); param.call->PerformOps(&ops); param.call->cq()->Pluck(&ops); + // We also have to destroy any request payload in the handler parameter + ByteBuffer* payload = param.request.bbuf_ptr(); + if (payload != nullptr) { + payload->Clear(); + } } }; +typedef ErrorMethodHandler<StatusCode::UNIMPLEMENTED> UnknownMethodHandler; +typedef ErrorMethodHandler<StatusCode::RESOURCE_EXHAUSTED> + ResourceExhaustedHandler; + } // namespace internal } // namespace grpc diff --git a/include/grpcpp/impl/codegen/server_context.h b/include/grpcpp/impl/codegen/server_context.h index 153b404d9e..6314364db6 100644 --- a/include/grpcpp/impl/codegen/server_context.h +++ b/include/grpcpp/impl/codegen/server_context.h @@ -63,9 +63,10 @@ template <class ServiceType, class RequestType, class ResponseType> class ServerStreamingHandler; template <class ServiceType, class RequestType, class ResponseType> class BidiStreamingHandler; -class UnknownMethodHandler; template <class Streamer, bool WriteNeeded> class TemplatedBidiStreamingHandler; +template <StatusCode code> +class ErrorMethodHandler; class Call; } // namespace internal @@ -226,6 +227,8 @@ class ServerContext { /// Async only. Has to be called before the rpc starts. /// Returns the tag in completion queue when the rpc finishes. /// IsCancelled() can then be called to check whether the rpc was cancelled. + /// TODO(vjpai): Fix this so that the tag is returned even if the call never + /// starts (https://github.com/grpc/grpc/issues/10136). void AsyncNotifyWhenDone(void* tag) { has_notify_when_done_tag_ = true; async_notify_when_done_tag_ = tag; @@ -262,7 +265,8 @@ class ServerContext { friend class ::grpc::internal::ServerStreamingHandler; template <class Streamer, bool WriteNeeded> friend class ::grpc::internal::TemplatedBidiStreamingHandler; - friend class ::grpc::internal::UnknownMethodHandler; + template <StatusCode code> + friend class internal::ErrorMethodHandler; friend class ::grpc::ClientContext; /// Prevent copying. diff --git a/include/grpcpp/impl/codegen/service_type.h b/include/grpcpp/impl/codegen/service_type.h index a0bbd659e2..9f1a052168 100644 --- a/include/grpcpp/impl/codegen/service_type.h +++ b/include/grpcpp/impl/codegen/service_type.h @@ -93,14 +93,19 @@ class Service { internal::ServerAsyncStreamingInterface* stream, CompletionQueue* call_cq, ServerCompletionQueue* notification_cq, void* tag) { - server_->RequestAsyncCall(methods_[index].get(), context, stream, call_cq, + // Typecast the index to size_t for indexing into a vector + // while preserving the API that existed before a compiler + // warning was first seen (grpc/grpc#11664) + size_t idx = static_cast<size_t>(index); + server_->RequestAsyncCall(methods_[idx].get(), context, stream, call_cq, notification_cq, tag, request); } void RequestAsyncClientStreaming( int index, ServerContext* context, internal::ServerAsyncStreamingInterface* stream, CompletionQueue* call_cq, ServerCompletionQueue* notification_cq, void* tag) { - server_->RequestAsyncCall(methods_[index].get(), context, stream, call_cq, + size_t idx = static_cast<size_t>(index); + server_->RequestAsyncCall(methods_[idx].get(), context, stream, call_cq, notification_cq, tag); } template <class Message> @@ -108,14 +113,16 @@ class Service { int index, ServerContext* context, Message* request, internal::ServerAsyncStreamingInterface* stream, CompletionQueue* call_cq, ServerCompletionQueue* notification_cq, void* tag) { - server_->RequestAsyncCall(methods_[index].get(), context, stream, call_cq, + size_t idx = static_cast<size_t>(index); + server_->RequestAsyncCall(methods_[idx].get(), context, stream, call_cq, notification_cq, tag, request); } void RequestAsyncBidiStreaming( int index, ServerContext* context, internal::ServerAsyncStreamingInterface* stream, CompletionQueue* call_cq, ServerCompletionQueue* notification_cq, void* tag) { - server_->RequestAsyncCall(methods_[index].get(), context, stream, call_cq, + size_t idx = static_cast<size_t>(index); + server_->RequestAsyncCall(methods_[idx].get(), context, stream, call_cq, notification_cq, tag); } @@ -126,46 +133,50 @@ class Service { void MarkMethodAsync(int index) { // This does not have to be a hard error, however no one has approached us // with a use case yet. Please file an issue if you believe you have one. + size_t idx = static_cast<size_t>(index); GPR_CODEGEN_ASSERT( - methods_[index].get() != nullptr && + methods_[idx].get() != nullptr && "Cannot mark the method as 'async' because it has already been " "marked as 'generic'."); - methods_[index]->SetServerAsyncType( + methods_[idx]->SetServerAsyncType( internal::RpcServiceMethod::AsyncType::ASYNC); } void MarkMethodRaw(int index) { // This does not have to be a hard error, however no one has approached us // with a use case yet. Please file an issue if you believe you have one. - GPR_CODEGEN_ASSERT(methods_[index].get() != nullptr && + size_t idx = static_cast<size_t>(index); + GPR_CODEGEN_ASSERT(methods_[idx].get() != nullptr && "Cannot mark the method as 'raw' because it has already " "been marked as 'generic'."); - methods_[index]->SetServerAsyncType( + methods_[idx]->SetServerAsyncType( internal::RpcServiceMethod::AsyncType::RAW); } void MarkMethodGeneric(int index) { // This does not have to be a hard error, however no one has approached us // with a use case yet. Please file an issue if you believe you have one. + size_t idx = static_cast<size_t>(index); GPR_CODEGEN_ASSERT( - methods_[index]->handler() != nullptr && + methods_[idx]->handler() != nullptr && "Cannot mark the method as 'generic' because it has already been " "marked as 'async' or 'raw'."); - methods_[index].reset(); + methods_[idx].reset(); } void MarkMethodStreamed(int index, internal::MethodHandler* streamed_method) { // This does not have to be a hard error, however no one has approached us // with a use case yet. Please file an issue if you believe you have one. - GPR_CODEGEN_ASSERT(methods_[index] && methods_[index]->handler() && + size_t idx = static_cast<size_t>(index); + GPR_CODEGEN_ASSERT(methods_[idx] && methods_[idx]->handler() && "Cannot mark an async or generic method Streamed"); - methods_[index]->SetHandler(streamed_method); + methods_[idx]->SetHandler(streamed_method); // From the server's point of view, streamed unary is a special // case of BIDI_STREAMING that has 1 read and 1 write, in that order, // and split server-side streaming is BIDI_STREAMING with 1 read and // any number of writes, in that order. - methods_[index]->SetMethodType(internal::RpcMethod::BIDI_STREAMING); + methods_[idx]->SetMethodType(internal::RpcMethod::BIDI_STREAMING); } private: diff --git a/include/grpcpp/impl/codegen/sync_stream.h b/include/grpcpp/impl/codegen/sync_stream.h index 7152eaf41f..cbfcf25d0a 100644 --- a/include/grpcpp/impl/codegen/sync_stream.h +++ b/include/grpcpp/impl/codegen/sync_stream.h @@ -243,8 +243,8 @@ class ClientReader final : public ClientReaderInterface<R> { ClientContext* context, const W& request) : context_(context), cq_(grpc_completion_queue_attributes{ - GRPC_CQ_CURRENT_VERSION, GRPC_CQ_PLUCK, - GRPC_CQ_DEFAULT_POLLING}), // Pluckable cq + GRPC_CQ_CURRENT_VERSION, GRPC_CQ_PLUCK, GRPC_CQ_DEFAULT_POLLING, + nullptr}), // Pluckable cq call_(channel->CreateCall(method, context, &cq_)) { ::grpc::internal::CallOpSet<::grpc::internal::CallOpSendInitialMetadata, ::grpc::internal::CallOpSendMessage, @@ -377,8 +377,8 @@ class ClientWriter : public ClientWriterInterface<W> { ClientContext* context, R* response) : context_(context), cq_(grpc_completion_queue_attributes{ - GRPC_CQ_CURRENT_VERSION, GRPC_CQ_PLUCK, - GRPC_CQ_DEFAULT_POLLING}), // Pluckable cq + GRPC_CQ_CURRENT_VERSION, GRPC_CQ_PLUCK, GRPC_CQ_DEFAULT_POLLING, + nullptr}), // Pluckable cq call_(channel->CreateCall(method, context, &cq_)) { finish_ops_.RecvMessage(response); finish_ops_.AllowNoMessage(); @@ -551,8 +551,8 @@ class ClientReaderWriter final : public ClientReaderWriterInterface<W, R> { ClientContext* context) : context_(context), cq_(grpc_completion_queue_attributes{ - GRPC_CQ_CURRENT_VERSION, GRPC_CQ_PLUCK, - GRPC_CQ_DEFAULT_POLLING}), // Pluckable cq + GRPC_CQ_CURRENT_VERSION, GRPC_CQ_PLUCK, GRPC_CQ_DEFAULT_POLLING, + nullptr}), // Pluckable cq call_(channel->CreateCall(method, context, &cq_)) { if (!context_->initial_metadata_corked_) { ::grpc::internal::CallOpSet<::grpc::internal::CallOpSendInitialMetadata> |