From 0823cb786b873ce5e6d180dd279865742580e3a3 Mon Sep 17 00:00:00 2001 From: Vijay Pai Date: Mon, 2 Mar 2015 15:48:51 -0800 Subject: Sanity checks for calls that were causing crashes --- src/cpp/server/server.cc | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/cpp/server/server.cc b/src/cpp/server/server.cc index 97bf0f1a6e..5c5b8d8286 100644 --- a/src/cpp/server/server.cc +++ b/src/cpp/server/server.cc @@ -287,12 +287,14 @@ void Server::Wait() { } void Server::PerformOpsOnCall(CallOpBuffer* buf, Call* call) { - static const size_t MAX_OPS = 8; - size_t nops = MAX_OPS; - grpc_op ops[MAX_OPS]; - buf->FillOps(ops, &nops); - GPR_ASSERT(GRPC_CALL_OK == - grpc_call_start_batch(call->call(), ops, nops, buf)); + if (call->call()) { + static const size_t MAX_OPS = 8; + size_t nops = MAX_OPS; + grpc_op ops[MAX_OPS]; + buf->FillOps(ops, &nops); + GPR_ASSERT(GRPC_CALL_OK == + grpc_call_start_batch(call->call(), ops, nops, buf)); + } } class Server::AsyncRequest GRPC_FINAL : public CompletionQueueTag { @@ -343,7 +345,9 @@ class Server::AsyncRequest GRPC_FINAL : public CompletionQueueTag { } ctx_->call_ = call_; Call call(call_, server_, cq_); - ctx_->BeginCompletionOp(&call); + if (call_) { + ctx_->BeginCompletionOp(&call); + } // just the pointers inside call are copied here stream_->BindCall(&call); delete this; -- cgit v1.2.3 From 7694c35d5f9c85ea844755d35f7d78d76e38348c Mon Sep 17 00:00:00 2001 From: Yang Gao Date: Tue, 3 Mar 2015 09:48:06 -0800 Subject: Global replace google::protobuf::Message with grpc::protobuf::Message, all tests passed --- include/grpc++/async_unary_call.h | 2 +- include/grpc++/channel_interface.h | 6 ------ include/grpc++/client_context.h | 6 ------ include/grpc++/completion_queue.h | 4 ++-- include/grpc++/impl/call.h | 14 ++++---------- include/grpc++/impl/client_unary_call.h | 11 ++++------- include/grpc++/impl/rpc_method.h | 6 ------ include/grpc++/impl/rpc_service_method.h | 20 ++++++++++---------- include/grpc++/impl/service_type.h | 12 ++++-------- include/grpc++/server.h | 8 +------- include/grpc++/stream.h | 12 ++++++------ src/cpp/client/client_unary_call.cc | 4 ++-- src/cpp/common/call.cc | 4 ++-- src/cpp/proto/proto_utils.cc | 4 ++-- src/cpp/proto/proto_utils.h | 11 ++++------- src/cpp/server/async_server_context.cc | 4 ++-- src/cpp/server/server.cc | 10 +++++----- 17 files changed, 49 insertions(+), 89 deletions(-) (limited to 'src') diff --git a/include/grpc++/async_unary_call.h b/include/grpc++/async_unary_call.h index 71b7d3ff85..f81cd7605d 100644 --- a/include/grpc++/async_unary_call.h +++ b/include/grpc++/async_unary_call.h @@ -49,7 +49,7 @@ class ClientAsyncResponseReader GRPC_FINAL { public: ClientAsyncResponseReader(ChannelInterface* channel, CompletionQueue* cq, const RpcMethod& method, ClientContext* context, - const google::protobuf::Message& request, void* tag) + const grpc::protobuf::Message& request, void* tag) : context_(context), call_(channel->CreateCall(method, context, cq)) { init_buf_.Reset(tag); diff --git a/include/grpc++/channel_interface.h b/include/grpc++/channel_interface.h index 77d1363618..51260aed3d 100644 --- a/include/grpc++/channel_interface.h +++ b/include/grpc++/channel_interface.h @@ -37,12 +37,6 @@ #include #include -namespace google { -namespace protobuf { -class Message; -} // namespace protobuf -} // namespace google - struct grpc_call; namespace grpc { diff --git a/include/grpc++/client_context.h b/include/grpc++/client_context.h index 87e5e9ad6c..c55d7c2d58 100644 --- a/include/grpc++/client_context.h +++ b/include/grpc++/client_context.h @@ -47,12 +47,6 @@ using std::chrono::system_clock; struct grpc_call; struct grpc_completion_queue; -namespace google { -namespace protobuf { -class Message; -} // namespace protobuf -} // namespace google - namespace grpc { class CallOpBuffer; diff --git a/include/grpc++/completion_queue.h b/include/grpc++/completion_queue.h index 0ca1260403..f741e3c36b 100644 --- a/include/grpc++/completion_queue.h +++ b/include/grpc++/completion_queue.h @@ -106,8 +106,8 @@ class CompletionQueue { friend Status BlockingUnaryCall(ChannelInterface *channel, const RpcMethod &method, ClientContext *context, - const google::protobuf::Message &request, - google::protobuf::Message *result); + const grpc::protobuf::Message &request, + grpc::protobuf::Message *result); // Wraps grpc_completion_queue_pluck. // Cannot be mixed with calls to Next(). diff --git a/include/grpc++/impl/call.h b/include/grpc++/impl/call.h index 3e199e3eae..5de5662973 100644 --- a/include/grpc++/impl/call.h +++ b/include/grpc++/impl/call.h @@ -42,12 +42,6 @@ #include #include -namespace google { -namespace protobuf { -class Message; -} // namespace protobuf -} // namespace google - struct grpc_call; struct grpc_op; @@ -67,8 +61,8 @@ class CallOpBuffer : public CompletionQueueTag { std::multimap *metadata); void AddSendInitialMetadata(ClientContext *ctx); void AddRecvInitialMetadata(ClientContext *ctx); - void AddSendMessage(const google::protobuf::Message &message); - void AddRecvMessage(google::protobuf::Message *message); + void AddSendMessage(const grpc::protobuf::Message &message); + void AddRecvMessage(grpc::protobuf::Message *message); void AddClientSendClose(); void AddClientRecvStatus(ClientContext *ctx, Status *status); void AddServerSendStatus(std::multimap *metadata, @@ -95,10 +89,10 @@ class CallOpBuffer : public CompletionQueueTag { std::multimap *recv_initial_metadata_; grpc_metadata_array recv_initial_metadata_arr_; // Send message - const google::protobuf::Message *send_message_; + const grpc::protobuf::Message *send_message_; grpc_byte_buffer *send_message_buf_; // Recv message - google::protobuf::Message *recv_message_; + grpc::protobuf::Message *recv_message_; grpc_byte_buffer *recv_message_buf_; // Client send close bool client_send_close_; diff --git a/include/grpc++/impl/client_unary_call.h b/include/grpc++/impl/client_unary_call.h index d8703264e6..23cf3a66df 100644 --- a/include/grpc++/impl/client_unary_call.h +++ b/include/grpc++/impl/client_unary_call.h @@ -34,11 +34,8 @@ #ifndef GRPCXX_IMPL_CLIENT_UNARY_CALL_H #define GRPCXX_IMPL_CLIENT_UNARY_CALL_H -namespace google { -namespace protobuf { -class Message; -} // namespace protobuf -} // namespace google + +#include namespace grpc { @@ -51,8 +48,8 @@ class Status; // Wrapper that performs a blocking unary call Status BlockingUnaryCall(ChannelInterface *channel, const RpcMethod &method, ClientContext *context, - const google::protobuf::Message &request, - google::protobuf::Message *result); + const grpc::protobuf::Message &request, + grpc::protobuf::Message *result); } // namespace grpc diff --git a/include/grpc++/impl/rpc_method.h b/include/grpc++/impl/rpc_method.h index ab407f5c46..e8909ac184 100644 --- a/include/grpc++/impl/rpc_method.h +++ b/include/grpc++/impl/rpc_method.h @@ -34,12 +34,6 @@ #ifndef GRPCXX_IMPL_RPC_METHOD_H #define GRPCXX_IMPL_RPC_METHOD_H -namespace google { -namespace protobuf { -class Message; -} // namespace protobuf -} // namespace google - namespace grpc { class RpcMethod { diff --git a/include/grpc++/impl/rpc_service_method.h b/include/grpc++/impl/rpc_service_method.h index ff94c7e6c0..325c8812ca 100644 --- a/include/grpc++/impl/rpc_service_method.h +++ b/include/grpc++/impl/rpc_service_method.h @@ -56,13 +56,13 @@ class MethodHandler { virtual ~MethodHandler() {} struct HandlerParameter { HandlerParameter(Call* c, ServerContext* context, - const google::protobuf::Message* req, - google::protobuf::Message* resp) + const grpc::protobuf::Message* req, + grpc::protobuf::Message* resp) : call(c), server_context(context), request(req), response(resp) {} Call* call; ServerContext* server_context; - const google::protobuf::Message* request; - google::protobuf::Message* response; + const grpc::protobuf::Message* request; + grpc::protobuf::Message* response; }; virtual Status RunHandler(const HandlerParameter& param) = 0; }; @@ -165,8 +165,8 @@ class RpcServiceMethod : public RpcMethod { // Takes ownership of the handler and two prototype objects. RpcServiceMethod(const char* name, RpcMethod::RpcType type, MethodHandler* handler, - google::protobuf::Message* request_prototype, - google::protobuf::Message* response_prototype) + grpc::protobuf::Message* request_prototype, + grpc::protobuf::Message* response_prototype) : RpcMethod(name, type), handler_(handler), request_prototype_(request_prototype), @@ -174,17 +174,17 @@ class RpcServiceMethod : public RpcMethod { MethodHandler* handler() { return handler_.get(); } - google::protobuf::Message* AllocateRequestProto() { + grpc::protobuf::Message* AllocateRequestProto() { return request_prototype_->New(); } - google::protobuf::Message* AllocateResponseProto() { + grpc::protobuf::Message* AllocateResponseProto() { return response_prototype_->New(); } private: std::unique_ptr handler_; - std::unique_ptr request_prototype_; - std::unique_ptr response_prototype_; + std::unique_ptr request_prototype_; + std::unique_ptr response_prototype_; }; // This class contains all the method information for an rpc service. It is diff --git a/include/grpc++/impl/service_type.h b/include/grpc++/impl/service_type.h index 7481d64d6a..7cd3ddad6b 100644 --- a/include/grpc++/impl/service_type.h +++ b/include/grpc++/impl/service_type.h @@ -34,11 +34,7 @@ #ifndef GRPCXX_IMPL_SERVICE_TYPE_H #define GRPCXX_IMPL_SERVICE_TYPE_H -namespace google { -namespace protobuf { -class Message; -} // namespace protobuf -} // namespace google +#include namespace grpc { @@ -72,7 +68,7 @@ class AsynchronousService { public: virtual void RequestAsyncCall(void* registered_method, ServerContext* context, - ::google::protobuf::Message* request, + ::grpc::protobuf::Message* request, ServerAsyncStreamingInterface* stream, CompletionQueue* cq, void* tag) = 0; }; @@ -91,7 +87,7 @@ class AsynchronousService { protected: void RequestAsyncUnary(int index, ServerContext* context, - ::google::protobuf::Message* request, + grpc::protobuf::Message* request, ServerAsyncStreamingInterface* stream, CompletionQueue* cq, void* tag) { dispatch_impl_->RequestAsyncCall(request_args_[index], context, request, @@ -104,7 +100,7 @@ class AsynchronousService { stream, cq, tag); } void RequestServerStreaming(int index, ServerContext* context, - ::google::protobuf::Message* request, + grpc::protobuf::Message* request, ServerAsyncStreamingInterface* stream, CompletionQueue* cq, void* tag) { dispatch_impl_->RequestAsyncCall(request_args_[index], context, request, diff --git a/include/grpc++/server.h b/include/grpc++/server.h index 3282b82d04..e3ba93e487 100644 --- a/include/grpc++/server.h +++ b/include/grpc++/server.h @@ -47,12 +47,6 @@ struct grpc_server; -namespace google { -namespace protobuf { -class Message; -} // namespace protobuf -} // namespace google - namespace grpc { class AsynchronousService; class RpcService; @@ -101,7 +95,7 @@ class Server GRPC_FINAL : private CallHook, // DispatchImpl void RequestAsyncCall(void* registered_method, ServerContext* context, - ::google::protobuf::Message* request, + grpc::protobuf::Message* request, ServerAsyncStreamingInterface* stream, CompletionQueue* cq, void* tag); diff --git a/include/grpc++/stream.h b/include/grpc++/stream.h index d95a379757..7625bcc38d 100644 --- a/include/grpc++/stream.h +++ b/include/grpc++/stream.h @@ -88,7 +88,7 @@ class ClientReader GRPC_FINAL : public ClientStreamingInterface, public: // Blocking create a stream and write the first request out. ClientReader(ChannelInterface* channel, const RpcMethod& method, - ClientContext* context, const google::protobuf::Message& request) + ClientContext* context, const grpc::protobuf::Message& request) : context_(context), call_(channel->CreateCall(method, context, &cq_)) { CallOpBuffer buf; buf.AddSendInitialMetadata(&context->send_initial_metadata_); @@ -142,7 +142,7 @@ class ClientWriter GRPC_FINAL : public ClientStreamingInterface, public: // Blocking create a stream. ClientWriter(ChannelInterface* channel, const RpcMethod& method, - ClientContext* context, google::protobuf::Message* response) + ClientContext* context, grpc::protobuf::Message* response) : context_(context), response_(response), call_(channel->CreateCall(method, context, &cq_)) { @@ -179,7 +179,7 @@ class ClientWriter GRPC_FINAL : public ClientStreamingInterface, private: ClientContext* context_; - google::protobuf::Message* const response_; + grpc::protobuf::Message* const response_; CompletionQueue cq_; Call call_; }; @@ -386,7 +386,7 @@ class ClientAsyncReader GRPC_FINAL : public ClientAsyncStreamingInterface, // Create a stream and write the first request out. ClientAsyncReader(ChannelInterface* channel, CompletionQueue* cq, const RpcMethod& method, ClientContext* context, - const google::protobuf::Message& request, void* tag) + const grpc::protobuf::Message& request, void* tag) : context_(context), call_(channel->CreateCall(method, context, cq)) { init_buf_.Reset(tag); init_buf_.AddSendInitialMetadata(&context->send_initial_metadata_); @@ -436,7 +436,7 @@ class ClientAsyncWriter GRPC_FINAL : public ClientAsyncStreamingInterface, public: ClientAsyncWriter(ChannelInterface* channel, CompletionQueue* cq, const RpcMethod& method, ClientContext* context, - google::protobuf::Message* response, void* tag) + grpc::protobuf::Message* response, void* tag) : context_(context), response_(response), call_(channel->CreateCall(method, context, cq)) { @@ -477,7 +477,7 @@ class ClientAsyncWriter GRPC_FINAL : public ClientAsyncStreamingInterface, private: ClientContext* context_; - google::protobuf::Message* const response_; + grpc::protobuf::Message* const response_; Call call_; CallOpBuffer init_buf_; CallOpBuffer meta_buf_; diff --git a/src/cpp/client/client_unary_call.cc b/src/cpp/client/client_unary_call.cc index 684b3cbadb..5c179de9d8 100644 --- a/src/cpp/client/client_unary_call.cc +++ b/src/cpp/client/client_unary_call.cc @@ -44,8 +44,8 @@ namespace grpc { // Wrapper that performs a blocking unary call Status BlockingUnaryCall(ChannelInterface *channel, const RpcMethod &method, ClientContext *context, - const google::protobuf::Message &request, - google::protobuf::Message *result) { + const grpc::protobuf::Message &request, + grpc::protobuf::Message *result) { CompletionQueue cq; Call call(channel->CreateCall(method, context, &cq)); CallOpBuffer buf; diff --git a/src/cpp/common/call.cc b/src/cpp/common/call.cc index f3a691114d..b2b6c62785 100644 --- a/src/cpp/common/call.cc +++ b/src/cpp/common/call.cc @@ -163,11 +163,11 @@ void CallOpBuffer::AddSendInitialMetadata(ClientContext* ctx) { AddSendInitialMetadata(&ctx->send_initial_metadata_); } -void CallOpBuffer::AddSendMessage(const google::protobuf::Message& message) { +void CallOpBuffer::AddSendMessage(const grpc::protobuf::Message& message) { send_message_ = &message; } -void CallOpBuffer::AddRecvMessage(google::protobuf::Message* message) { +void CallOpBuffer::AddRecvMessage(grpc::protobuf::Message* message) { recv_message_ = message; recv_message_->Clear(); } diff --git a/src/cpp/proto/proto_utils.cc b/src/cpp/proto/proto_utils.cc index 69a6bb080e..e6badd5d6e 100644 --- a/src/cpp/proto/proto_utils.cc +++ b/src/cpp/proto/proto_utils.cc @@ -40,7 +40,7 @@ namespace grpc { -bool SerializeProto(const google::protobuf::Message &msg, +bool SerializeProto(const grpc::protobuf::Message &msg, grpc_byte_buffer **bp) { grpc::string msg_str; bool success = msg.SerializeToString(&msg_str); @@ -54,7 +54,7 @@ bool SerializeProto(const google::protobuf::Message &msg, } bool DeserializeProto(grpc_byte_buffer *buffer, - google::protobuf::Message *msg) { + grpc::protobuf::Message *msg) { grpc::string msg_string; grpc_byte_buffer_reader *reader = grpc_byte_buffer_reader_create(buffer); gpr_slice slice; diff --git a/src/cpp/proto/proto_utils.h b/src/cpp/proto/proto_utils.h index a0af4d6465..7a1b1f8b7c 100644 --- a/src/cpp/proto/proto_utils.h +++ b/src/cpp/proto/proto_utils.h @@ -34,23 +34,20 @@ #ifndef GRPC_INTERNAL_CPP_PROTO_PROTO_UTILS_H #define GRPC_INTERNAL_CPP_PROTO_PROTO_UTILS_H +#include + struct grpc_byte_buffer; -namespace google { -namespace protobuf { -class Message; -} -} namespace grpc { // Serialize the msg into a buffer created inside the function. The caller // should destroy the returned buffer when done with it. If serialization fails, // false is returned and buffer is left unchanged. -bool SerializeProto(const google::protobuf::Message &msg, +bool SerializeProto(const grpc::protobuf::Message &msg, grpc_byte_buffer **buffer); // The caller keeps ownership of buffer and msg. -bool DeserializeProto(grpc_byte_buffer *buffer, google::protobuf::Message *msg); +bool DeserializeProto(grpc_byte_buffer *buffer, grpc::protobuf::Message *msg); } // namespace grpc diff --git a/src/cpp/server/async_server_context.cc b/src/cpp/server/async_server_context.cc index 5f8c2ba10f..bee75497b8 100644 --- a/src/cpp/server/async_server_context.cc +++ b/src/cpp/server/async_server_context.cc @@ -58,14 +58,14 @@ void AsyncServerContext::Accept(grpc_completion_queue *cq) { call_, GRPC_WRITE_BUFFER_HINT) == GRPC_CALL_OK); } -bool AsyncServerContext::StartRead(google::protobuf::Message *request) { +bool AsyncServerContext::StartRead(grpc::protobuf::Message *request) { GPR_ASSERT(request); request_ = request; grpc_call_error err = grpc_call_start_read_old(call_, this); return err == GRPC_CALL_OK; } -bool AsyncServerContext::StartWrite(const google::protobuf::Message &response, +bool AsyncServerContext::StartWrite(const grpc::protobuf::Message &response, int flags) { grpc_byte_buffer *buffer = nullptr; if (!SerializeProto(response, &buffer)) { diff --git a/src/cpp/server/server.cc b/src/cpp/server/server.cc index 97bf0f1a6e..17b97f6ecf 100644 --- a/src/cpp/server/server.cc +++ b/src/cpp/server/server.cc @@ -117,8 +117,8 @@ class Server::SyncRequest GRPC_FINAL : public CompletionQueueTag { } void Run() { - std::unique_ptr req; - std::unique_ptr res; + std::unique_ptr req; + std::unique_ptr res; if (has_request_payload_) { req.reset(method_->AllocateRequestProto()); if (!DeserializeProto(request_payload_, req.get())) { @@ -298,7 +298,7 @@ void Server::PerformOpsOnCall(CallOpBuffer* buf, Call* call) { class Server::AsyncRequest GRPC_FINAL : public CompletionQueueTag { public: AsyncRequest(Server* server, void* registered_method, ServerContext* ctx, - ::google::protobuf::Message* request, + grpc::protobuf::Message* request, ServerAsyncStreamingInterface* stream, CompletionQueue* cq, void* tag) : tag_(tag), @@ -352,7 +352,7 @@ class Server::AsyncRequest GRPC_FINAL : public CompletionQueueTag { private: void* const tag_; - ::google::protobuf::Message* const request_; + grpc::protobuf::Message* const request_; ServerAsyncStreamingInterface* const stream_; CompletionQueue* const cq_; ServerContext* const ctx_; @@ -364,7 +364,7 @@ class Server::AsyncRequest GRPC_FINAL : public CompletionQueueTag { }; void Server::RequestAsyncCall(void* registered_method, ServerContext* context, - ::google::protobuf::Message* request, + grpc::protobuf::Message* request, ServerAsyncStreamingInterface* stream, CompletionQueue* cq, void* tag) { new AsyncRequest(this, registered_method, context, request, stream, cq, tag); -- cgit v1.2.3 From 991ca9fef80d2c41f27b35718d8ea71dff44eafa Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Tue, 3 Mar 2015 09:59:22 -0800 Subject: Allow only one thread to complete ioreqs at once Otherwise we can get a total-queue-ordering violation and complete some ioreqs out-of-order. This leads to events being pushed to the completion queue out-of-order, and that leads to applications believing streams are completed before receiving the last message. --- src/core/surface/call.c | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/core/surface/call.c b/src/core/surface/call.c index 7cf3c0e4fd..b2033f3dc0 100644 --- a/src/core/surface/call.c +++ b/src/core/surface/call.c @@ -140,6 +140,8 @@ struct grpc_call { gpr_uint8 have_alarm; /* are we currently performing a send operation */ gpr_uint8 sending; + /* are we currently completing requests */ + gpr_uint8 completing; /* pairs with completed_requests */ gpr_uint8 num_completed_requests; /* flag that we need to request more data */ @@ -357,7 +359,7 @@ static void lock(grpc_call *call) { gpr_mu_lock(&call->mu); } static void unlock(grpc_call *call) { send_action sa = SEND_NOTHING; completed_request completed_requests[GRPC_IOREQ_OP_COUNT]; - int num_completed_requests = call->num_completed_requests; + int completing_requests = 0; int need_more_data = call->need_more_data && (call->write_state >= WRITE_STATE_STARTED || !call->is_client); @@ -367,10 +369,12 @@ static void unlock(grpc_call *call) { call->need_more_data = 0; } - if (num_completed_requests != 0) { + if (!call->completing && call->num_completed_requests != 0) { + completing_requests = call->num_completed_requests; memcpy(completed_requests, call->completed_requests, sizeof(completed_requests)); call->num_completed_requests = 0; + call->completing = 1; } if (!call->sending) { @@ -391,9 +395,14 @@ static void unlock(grpc_call *call) { enact_send_action(call, sa); } - for (i = 0; i < num_completed_requests; i++) { - completed_requests[i].on_complete(call, completed_requests[i].status, - completed_requests[i].user_data); + if (completing_requests > 0) { + for (i = 0; i < completing_requests; i++) { + completed_requests[i].on_complete(call, completed_requests[i].status, + completed_requests[i].user_data); + } + lock(call); + call->completing = 0; + unlock(call); } } -- cgit v1.2.3 From dbb79631eb7231d82114aecaa5d0c7d8be6d34a9 Mon Sep 17 00:00:00 2001 From: Vijay Pai Date: Tue, 3 Mar 2015 11:54:27 -0800 Subject: Solve the call-suppression problem earlier in the stack --- src/cpp/server/server.cc | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/cpp/server/server.cc b/src/cpp/server/server.cc index 5c5b8d8286..f4410c12a5 100644 --- a/src/cpp/server/server.cc +++ b/src/cpp/server/server.cc @@ -287,14 +287,12 @@ void Server::Wait() { } void Server::PerformOpsOnCall(CallOpBuffer* buf, Call* call) { - if (call->call()) { - static const size_t MAX_OPS = 8; - size_t nops = MAX_OPS; - grpc_op ops[MAX_OPS]; - buf->FillOps(ops, &nops); - GPR_ASSERT(GRPC_CALL_OK == - grpc_call_start_batch(call->call(), ops, nops, buf)); - } + static const size_t MAX_OPS = 8; + size_t nops = MAX_OPS; + grpc_op ops[MAX_OPS]; + buf->FillOps(ops, &nops); + GPR_ASSERT(GRPC_CALL_OK == + grpc_call_start_batch(call->call(), ops, nops, buf)); } class Server::AsyncRequest GRPC_FINAL : public CompletionQueueTag { @@ -326,6 +324,7 @@ class Server::AsyncRequest GRPC_FINAL : public CompletionQueueTag { bool FinalizeResult(void** tag, bool* status) GRPC_OVERRIDE { *tag = tag_; + bool orig_status = *status; if (*status && request_) { if (payload_) { *status = DeserializeProto(payload_, request_); @@ -345,7 +344,7 @@ class Server::AsyncRequest GRPC_FINAL : public CompletionQueueTag { } ctx_->call_ = call_; Call call(call_, server_, cq_); - if (call_) { + if (orig_status && call_) { ctx_->BeginCompletionOp(&call); } // just the pointers inside call are copied here -- cgit v1.2.3