From 4224384d398ee3ddd01c0b95f93f33bdd75e8fb2 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Thu, 3 Jan 2019 15:47:00 -0800 Subject: Modifying semantics for GetSendMessage and GetSerializedSendMessage. Also adding ModifySendMessage --- include/grpcpp/impl/codegen/call_op_set.h | 31 +++++++++++++++------- include/grpcpp/impl/codegen/interceptor.h | 2 ++ include/grpcpp/impl/codegen/interceptor_common.h | 33 +++++++++++++++++++++--- 3 files changed, 53 insertions(+), 13 deletions(-) (limited to 'include') diff --git a/include/grpcpp/impl/codegen/call_op_set.h b/include/grpcpp/impl/codegen/call_op_set.h index 310bea93ca..b9cf0b1db0 100644 --- a/include/grpcpp/impl/codegen/call_op_set.h +++ b/include/grpcpp/impl/codegen/call_op_set.h @@ -317,7 +317,10 @@ class CallOpSendMessage { protected: void AddOp(grpc_op* ops, size_t* nops) { - if (!send_buf_.Valid() || hijacked_) return; + if ((msg_ == nullptr && !send_buf_.Valid()) || hijacked_) return; + if (msg_ != nullptr) { + GPR_CODEGEN_ASSERT(serializer_(msg_).ok()); + } grpc_op* op = &ops[(*nops)++]; op->op = GRPC_OP_SEND_MESSAGE; op->flags = write_options_.flags(); @@ -330,17 +333,17 @@ class CallOpSendMessage { void SetInterceptionHookPoint( InterceptorBatchMethodsImpl* interceptor_methods) { - if (!send_buf_.Valid()) return; + if (msg_ == nullptr && !send_buf_.Valid()) return; interceptor_methods->AddInterceptionHookPoint( experimental::InterceptionHookPoints::PRE_SEND_MESSAGE); - interceptor_methods->SetSendMessage(&send_buf_, msg_); + interceptor_methods->SetSendMessage(&send_buf_, &msg_, serializer_); } void SetFinishInterceptionHookPoint( InterceptorBatchMethodsImpl* interceptor_methods) { // The contents of the SendMessage value that was previously set // has had its references stolen by core's operations - interceptor_methods->SetSendMessage(nullptr, nullptr); + interceptor_methods->SetSendMessage(nullptr, nullptr, nullptr); } void SetHijackingState(InterceptorBatchMethodsImpl* interceptor_methods) { @@ -352,6 +355,7 @@ class CallOpSendMessage { bool hijacked_ = false; ByteBuffer send_buf_; WriteOptions write_options_; + std::function serializer_; }; template @@ -362,12 +366,21 @@ Status CallOpSendMessage::SendMessage(const M& message, WriteOptions options) { // The void in the template parameter below should not be needed // (since it should be implicit) but is needed due to an observed // difference in behavior between clang and gcc for certain internal users - Status result = SerializationTraits::Serialize( - message, send_buf_.bbuf_ptr(), &own_buf); - if (!own_buf) { - send_buf_.Duplicate(); + serializer_ = [this](const void* message) { + bool own_buf; + send_buf_.Clear(); + Status result = SerializationTraits::Serialize( + *static_cast(message), send_buf_.bbuf_ptr(), &own_buf); + if (!own_buf) { + send_buf_.Duplicate(); + } + return result; + }; + // Serialize immediately only if we do not have access to the message pointer + if (msg_ == nullptr) { + return serializer_(&message); } - return result; + return Status::OK; } template diff --git a/include/grpcpp/impl/codegen/interceptor.h b/include/grpcpp/impl/codegen/interceptor.h index 5a9a3a44e6..edf3ab49f1 100644 --- a/include/grpcpp/impl/codegen/interceptor.h +++ b/include/grpcpp/impl/codegen/interceptor.h @@ -117,6 +117,8 @@ class InterceptorBatchMethods { /// only supported for sync and callback APIs at the present moment. virtual const void* GetSendMessage() = 0; + virtual void ModifySendMessage(const void* message) = 0; + /// Returns a modifiable multimap of the initial metadata to be sent. Valid /// for PRE_SEND_INITIAL_METADATA interceptions. A value of nullptr indicates /// that this field is not valid. diff --git a/include/grpcpp/impl/codegen/interceptor_common.h b/include/grpcpp/impl/codegen/interceptor_common.h index 4b7eaefee1..6fa6210dc3 100644 --- a/include/grpcpp/impl/codegen/interceptor_common.h +++ b/include/grpcpp/impl/codegen/interceptor_common.h @@ -79,9 +79,24 @@ class InterceptorBatchMethodsImpl hooks_[static_cast(type)] = true; } - ByteBuffer* GetSerializedSendMessage() override { return send_message_; } + ByteBuffer* GetSerializedSendMessage() override { + GPR_CODEGEN_ASSERT(orig_send_message_ != nullptr); + if (*orig_send_message_ != nullptr) { + GPR_CODEGEN_ASSERT(serializer_(*orig_send_message_).ok()); + *orig_send_message_ = nullptr; + } + return send_message_; + } + + const void* GetSendMessage() override { + GPR_CODEGEN_ASSERT(orig_send_message_ != nullptr); + return *orig_send_message_; + } - const void* GetSendMessage() override { return orig_send_message_; } + void ModifySendMessage(const void* message) override { + GPR_CODEGEN_ASSERT(orig_send_message_ != nullptr); + *orig_send_message_ = message; + } std::multimap* GetSendInitialMetadata() override { return send_initial_metadata_; @@ -117,9 +132,11 @@ class InterceptorBatchMethodsImpl return recv_trailing_metadata_->map(); } - void SetSendMessage(ByteBuffer* buf, const void* msg) { + void SetSendMessage(ByteBuffer* buf, const void** msg, + std::function serializer) { send_message_ = buf; orig_send_message_ = msg; + serializer_ = serializer; } void SetSendInitialMetadata( @@ -339,7 +356,8 @@ class InterceptorBatchMethodsImpl std::function callback_; ByteBuffer* send_message_ = nullptr; - const void* orig_send_message_ = nullptr; + const void** orig_send_message_ = nullptr; + std::function serializer_; std::multimap* send_initial_metadata_; @@ -400,6 +418,13 @@ class CancelInterceptorBatchMethods return nullptr; } + void ModifySendMessage(const void* message) override { + GPR_CODEGEN_ASSERT( + false && + "It is illegal to call ModifySendMessage on a method which " + "has a Cancel notification"); + } + std::multimap* GetSendInitialMetadata() override { GPR_CODEGEN_ASSERT(false && "It is illegal to call GetSendInitialMetadata on a " -- cgit v1.2.3