GRPC C++  1.26.0
async_unary_call_impl.h
Go to the documentation of this file.
1 /*
2  *
3  * Copyright 2015 gRPC authors.
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  */
18 
19 #ifndef GRPCPP_IMPL_CODEGEN_ASYNC_UNARY_CALL_IMPL_H
20 #define GRPCPP_IMPL_CODEGEN_ASYNC_UNARY_CALL_IMPL_H
21 
28 
29 namespace grpc_impl {
30 
33 template <class R>
35  public:
37 
41  virtual void StartCall() = 0;
42 
49  virtual void ReadInitialMetadata(void* tag) = 0;
50 
65  virtual void Finish(R* msg, ::grpc::Status* status, void* tag) = 0;
66 };
67 
68 namespace internal {
69 template <class R>
71  public:
78  template <class W>
81  const ::grpc::internal::RpcMethod& method,
82  ::grpc_impl::ClientContext* context, const W& request, bool start) {
83  ::grpc::internal::Call call = channel->CreateCall(method, context, cq);
85  call.call(), sizeof(ClientAsyncResponseReader<R>)))
86  ClientAsyncResponseReader<R>(call, context, request, start);
87  }
88 };
89 } // namespace internal
90 
93 template <class R>
96  public:
97  // always allocated against a call arena, no memory free required
98  static void operator delete(void* /*ptr*/, std::size_t size) {
100  }
101 
102  // This operator should never be called as the memory should be freed as part
103  // of the arena destruction. It only exists to provide a matching operator
104  // delete to the operator new so that some compilers will not complain (see
105  // https://github.com/grpc/grpc/issues/11301) Note at the time of adding this
106  // there are no tests catching the compiler warning.
107  static void operator delete(void*, void*) { GPR_CODEGEN_ASSERT(false); }
108 
109  void StartCall() override {
110  GPR_CODEGEN_ASSERT(!started_);
111  started_ = true;
112  StartCallInternal();
113  }
114 
121  void ReadInitialMetadata(void* tag) override {
122  GPR_CODEGEN_ASSERT(started_);
123  GPR_CODEGEN_ASSERT(!context_->initial_metadata_received_);
124 
125  single_buf.set_output_tag(tag);
126  single_buf.RecvInitialMetadata(context_);
127  call_.PerformOps(&single_buf);
128  initial_metadata_read_ = true;
129  }
130 
136  void Finish(R* msg, ::grpc::Status* status, void* tag) override {
137  GPR_CODEGEN_ASSERT(started_);
138  if (initial_metadata_read_) {
139  finish_buf.set_output_tag(tag);
140  finish_buf.RecvMessage(msg);
141  finish_buf.AllowNoMessage();
142  finish_buf.ClientRecvStatus(context_, status);
143  call_.PerformOps(&finish_buf);
144  } else {
145  single_buf.set_output_tag(tag);
146  single_buf.RecvInitialMetadata(context_);
147  single_buf.RecvMessage(msg);
148  single_buf.AllowNoMessage();
149  single_buf.ClientRecvStatus(context_, status);
150  call_.PerformOps(&single_buf);
151  }
152  }
153 
154  private:
156  ::grpc_impl::ClientContext* const context_;
158  bool started_;
159  bool initial_metadata_read_ = false;
160 
161  template <class W>
163  ::grpc_impl::ClientContext* context,
164  const W& request, bool start)
165  : context_(context), call_(call), started_(start) {
166  // Bind the metadata at time of StartCallInternal but set up the rest here
167  // TODO(ctiller): don't assert
168  GPR_CODEGEN_ASSERT(single_buf.SendMessage(request).ok());
169  single_buf.ClientSendClose();
170  if (start) StartCallInternal();
171  }
172 
173  void StartCallInternal() {
174  single_buf.SendInitialMetadata(&context_->send_initial_metadata_,
175  context_->initial_metadata_flags());
176  }
177 
178  // disable operator new
179  static void* operator new(std::size_t size);
180  static void* operator new(std::size_t /*size*/, void* p) { return p; }
181 
188  single_buf;
191  finish_buf;
192 };
193 
196 template <class W>
199  public:
201  : call_(nullptr, nullptr, nullptr), ctx_(ctx) {}
202 
210  void SendInitialMetadata(void* tag) override {
211  GPR_CODEGEN_ASSERT(!ctx_->sent_initial_metadata_);
212 
213  meta_buf_.set_output_tag(tag);
214  meta_buf_.SendInitialMetadata(&ctx_->initial_metadata_,
215  ctx_->initial_metadata_flags());
216  if (ctx_->compression_level_set()) {
217  meta_buf_.set_compression_level(ctx_->compression_level());
218  }
219  ctx_->sent_initial_metadata_ = true;
220  call_.PerformOps(&meta_buf_);
221  }
222 
238  void Finish(const W& msg, const ::grpc::Status& status, void* tag) {
239  finish_buf_.set_output_tag(tag);
240  finish_buf_.set_core_cq_tag(&finish_buf_);
241  if (!ctx_->sent_initial_metadata_) {
242  finish_buf_.SendInitialMetadata(&ctx_->initial_metadata_,
243  ctx_->initial_metadata_flags());
244  if (ctx_->compression_level_set()) {
245  finish_buf_.set_compression_level(ctx_->compression_level());
246  }
247  ctx_->sent_initial_metadata_ = true;
248  }
249  // The response is dropped if the status is not OK.
250  if (status.ok()) {
251  finish_buf_.ServerSendStatus(&ctx_->trailing_metadata_,
252  finish_buf_.SendMessage(msg));
253  } else {
254  finish_buf_.ServerSendStatus(&ctx_->trailing_metadata_, status);
255  }
256  call_.PerformOps(&finish_buf_);
257  }
258 
271  void FinishWithError(const ::grpc::Status& status, void* tag) {
272  GPR_CODEGEN_ASSERT(!status.ok());
273  finish_buf_.set_output_tag(tag);
274  if (!ctx_->sent_initial_metadata_) {
275  finish_buf_.SendInitialMetadata(&ctx_->initial_metadata_,
276  ctx_->initial_metadata_flags());
277  if (ctx_->compression_level_set()) {
278  finish_buf_.set_compression_level(ctx_->compression_level());
279  }
280  ctx_->sent_initial_metadata_ = true;
281  }
282  finish_buf_.ServerSendStatus(&ctx_->trailing_metadata_, status);
283  call_.PerformOps(&finish_buf_);
284  }
285 
286  private:
287  void BindCall(::grpc::internal::Call* call) override { call_ = *call; }
288 
292  meta_buf_;
296  finish_buf_;
297 };
298 
299 } // namespace grpc_impl
300 
301 namespace std {
302 template <class R>
303 class default_delete<::grpc_impl::ClientAsyncResponseReader<R>> {
304  public:
305  void operator()(void* /*p*/) {}
306 };
307 template <class R>
309  public:
310  void operator()(void* /*p*/) {}
311 };
312 } // namespace std
313 
314 #endif // GRPCPP_IMPL_CODEGEN_ASYNC_UNARY_CALL_IMPL_H
#define GPR_CODEGEN_ASSERT(x)
Codegen specific version of GPR_ASSERT.
Definition: core_codegen_interface.h:146
Definition: async_unary_call_impl.h:70
Primary implementation of CallOpSetInterface.
Definition: call_op_set.h:824
virtual void Finish(R *msg, ::grpc::Status *status, void *tag)=0
Request to receive the server&#39;s response msg and final status for the call, and to notify tag on this...
void ReadInitialMetadata(void *tag) override
See ClientAsyncResponseReaderInterface::ReadInitialMetadata for semantics.
Definition: async_unary_call_impl.h:121
Definition: async_unary_call_impl.h:301
void operator()(void *)
Definition: async_unary_call_impl.h:310
grpc_call * call() const
Definition: call.h:72
A ServerContext or CallbackServerContext allows the code implementing a service handler to: ...
Definition: server_context_impl.h:488
::google::protobuf::util::Status Status
Definition: config_protobuf.h:90
virtual ~ClientAsyncResponseReaderInterface()
Definition: async_unary_call_impl.h:36
void Finish(const W &msg, const ::grpc::Status &status, void *tag)
Indicate that the stream is to be finished and request notification when the server has sent the appr...
Definition: async_unary_call_impl.h:238
An interface relevant for async client side unary RPCs (which send one request message to a server an...
Definition: async_unary_call_impl.h:34
Definition: call_op_set.h:627
Definition: call_op_set.h:216
void StartCall() override
Start the call that was set up by the constructor, but only if the constructor was invoked through th...
Definition: async_unary_call_impl.h:109
static ClientAsyncResponseReader< R > * Create(::grpc::ChannelInterface *channel, ::grpc_impl::CompletionQueue *cq, const ::grpc::internal::RpcMethod &method, ::grpc_impl::ClientContext *context, const W &request, bool start)
Start a call and write the request out if start is set.
Definition: async_unary_call_impl.h:79
Definition: call_op_set.h:694
void Finish(R *msg, ::grpc::Status *status, void *tag) override
See ClientAysncResponseReaderInterface::Finish for semantics.
Definition: async_unary_call_impl.h:136
void FinishWithError(const ::grpc::Status &status, void *tag)
Indicate that the stream is to be finished with a non-OK status, and request notification for when th...
Definition: async_unary_call_impl.h:271
Definition: call_op_set.h:286
Async API for client-side unary RPCs, where the message response received from the server is of type ...
Definition: async_unary_call_impl.h:94
Async server-side API for handling unary calls, where the single response message sent to the client ...
Definition: async_unary_call_impl.h:197
virtual void StartCall()=0
Start the call that was set up by the constructor, but only if the constructor was invoked through th...
Codegen interface for grpc::Channel.
Definition: channel_interface.h:74
CoreCodegenInterface * g_core_codegen_interface
Definition: completion_queue_impl.h:90
void SendInitialMetadata(void *tag) override
See ServerAsyncStreamingInterface::SendInitialMetadata for semantics.
Definition: async_unary_call_impl.h:210
Definition: byte_buffer.h:58
An Alarm posts the user-provided tag to its associated completion queue or invokes the user-provided ...
Definition: alarm_impl.h:33
Definition: call_op_set.h:592
virtual void * grpc_call_arena_alloc(grpc_call *call, size_t length)=0
virtual void ReadInitialMetadata(void *tag)=0
Request notification of the reading of initial metadata.
A thin wrapper around grpc_completion_queue (see src/core/lib/surface/completion_queue.h).
Definition: completion_queue_impl.h:100
A ClientContext allows the person implementing a service client to:
Definition: client_context_impl.h:184
ServerAsyncResponseWriter(::grpc_impl::ServerContext *ctx)
Definition: async_unary_call_impl.h:200
Did it work? If it didn&#39;t, why?
Definition: status.h:31
void PerformOps(CallOpSetInterface *ops)
Definition: call.h:68
Definition: call_op_set.h:742
void operator()(void *)
Definition: async_unary_call_impl.h:305
grpc_impl::ClientAsyncResponseReader< R > ClientAsyncResponseReader
Definition: async_unary_call.h:31
Straightforward wrapping of the C call object.
Definition: call.h:38