GRPC C++  1.22.0
async_unary_call.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_H
20 #define GRPCPP_IMPL_CODEGEN_ASYNC_UNARY_CALL_H
21 
22 #include <assert.h>
29 
30 namespace grpc {
31 
32 extern CoreCodegenInterface* g_core_codegen_interface;
33 
36 template <class R>
38  public:
40 
44  virtual void StartCall() = 0;
45 
52  virtual void ReadInitialMetadata(void* tag) = 0;
53 
68  virtual void Finish(R* msg, Status* status, void* tag) = 0;
69 };
70 
71 namespace internal {
72 template <class R>
74  public:
81  template <class W>
83  ChannelInterface* channel, CompletionQueue* cq,
84  const ::grpc::internal::RpcMethod& method, ClientContext* context,
85  const W& request, bool start) {
86  ::grpc::internal::Call call = channel->CreateCall(method, context, cq);
87  return new (g_core_codegen_interface->grpc_call_arena_alloc(
88  call.call(), sizeof(ClientAsyncResponseReader<R>)))
89  ClientAsyncResponseReader<R>(call, context, request, start);
90  }
91 };
92 } // namespace internal
93 
96 template <class R>
99  public:
100  // always allocated against a call arena, no memory free required
101  static void operator delete(void* ptr, std::size_t size) {
102  assert(size == sizeof(ClientAsyncResponseReader));
103  }
104 
105  // This operator should never be called as the memory should be freed as part
106  // of the arena destruction. It only exists to provide a matching operator
107  // delete to the operator new so that some compilers will not complain (see
108  // https://github.com/grpc/grpc/issues/11301) Note at the time of adding this
109  // there are no tests catching the compiler warning.
110  static void operator delete(void*, void*) { assert(0); }
111 
112  void StartCall() override {
113  assert(!started_);
114  started_ = true;
115  StartCallInternal();
116  }
117 
124  void ReadInitialMetadata(void* tag) override {
125  assert(started_);
126  GPR_CODEGEN_ASSERT(!context_->initial_metadata_received_);
127 
128  single_buf.set_output_tag(tag);
129  single_buf.RecvInitialMetadata(context_);
130  call_.PerformOps(&single_buf);
131  initial_metadata_read_ = true;
132  }
133 
139  void Finish(R* msg, Status* status, void* tag) override {
140  assert(started_);
141  if (initial_metadata_read_) {
142  finish_buf.set_output_tag(tag);
143  finish_buf.RecvMessage(msg);
144  finish_buf.AllowNoMessage();
145  finish_buf.ClientRecvStatus(context_, status);
146  call_.PerformOps(&finish_buf);
147  } else {
148  single_buf.set_output_tag(tag);
149  single_buf.RecvInitialMetadata(context_);
150  single_buf.RecvMessage(msg);
151  single_buf.AllowNoMessage();
152  single_buf.ClientRecvStatus(context_, status);
153  call_.PerformOps(&single_buf);
154  }
155  }
156 
157  private:
159  ClientContext* const context_;
161  bool started_;
162  bool initial_metadata_read_ = false;
163 
164  template <class W>
166  const W& request, bool start)
167  : context_(context), call_(call), started_(start) {
168  // Bind the metadata at time of StartCallInternal but set up the rest here
169  // TODO(ctiller): don't assert
170  GPR_CODEGEN_ASSERT(single_buf.SendMessage(request).ok());
171  single_buf.ClientSendClose();
172  if (start) StartCallInternal();
173  }
174 
175  void StartCallInternal() {
176  single_buf.SendInitialMetadata(&context_->send_initial_metadata_,
177  context_->initial_metadata_flags());
178  }
179 
180  // disable operator new
181  static void* operator new(std::size_t size);
182  static void* operator new(std::size_t size, void* p) { return p; }
183 
190  single_buf;
193  finish_buf;
194 };
195 
198 template <class W>
201  public:
203  : call_(nullptr, nullptr, nullptr), ctx_(ctx) {}
204 
212  void SendInitialMetadata(void* tag) override {
213  GPR_CODEGEN_ASSERT(!ctx_->sent_initial_metadata_);
214 
215  meta_buf_.set_output_tag(tag);
216  meta_buf_.SendInitialMetadata(&ctx_->initial_metadata_,
217  ctx_->initial_metadata_flags());
218  if (ctx_->compression_level_set()) {
219  meta_buf_.set_compression_level(ctx_->compression_level());
220  }
221  ctx_->sent_initial_metadata_ = true;
222  call_.PerformOps(&meta_buf_);
223  }
224 
240  void Finish(const W& msg, const Status& status, void* tag) {
241  finish_buf_.set_output_tag(tag);
242  finish_buf_.set_core_cq_tag(&finish_buf_);
243  if (!ctx_->sent_initial_metadata_) {
244  finish_buf_.SendInitialMetadata(&ctx_->initial_metadata_,
245  ctx_->initial_metadata_flags());
246  if (ctx_->compression_level_set()) {
247  finish_buf_.set_compression_level(ctx_->compression_level());
248  }
249  ctx_->sent_initial_metadata_ = true;
250  }
251  // The response is dropped if the status is not OK.
252  if (status.ok()) {
253  finish_buf_.ServerSendStatus(&ctx_->trailing_metadata_,
254  finish_buf_.SendMessage(msg));
255  } else {
256  finish_buf_.ServerSendStatus(&ctx_->trailing_metadata_, status);
257  }
258  call_.PerformOps(&finish_buf_);
259  }
260 
273  void FinishWithError(const Status& status, void* tag) {
274  GPR_CODEGEN_ASSERT(!status.ok());
275  finish_buf_.set_output_tag(tag);
276  if (!ctx_->sent_initial_metadata_) {
277  finish_buf_.SendInitialMetadata(&ctx_->initial_metadata_,
278  ctx_->initial_metadata_flags());
279  if (ctx_->compression_level_set()) {
280  finish_buf_.set_compression_level(ctx_->compression_level());
281  }
282  ctx_->sent_initial_metadata_ = true;
283  }
284  finish_buf_.ServerSendStatus(&ctx_->trailing_metadata_, status);
285  call_.PerformOps(&finish_buf_);
286  }
287 
288  private:
289  void BindCall(::grpc::internal::Call* call) override { call_ = *call; }
290 
292  ServerContext* ctx_;
294  meta_buf_;
298  finish_buf_;
299 };
300 
301 } // namespace grpc
302 
303 namespace std {
304 template <class R>
305 class default_delete<grpc::ClientAsyncResponseReader<R>> {
306  public:
307  void operator()(void* p) {}
308 };
309 template <class R>
310 class default_delete<grpc::ClientAsyncResponseReaderInterface<R>> {
311  public:
312  void operator()(void* p) {}
313 };
314 } // namespace std
315 
316 #endif // GRPCPP_IMPL_CODEGEN_ASYNC_UNARY_CALL_H
void FinishWithError(const 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.h:273
virtual ~ClientAsyncResponseReaderInterface()
Definition: async_unary_call.h:39
virtual void Finish(R *msg, 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...
#define GPR_CODEGEN_ASSERT(x)
Codegen specific version of GPR_ASSERT.
Definition: core_codegen_interface.h:145
virtual void StartCall()=0
Start the call that was set up by the constructor, but only if the constructor was invoked through th...
Definition: async_unary_call.h:73
void Finish(const W &msg, const 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.h:240
Primary implementation of CallOpSetInterface.
Definition: call_op_set.h:821
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.h:112
Definition: async_unary_call.h:303
virtual void ReadInitialMetadata(void *tag)=0
Request notification of the reading of initial metadata.
grpc_call * call() const
Definition: call.h:72
Async API for client-side unary RPCs, where the message response received from the server is of type ...
Definition: async_unary_call.h:97
A ServerContext allows the person implementing a service handler to:
Definition: server_context_impl.h:114
void operator()(void *p)
Definition: async_unary_call.h:307
void SendInitialMetadata(void *tag) override
See ServerAsyncStreamingInterface::SendInitialMetadata for semantics.
Definition: async_unary_call.h:212
Definition: call_op_set.h:629
Definition: call_op_set.h:218
Definition: call_op_set.h:696
An interface relevant for async client side unary RPCs (which send one request message to a server an...
Definition: async_unary_call.h:37
Definition: call_op_set.h:288
void operator()(void *p)
Definition: async_unary_call.h:312
static ClientAsyncResponseReader< R > * Create(ChannelInterface *channel, CompletionQueue *cq, const ::grpc::internal::RpcMethod &method, ClientContext *context, const W &request, bool start)
Start a call and write the request out if start is set.
Definition: async_unary_call.h:82
This header provides an object that reads bytes directly from a grpc::ByteBuffer, via the ZeroCopyInp...
Definition: alarm.h:24
Codegen interface for grpc::Channel.
Definition: channel_interface.h:69
CoreCodegenInterface * g_core_codegen_interface
Definition: call_op_set.h:51
void ReadInitialMetadata(void *tag) override
See ClientAsyncResponseReaderInterface::ReadInitialMetadata for semantics.
Definition: async_unary_call.h:124
Definition: byte_buffer.h:41
Definition: call_op_set.h:594
bool ok() const
Is the status OK?
Definition: status.h:118
ServerAsyncResponseWriter(ServerContext *ctx)
Definition: async_unary_call.h:202
A thin wrapper around grpc_completion_queue (see src/core/lib/surface/completion_queue.h).
Definition: completion_queue_impl.h:102
A ClientContext allows the person implementing a service client to:
Definition: client_context_impl.h:178
Did it work? If it didn&#39;t, why?
Definition: status.h:31
Async server-side API for handling unary calls, where the single response message sent to the client ...
Definition: async_unary_call.h:199
void Finish(R *msg, Status *status, void *tag) override
See ClientAysncResponseReaderInterface::Finish for semantics.
Definition: async_unary_call.h:139
void PerformOps(CallOpSetInterface *ops)
Definition: call.h:68
Definition: call_op_set.h:744
Straightforward wrapping of the C call object.
Definition: call.h:38