GRPC C++  1.28.0
client_callback_impl.h
Go to the documentation of this file.
1 /*
2  *
3  * Copyright 2019 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 #ifndef GRPCPP_IMPL_CODEGEN_CLIENT_CALLBACK_IMPL_H
19 #define GRPCPP_IMPL_CODEGEN_CLIENT_CALLBACK_IMPL_H
20 #include <atomic>
21 #include <functional>
22 
30 
31 namespace grpc {
32 namespace internal {
33 class RpcMethod;
34 } // namespace internal
35 } // namespace grpc
36 
37 namespace grpc_impl {
38 class Channel;
39 class ClientContext;
40 
41 namespace internal {
42 
45 template <class InputMessage, class OutputMessage>
47  const ::grpc::internal::RpcMethod& method,
48  ::grpc_impl::ClientContext* context,
49  const InputMessage* request, OutputMessage* result,
50  std::function<void(::grpc::Status)> on_completion) {
52  channel, method, context, request, result, on_completion);
53 }
54 
55 template <class InputMessage, class OutputMessage>
56 class CallbackUnaryCallImpl {
57  public:
59  const ::grpc::internal::RpcMethod& method,
60  ::grpc_impl::ClientContext* context,
61  const InputMessage* request, OutputMessage* result,
62  std::function<void(::grpc::Status)> on_completion) {
63  ::grpc_impl::CompletionQueue* cq = channel->CallbackCQ();
64  GPR_CODEGEN_ASSERT(cq != nullptr);
65  grpc::internal::Call call(channel->CreateCall(method, context, cq));
66 
67  using FullCallOpSet = grpc::internal::CallOpSet<
74 
75  struct OpSetAndTag {
76  FullCallOpSet opset;
78  };
79  const size_t alloc_sz = sizeof(OpSetAndTag);
80  auto* const alloced = static_cast<OpSetAndTag*>(
82  alloc_sz));
83  auto* ops = new (&alloced->opset) FullCallOpSet;
84  auto* tag = new (&alloced->tag)
85  grpc::internal::CallbackWithStatusTag(call.call(), on_completion, ops);
86 
87  // TODO(vjpai): Unify code with sync API as much as possible
88  ::grpc::Status s = ops->SendMessagePtr(request);
89  if (!s.ok()) {
90  tag->force_run(s);
91  return;
92  }
93  ops->SendInitialMetadata(&context->send_initial_metadata_,
94  context->initial_metadata_flags());
95  ops->RecvInitialMetadata(context);
96  ops->RecvMessage(result);
97  ops->AllowNoMessage();
98  ops->ClientSendClose();
99  ops->ClientRecvStatus(context, tag->status_ptr());
100  ops->set_core_cq_tag(tag);
101  call.PerformOps(ops);
102  }
103 };
104 } // namespace internal
105 
106 // Forward declarations
107 template <class Request, class Response>
109 template <class Response>
111 template <class Request>
113 class ClientUnaryReactor;
114 
115 // NOTE: The streaming objects are not actually implemented in the public API.
116 // These interfaces are provided for mocking only. Typical applications
117 // will interact exclusively with the reactors that they define.
118 template <class Request, class Response>
120  public:
122  virtual void StartCall() = 0;
123  virtual void Write(const Request* req, ::grpc::WriteOptions options) = 0;
124  virtual void WritesDone() = 0;
125  virtual void Read(Response* resp) = 0;
126  virtual void AddHold(int holds) = 0;
127  virtual void RemoveHold() = 0;
128 
129  protected:
131  reactor->BindStream(this);
132  }
133 };
134 
135 template <class Response>
137  public:
139  virtual void StartCall() = 0;
140  virtual void Read(Response* resp) = 0;
141  virtual void AddHold(int holds) = 0;
142  virtual void RemoveHold() = 0;
143 
144  protected:
146  reactor->BindReader(this);
147  }
148 };
149 
150 template <class Request>
152  public:
154  virtual void StartCall() = 0;
155  void Write(const Request* req) { Write(req, ::grpc::WriteOptions()); }
156  virtual void Write(const Request* req, ::grpc::WriteOptions options) = 0;
157  void WriteLast(const Request* req, ::grpc::WriteOptions options) {
158  Write(req, options.set_last_message());
159  }
160  virtual void WritesDone() = 0;
161 
162  virtual void AddHold(int holds) = 0;
163  virtual void RemoveHold() = 0;
164 
165  protected:
167  reactor->BindWriter(this);
168  }
169 };
170 
172  public:
173  virtual ~ClientCallbackUnary() {}
174  virtual void StartCall() = 0;
175 
176  protected:
177  void BindReactor(ClientUnaryReactor* reactor);
178 };
179 
180 // The following classes are the reactor interfaces that are to be implemented
181 // by the user. They are passed in to the library as an argument to a call on a
182 // stub (either a codegen-ed call or a generic call). The streaming RPC is
183 // activated by calling StartCall, possibly after initiating StartRead,
184 // StartWrite, or AddHold operations on the streaming object. Note that none of
185 // the classes are pure; all reactions have a default empty reaction so that the
186 // user class only needs to override those classes that it cares about.
187 // The reactor must be passed to the stub invocation before any of the below
188 // operations can be called.
189 
191 template <class Request, class Response>
192 class ClientBidiReactor {
193  public:
194  virtual ~ClientBidiReactor() {}
195 
200  void StartCall() { stream_->StartCall(); }
201 
207  void StartRead(Response* resp) { stream_->Read(resp); }
208 
215  void StartWrite(const Request* req) {
216  StartWrite(req, ::grpc::WriteOptions());
217  }
218 
225  void StartWrite(const Request* req, ::grpc::WriteOptions options) {
226  stream_->Write(req, std::move(options));
227  }
228 
238  void StartWriteLast(const Request* req, ::grpc::WriteOptions options) {
239  StartWrite(req, std::move(options.set_last_message()));
240  }
241 
247  void StartWritesDone() { stream_->WritesDone(); }
248 
270  void AddHold() { AddMultipleHolds(1); }
271  void AddMultipleHolds(int holds) { stream_->AddHold(holds); }
272  void RemoveHold() { stream_->RemoveHold(); }
273 
278  virtual void OnDone(const ::grpc::Status& /*s*/) {}
279 
287  virtual void OnReadInitialMetadataDone(bool /*ok*/) {}
288 
293  virtual void OnReadDone(bool /*ok*/) {}
294 
299  virtual void OnWriteDone(bool /*ok*/) {}
300 
307  virtual void OnWritesDoneDone(bool /*ok*/) {}
308 
309  private:
310  friend class ClientCallbackReaderWriter<Request, Response>;
311  void BindStream(ClientCallbackReaderWriter<Request, Response>* stream) {
312  stream_ = stream;
313  }
315 };
316 
319 template <class Response>
320 class ClientReadReactor {
321  public:
322  virtual ~ClientReadReactor() {}
323 
324  void StartCall() { reader_->StartCall(); }
325  void StartRead(Response* resp) { reader_->Read(resp); }
326 
327  void AddHold() { AddMultipleHolds(1); }
328  void AddMultipleHolds(int holds) { reader_->AddHold(holds); }
329  void RemoveHold() { reader_->RemoveHold(); }
330 
331  virtual void OnDone(const ::grpc::Status& /*s*/) {}
332  virtual void OnReadInitialMetadataDone(bool /*ok*/) {}
333  virtual void OnReadDone(bool /*ok*/) {}
334 
335  private:
336  friend class ClientCallbackReader<Response>;
337  void BindReader(ClientCallbackReader<Response>* reader) { reader_ = reader; }
339 };
340 
343 template <class Request>
344 class ClientWriteReactor {
345  public:
346  virtual ~ClientWriteReactor() {}
347 
348  void StartCall() { writer_->StartCall(); }
349  void StartWrite(const Request* req) {
350  StartWrite(req, ::grpc::WriteOptions());
351  }
352  void StartWrite(const Request* req, ::grpc::WriteOptions options) {
353  writer_->Write(req, std::move(options));
354  }
355  void StartWriteLast(const Request* req, ::grpc::WriteOptions options) {
356  StartWrite(req, std::move(options.set_last_message()));
357  }
358  void StartWritesDone() { writer_->WritesDone(); }
359 
360  void AddHold() { AddMultipleHolds(1); }
361  void AddMultipleHolds(int holds) { writer_->AddHold(holds); }
362  void RemoveHold() { writer_->RemoveHold(); }
363 
364  virtual void OnDone(const ::grpc::Status& /*s*/) {}
365  virtual void OnReadInitialMetadataDone(bool /*ok*/) {}
366  virtual void OnWriteDone(bool /*ok*/) {}
367  virtual void OnWritesDoneDone(bool /*ok*/) {}
368 
369  private:
370  friend class ClientCallbackWriter<Request>;
371  void BindWriter(ClientCallbackWriter<Request>* writer) { writer_ = writer; }
373 };
374 
387  public:
388  virtual ~ClientUnaryReactor() {}
389 
390  void StartCall() { call_->StartCall(); }
391  virtual void OnDone(const ::grpc::Status& /*s*/) {}
392  virtual void OnReadInitialMetadataDone(bool /*ok*/) {}
393 
394  private:
395  friend class ClientCallbackUnary;
396  void BindCall(ClientCallbackUnary* call) { call_ = call; }
397  ClientCallbackUnary* call_;
398 };
399 
400 // Define function out-of-line from class to avoid forward declaration issue
402  reactor->BindCall(this);
403 }
404 
405 namespace internal {
406 
407 // Forward declare factory classes for friendship
408 template <class Request, class Response>
409 class ClientCallbackReaderWriterFactory;
410 template <class Response>
411 class ClientCallbackReaderFactory;
412 template <class Request>
413 class ClientCallbackWriterFactory;
414 
415 template <class Request, class Response>
417  : public ClientCallbackReaderWriter<Request, Response> {
418  public:
419  // always allocated against a call arena, no memory free required
420  static void operator delete(void* /*ptr*/, std::size_t size) {
422  }
423 
424  // This operator should never be called as the memory should be freed as part
425  // of the arena destruction. It only exists to provide a matching operator
426  // delete to the operator new so that some compilers will not complain (see
427  // https://github.com/grpc/grpc/issues/11301) Note at the time of adding this
428  // there are no tests catching the compiler warning.
429  static void operator delete(void*, void*) { GPR_CODEGEN_ASSERT(false); }
430 
431  void MaybeFinish() {
432  if (GPR_UNLIKELY(callbacks_outstanding_.fetch_sub(
433  1, std::memory_order_acq_rel) == 1)) {
434  ::grpc::Status s = std::move(finish_status_);
435  auto* reactor = reactor_;
436  auto* call = call_.call();
439  reactor->OnDone(s);
440  }
441  }
442 
443  void StartCall() override {
444  // This call initiates two batches, plus any backlog, each with a callback
445  // 1. Send initial metadata (unless corked) + recv initial metadata
446  // 2. Any read backlog
447  // 3. Any write backlog
448  // 4. Recv trailing metadata, on_completion callback
449  started_ = true;
450 
451  start_tag_.Set(call_.call(),
452  [this](bool ok) {
453  reactor_->OnReadInitialMetadataDone(ok);
454  MaybeFinish();
455  },
456  &start_ops_, /*can_inline=*/false);
457  if (!start_corked_) {
458  start_ops_.SendInitialMetadata(&context_->send_initial_metadata_,
459  context_->initial_metadata_flags());
460  }
461  start_ops_.RecvInitialMetadata(context_);
462  start_ops_.set_core_cq_tag(&start_tag_);
463  call_.PerformOps(&start_ops_);
464 
465  // Also set up the read and write tags so that they don't have to be set up
466  // each time
467  write_tag_.Set(call_.call(),
468  [this](bool ok) {
469  reactor_->OnWriteDone(ok);
470  MaybeFinish();
471  },
472  &write_ops_, /*can_inline=*/false);
473  write_ops_.set_core_cq_tag(&write_tag_);
474 
475  read_tag_.Set(call_.call(),
476  [this](bool ok) {
477  reactor_->OnReadDone(ok);
478  MaybeFinish();
479  },
480  &read_ops_, /*can_inline=*/false);
481  read_ops_.set_core_cq_tag(&read_tag_);
482  if (read_ops_at_start_) {
483  call_.PerformOps(&read_ops_);
484  }
485 
486  if (write_ops_at_start_) {
487  call_.PerformOps(&write_ops_);
488  }
489 
490  if (writes_done_ops_at_start_) {
491  call_.PerformOps(&writes_done_ops_);
492  }
493 
494  finish_tag_.Set(call_.call(), [this](bool /*ok*/) { MaybeFinish(); },
495  &finish_ops_, /*can_inline=*/false);
496  finish_ops_.ClientRecvStatus(context_, &finish_status_);
497  finish_ops_.set_core_cq_tag(&finish_tag_);
498  call_.PerformOps(&finish_ops_);
499  }
500 
501  void Read(Response* msg) override {
502  read_ops_.RecvMessage(msg);
503  callbacks_outstanding_.fetch_add(1, std::memory_order_relaxed);
504  if (started_) {
505  call_.PerformOps(&read_ops_);
506  } else {
507  read_ops_at_start_ = true;
508  }
509  }
510 
511  void Write(const Request* msg, ::grpc::WriteOptions options) override {
512  if (start_corked_) {
513  write_ops_.SendInitialMetadata(&context_->send_initial_metadata_,
514  context_->initial_metadata_flags());
515  start_corked_ = false;
516  }
517 
518  if (options.is_last_message()) {
519  options.set_buffer_hint();
520  write_ops_.ClientSendClose();
521  }
522  // TODO(vjpai): don't assert
523  GPR_CODEGEN_ASSERT(write_ops_.SendMessagePtr(msg, options).ok());
524  callbacks_outstanding_.fetch_add(1, std::memory_order_relaxed);
525  if (started_) {
526  call_.PerformOps(&write_ops_);
527  } else {
528  write_ops_at_start_ = true;
529  }
530  }
531  void WritesDone() override {
532  if (start_corked_) {
533  writes_done_ops_.SendInitialMetadata(&context_->send_initial_metadata_,
534  context_->initial_metadata_flags());
535  start_corked_ = false;
536  }
537  writes_done_ops_.ClientSendClose();
538  writes_done_tag_.Set(call_.call(),
539  [this](bool ok) {
540  reactor_->OnWritesDoneDone(ok);
541  MaybeFinish();
542  },
543  &writes_done_ops_, /*can_inline=*/false);
544  writes_done_ops_.set_core_cq_tag(&writes_done_tag_);
545  callbacks_outstanding_.fetch_add(1, std::memory_order_relaxed);
546  if (started_) {
547  call_.PerformOps(&writes_done_ops_);
548  } else {
549  writes_done_ops_at_start_ = true;
550  }
551  }
552 
553  void AddHold(int holds) override {
554  callbacks_outstanding_.fetch_add(holds, std::memory_order_relaxed);
555  }
556  void RemoveHold() override { MaybeFinish(); }
557 
558  private:
559  friend class ClientCallbackReaderWriterFactory<Request, Response>;
560 
562  ::grpc_impl::ClientContext* context,
564  : context_(context),
565  call_(call),
566  reactor_(reactor),
567  start_corked_(context_->initial_metadata_corked_) {
568  this->BindReactor(reactor);
569  }
570 
571  ::grpc_impl::ClientContext* const context_;
572  grpc::internal::Call call_;
573  ClientBidiReactor<Request, Response>* const reactor_;
574 
577  start_ops_;
579  bool start_corked_;
580 
583  ::grpc::Status finish_status_;
584 
588  write_ops_;
590  bool write_ops_at_start_{false};
591 
594  writes_done_ops_;
596  bool writes_done_ops_at_start_{false};
597 
599  read_ops_;
601  bool read_ops_at_start_{false};
602 
603  // Minimum of 2 callbacks to pre-register for start and finish
604  std::atomic<intptr_t> callbacks_outstanding_{2};
605  bool started_{false};
606 };
607 
608 template <class Request, class Response>
609 class ClientCallbackReaderWriterFactory {
610  public:
611  static void Create(::grpc::ChannelInterface* channel,
612  const ::grpc::internal::RpcMethod& method,
613  ::grpc_impl::ClientContext* context,
615  grpc::internal::Call call =
616  channel->CreateCall(method, context, channel->CallbackCQ());
617 
622  reactor);
623  }
624 };
625 
626 template <class Response>
628  public:
629  // always allocated against a call arena, no memory free required
630  static void operator delete(void* /*ptr*/, std::size_t size) {
632  }
633 
634  // This operator should never be called as the memory should be freed as part
635  // of the arena destruction. It only exists to provide a matching operator
636  // delete to the operator new so that some compilers will not complain (see
637  // https://github.com/grpc/grpc/issues/11301) Note at the time of adding this
638  // there are no tests catching the compiler warning.
639  static void operator delete(void*, void*) { GPR_CODEGEN_ASSERT(false); }
640 
641  void MaybeFinish() {
642  if (GPR_UNLIKELY(callbacks_outstanding_.fetch_sub(
643  1, std::memory_order_acq_rel) == 1)) {
644  ::grpc::Status s = std::move(finish_status_);
645  auto* reactor = reactor_;
646  auto* call = call_.call();
647  this->~ClientCallbackReaderImpl();
649  reactor->OnDone(s);
650  }
651  }
652 
653  void StartCall() override {
654  // This call initiates two batches, plus any backlog, each with a callback
655  // 1. Send initial metadata (unless corked) + recv initial metadata
656  // 2. Any backlog
657  // 3. Recv trailing metadata, on_completion callback
658  started_ = true;
659 
660  start_tag_.Set(call_.call(),
661  [this](bool ok) {
662  reactor_->OnReadInitialMetadataDone(ok);
663  MaybeFinish();
664  },
665  &start_ops_, /*can_inline=*/false);
666  start_ops_.SendInitialMetadata(&context_->send_initial_metadata_,
667  context_->initial_metadata_flags());
668  start_ops_.RecvInitialMetadata(context_);
669  start_ops_.set_core_cq_tag(&start_tag_);
670  call_.PerformOps(&start_ops_);
671 
672  // Also set up the read tag so it doesn't have to be set up each time
673  read_tag_.Set(call_.call(),
674  [this](bool ok) {
675  reactor_->OnReadDone(ok);
676  MaybeFinish();
677  },
678  &read_ops_, /*can_inline=*/false);
679  read_ops_.set_core_cq_tag(&read_tag_);
680  if (read_ops_at_start_) {
681  call_.PerformOps(&read_ops_);
682  }
683 
684  finish_tag_.Set(call_.call(), [this](bool /*ok*/) { MaybeFinish(); },
685  &finish_ops_, /*can_inline=*/false);
686  finish_ops_.ClientRecvStatus(context_, &finish_status_);
687  finish_ops_.set_core_cq_tag(&finish_tag_);
688  call_.PerformOps(&finish_ops_);
689  }
690 
691  void Read(Response* msg) override {
692  read_ops_.RecvMessage(msg);
693  callbacks_outstanding_.fetch_add(1, std::memory_order_relaxed);
694  if (started_) {
695  call_.PerformOps(&read_ops_);
696  } else {
697  read_ops_at_start_ = true;
698  }
699  }
700 
701  void AddHold(int holds) override {
702  callbacks_outstanding_.fetch_add(holds, std::memory_order_relaxed);
703  }
704  void RemoveHold() override { MaybeFinish(); }
705 
706  private:
707  friend class ClientCallbackReaderFactory<Response>;
708 
709  template <class Request>
711  ::grpc_impl::ClientContext* context,
712  Request* request,
714  : context_(context), call_(call), reactor_(reactor) {
715  this->BindReactor(reactor);
716  // TODO(vjpai): don't assert
717  GPR_CODEGEN_ASSERT(start_ops_.SendMessagePtr(request).ok());
718  start_ops_.ClientSendClose();
719  }
720 
721  ::grpc_impl::ClientContext* const context_;
722  grpc::internal::Call call_;
723  ClientReadReactor<Response>* const reactor_;
724 
729  start_ops_;
731 
734  ::grpc::Status finish_status_;
735 
737  read_ops_;
739  bool read_ops_at_start_{false};
740 
741  // Minimum of 2 callbacks to pre-register for start and finish
742  std::atomic<intptr_t> callbacks_outstanding_{2};
743  bool started_{false};
744 };
745 
746 template <class Response>
747 class ClientCallbackReaderFactory {
748  public:
749  template <class Request>
750  static void Create(::grpc::ChannelInterface* channel,
751  const ::grpc::internal::RpcMethod& method,
752  ::grpc_impl::ClientContext* context,
753  const Request* request,
754  ClientReadReactor<Response>* reactor) {
755  grpc::internal::Call call =
756  channel->CreateCall(method, context, channel->CallbackCQ());
757 
760  call.call(), sizeof(ClientCallbackReaderImpl<Response>)))
761  ClientCallbackReaderImpl<Response>(call, context, request, reactor);
762  }
763 };
764 
765 template <class Request>
767  public:
768  // always allocated against a call arena, no memory free required
769  static void operator delete(void* /*ptr*/, std::size_t size) {
771  }
772 
773  // This operator should never be called as the memory should be freed as part
774  // of the arena destruction. It only exists to provide a matching operator
775  // delete to the operator new so that some compilers will not complain (see
776  // https://github.com/grpc/grpc/issues/11301) Note at the time of adding this
777  // there are no tests catching the compiler warning.
778  static void operator delete(void*, void*) { GPR_CODEGEN_ASSERT(false); }
779 
780  void MaybeFinish() {
781  if (GPR_UNLIKELY(callbacks_outstanding_.fetch_sub(
782  1, std::memory_order_acq_rel) == 1)) {
783  ::grpc::Status s = std::move(finish_status_);
784  auto* reactor = reactor_;
785  auto* call = call_.call();
786  this->~ClientCallbackWriterImpl();
788  reactor->OnDone(s);
789  }
790  }
791 
792  void StartCall() override {
793  // This call initiates two batches, plus any backlog, each with a callback
794  // 1. Send initial metadata (unless corked) + recv initial metadata
795  // 2. Any backlog
796  // 3. Recv trailing metadata, on_completion callback
797  started_ = true;
798 
799  start_tag_.Set(call_.call(),
800  [this](bool ok) {
801  reactor_->OnReadInitialMetadataDone(ok);
802  MaybeFinish();
803  },
804  &start_ops_, /*can_inline=*/false);
805  if (!start_corked_) {
806  start_ops_.SendInitialMetadata(&context_->send_initial_metadata_,
807  context_->initial_metadata_flags());
808  }
809  start_ops_.RecvInitialMetadata(context_);
810  start_ops_.set_core_cq_tag(&start_tag_);
811  call_.PerformOps(&start_ops_);
812 
813  // Also set up the read and write tags so that they don't have to be set up
814  // each time
815  write_tag_.Set(call_.call(),
816  [this](bool ok) {
817  reactor_->OnWriteDone(ok);
818  MaybeFinish();
819  },
820  &write_ops_, /*can_inline=*/false);
821  write_ops_.set_core_cq_tag(&write_tag_);
822 
823  if (write_ops_at_start_) {
824  call_.PerformOps(&write_ops_);
825  }
826 
827  if (writes_done_ops_at_start_) {
828  call_.PerformOps(&writes_done_ops_);
829  }
830 
831  finish_tag_.Set(call_.call(), [this](bool /*ok*/) { MaybeFinish(); },
832  &finish_ops_, /*can_inline=*/false);
833  finish_ops_.ClientRecvStatus(context_, &finish_status_);
834  finish_ops_.set_core_cq_tag(&finish_tag_);
835  call_.PerformOps(&finish_ops_);
836  }
837 
838  void Write(const Request* msg, ::grpc::WriteOptions options) override {
839  if (start_corked_) {
840  write_ops_.SendInitialMetadata(&context_->send_initial_metadata_,
841  context_->initial_metadata_flags());
842  start_corked_ = false;
843  }
844 
845  if (options.is_last_message()) {
846  options.set_buffer_hint();
847  write_ops_.ClientSendClose();
848  }
849  // TODO(vjpai): don't assert
850  GPR_CODEGEN_ASSERT(write_ops_.SendMessagePtr(msg, options).ok());
851  callbacks_outstanding_.fetch_add(1, std::memory_order_relaxed);
852  if (started_) {
853  call_.PerformOps(&write_ops_);
854  } else {
855  write_ops_at_start_ = true;
856  }
857  }
858  void WritesDone() override {
859  if (start_corked_) {
860  writes_done_ops_.SendInitialMetadata(&context_->send_initial_metadata_,
861  context_->initial_metadata_flags());
862  start_corked_ = false;
863  }
864  writes_done_ops_.ClientSendClose();
865  writes_done_tag_.Set(call_.call(),
866  [this](bool ok) {
867  reactor_->OnWritesDoneDone(ok);
868  MaybeFinish();
869  },
870  &writes_done_ops_, /*can_inline=*/false);
871  writes_done_ops_.set_core_cq_tag(&writes_done_tag_);
872  callbacks_outstanding_.fetch_add(1, std::memory_order_relaxed);
873  if (started_) {
874  call_.PerformOps(&writes_done_ops_);
875  } else {
876  writes_done_ops_at_start_ = true;
877  }
878  }
879 
880  void AddHold(int holds) override {
881  callbacks_outstanding_.fetch_add(holds, std::memory_order_relaxed);
882  }
883  void RemoveHold() override { MaybeFinish(); }
884 
885  private:
886  friend class ClientCallbackWriterFactory<Request>;
887 
888  template <class Response>
890  ::grpc_impl::ClientContext* context,
891  Response* response,
893  : context_(context),
894  call_(call),
895  reactor_(reactor),
896  start_corked_(context_->initial_metadata_corked_) {
897  this->BindReactor(reactor);
898  finish_ops_.RecvMessage(response);
899  finish_ops_.AllowNoMessage();
900  }
901 
902  ::grpc_impl::ClientContext* const context_;
903  grpc::internal::Call call_;
904  ClientWriteReactor<Request>* const reactor_;
905 
908  start_ops_;
910  bool start_corked_;
911 
914  finish_ops_;
916  ::grpc::Status finish_status_;
917 
921  write_ops_;
923  bool write_ops_at_start_{false};
924 
927  writes_done_ops_;
929  bool writes_done_ops_at_start_{false};
930 
931  // Minimum of 2 callbacks to pre-register for start and finish
932  std::atomic<intptr_t> callbacks_outstanding_{2};
933  bool started_{false};
934 };
935 
936 template <class Request>
937 class ClientCallbackWriterFactory {
938  public:
939  template <class Response>
940  static void Create(::grpc::ChannelInterface* channel,
941  const ::grpc::internal::RpcMethod& method,
942  ::grpc_impl::ClientContext* context, Response* response,
943  ClientWriteReactor<Request>* reactor) {
944  grpc::internal::Call call =
945  channel->CreateCall(method, context, channel->CallbackCQ());
946 
949  call.call(), sizeof(ClientCallbackWriterImpl<Request>)))
950  ClientCallbackWriterImpl<Request>(call, context, response, reactor);
951  }
952 };
953 
955  public:
956  // always allocated against a call arena, no memory free required
957  static void operator delete(void* /*ptr*/, std::size_t size) {
959  }
960 
961  // This operator should never be called as the memory should be freed as part
962  // of the arena destruction. It only exists to provide a matching operator
963  // delete to the operator new so that some compilers will not complain (see
964  // https://github.com/grpc/grpc/issues/11301) Note at the time of adding this
965  // there are no tests catching the compiler warning.
966  static void operator delete(void*, void*) { GPR_CODEGEN_ASSERT(false); }
967 
968  void StartCall() override {
969  // This call initiates two batches, each with a callback
970  // 1. Send initial metadata + write + writes done + recv initial metadata
971  // 2. Read message, recv trailing metadata
972  started_ = true;
973 
974  start_tag_.Set(call_.call(),
975  [this](bool ok) {
976  reactor_->OnReadInitialMetadataDone(ok);
977  MaybeFinish();
978  },
979  &start_ops_, /*can_inline=*/false);
980  start_ops_.SendInitialMetadata(&context_->send_initial_metadata_,
981  context_->initial_metadata_flags());
982  start_ops_.RecvInitialMetadata(context_);
983  start_ops_.set_core_cq_tag(&start_tag_);
984  call_.PerformOps(&start_ops_);
985 
986  finish_tag_.Set(call_.call(), [this](bool /*ok*/) { MaybeFinish(); },
987  &finish_ops_, /*can_inline=*/false);
988  finish_ops_.ClientRecvStatus(context_, &finish_status_);
989  finish_ops_.set_core_cq_tag(&finish_tag_);
990  call_.PerformOps(&finish_ops_);
991  }
992 
993  void MaybeFinish() {
994  if (GPR_UNLIKELY(callbacks_outstanding_.fetch_sub(
995  1, std::memory_order_acq_rel) == 1)) {
996  ::grpc::Status s = std::move(finish_status_);
997  auto* reactor = reactor_;
998  auto* call = call_.call();
999  this->~ClientCallbackUnaryImpl();
1001  reactor->OnDone(s);
1002  }
1003  }
1004 
1005  private:
1007 
1008  template <class Request, class Response>
1010  ::grpc_impl::ClientContext* context, Request* request,
1011  Response* response, ClientUnaryReactor* reactor)
1012  : context_(context), call_(call), reactor_(reactor) {
1013  this->BindReactor(reactor);
1014  // TODO(vjpai): don't assert
1015  GPR_CODEGEN_ASSERT(start_ops_.SendMessagePtr(request).ok());
1016  start_ops_.ClientSendClose();
1017  finish_ops_.RecvMessage(response);
1018  finish_ops_.AllowNoMessage();
1019  }
1020 
1021  ::grpc_impl::ClientContext* const context_;
1022  grpc::internal::Call call_;
1023  ClientUnaryReactor* const reactor_;
1024 
1029  start_ops_;
1031 
1034  finish_ops_;
1036  ::grpc::Status finish_status_;
1037 
1038  // This call will have 2 callbacks: start and finish
1039  std::atomic<intptr_t> callbacks_outstanding_{2};
1040  bool started_{false};
1041 };
1042 
1044  public:
1045  template <class Request, class Response>
1046  static void Create(::grpc::ChannelInterface* channel,
1047  const ::grpc::internal::RpcMethod& method,
1048  ::grpc_impl::ClientContext* context,
1049  const Request* request, Response* response,
1050  ClientUnaryReactor* reactor) {
1051  grpc::internal::Call call =
1052  channel->CreateCall(method, context, channel->CallbackCQ());
1053 
1055 
1057  call.call(), sizeof(ClientCallbackUnaryImpl)))
1058  ClientCallbackUnaryImpl(call, context, request, response, reactor);
1059  }
1060 };
1061 
1062 } // namespace internal
1063 } // namespace grpc_impl
1064 #endif // GRPCPP_IMPL_CODEGEN_CLIENT_CALLBACK_IMPL_H
grpc::internal::CallbackWithSuccessTag
CallbackWithSuccessTag can be reused multiple times, and will be used in this fashion for streaming o...
Definition: callback_common.h:136
grpc::internal::CallOpSendMessage::SendMessagePtr
Status SendMessagePtr(const M *message, WriteOptions options) GRPC_MUST_USE_RESULT
Send message using options for the write.
Definition: call_op_set.h:409
grpc_impl::ClientCallbackWriter::WritesDone
virtual void WritesDone()=0
grpc_impl::internal::ClientCallbackWriterImpl::StartCall
void StartCall() override
Definition: client_callback_impl.h:792
grpc::internal::CallOpRecvInitialMetadata
Definition: call_op_set.h:694
grpc_impl::internal::ClientCallbackReaderImpl::RemoveHold
void RemoveHold() override
Definition: client_callback_impl.h:704
grpc_impl::internal::ClientCallbackWriterImpl::Write
void Write(const Request *msg, ::grpc::WriteOptions options) override
Definition: client_callback_impl.h:838
grpc_impl::internal::ClientCallbackReaderWriterFactory
Definition: channel_interface.h:48
grpc_impl::ClientCallbackWriter
Definition: client_callback_impl.h:151
grpc::internal::CallOpClientSendClose
Definition: call_op_set.h:592
grpc_impl::ClientUnaryReactor::StartCall
void StartCall()
Definition: client_callback_impl.h:390
grpc_impl::internal::ClientCallbackWriterImpl
Definition: client_callback_impl.h:766
grpc_impl::ClientReadReactor::OnReadDone
virtual void OnReadDone(bool)
Definition: client_callback_impl.h:333
grpc_impl::internal::ClientCallbackReaderImpl::Read
void Read(Response *msg) override
Definition: client_callback_impl.h:691
grpc_call_arena_alloc
GRPCAPI void * grpc_call_arena_alloc(grpc_call *call, size_t size)
Allocate memory in the grpc_call arena: this memory is automatically discarded at call completion.
grpc::internal::CallOpGenericRecvMessage
Definition: call_op_set.h:514
grpc_impl::ClientCallbackWriter::Write
void Write(const Request *req)
Definition: client_callback_impl.h:155
grpc_impl::ClientBidiReactor::StartRead
void StartRead(Response *resp)
Initiate a read operation (or post it for later initiation if StartCall has not yet been invoked).
Definition: client_callback_impl.h:207
grpc
This header provides an object that reads bytes directly from a grpc::ByteBuffer, via the ZeroCopyInp...
Definition: alarm.h:24
grpc::internal::CallOpSet
Primary implementation of CallOpSetInterface.
Definition: call_op_set.h:824
status.h
grpc::CoreCodegenInterface::grpc_call_ref
virtual void grpc_call_ref(grpc_call *call)=0
grpc::internal::CallOpSendMessage
Definition: call_op_set.h:286
grpc::WriteOptions::set_last_message
WriteOptions & set_last_message()
last-message bit: indicates this is the last message in a stream client-side: makes Write the equival...
Definition: call_op_set.h:161
grpc_impl::ClientCallbackUnary::StartCall
virtual void StartCall()=0
grpc_impl::internal::ClientCallbackWriterImpl::MaybeFinish
void MaybeFinish()
Definition: client_callback_impl.h:780
grpc::CoreCodegenInterface::grpc_call_arena_alloc
virtual void * grpc_call_arena_alloc(grpc_call *call, size_t length)=0
grpc_impl::ClientCallbackReaderWriter::RemoveHold
virtual void RemoveHold()=0
grpc_impl::ClientUnaryReactor::OnReadInitialMetadataDone
virtual void OnReadInitialMetadataDone(bool)
Definition: client_callback_impl.h:392
grpc_impl::ClientCallbackReaderWriter::~ClientCallbackReaderWriter
virtual ~ClientCallbackReaderWriter()
Definition: client_callback_impl.h:121
grpc::internal::CallOpGenericRecvMessage::RecvMessage
void RecvMessage(R *message)
Definition: call_op_set.h:520
config.h
grpc_impl::ClientCallbackReaderWriter::WritesDone
virtual void WritesDone()=0
grpc_impl::ClientWriteReactor::StartWriteLast
void StartWriteLast(const Request *req, ::grpc::WriteOptions options)
Definition: client_callback_impl.h:355
grpc_impl::internal::CallbackUnaryCallImpl
Definition: channel_interface.h:38
grpc_impl::ClientUnaryReactor::~ClientUnaryReactor
virtual ~ClientUnaryReactor()
Definition: client_callback_impl.h:388
grpc::internal::Call
Straightforward wrapping of the C call object.
Definition: call.h:38
grpc_impl::internal::ClientCallbackWriterFactory
Definition: channel_interface.h:52
core_codegen_interface.h
grpc_impl::internal::ClientCallbackUnaryImpl::StartCall
void StartCall() override
Definition: client_callback_impl.h:968
grpc::internal::CallOpSendInitialMetadata
Definition: call_op_set.h:216
grpc_impl::ClientCallbackWriter::BindReactor
void BindReactor(ClientWriteReactor< Request > *reactor)
Definition: client_callback_impl.h:166
grpc_impl::ClientBidiReactor::RemoveHold
void RemoveHold()
Definition: client_callback_impl.h:272
grpc_impl::ClientCallbackReaderWriter::StartCall
virtual void StartCall()=0
grpc::internal::CallbackWithStatusTag
Definition: callback_common.h:68
grpc_impl::ClientReadReactor::StartRead
void StartRead(Response *resp)
Definition: client_callback_impl.h:325
grpc::Status::ok
bool ok() const
Is the status OK?
Definition: status.h:118
grpc_impl::ClientBidiReactor::StartWriteLast
void StartWriteLast(const Request *req, ::grpc::WriteOptions options)
Initiate/post a write operation with specified options and an indication that this is the last write ...
Definition: client_callback_impl.h:238
grpc::internal::CallOpSendInitialMetadata::SendInitialMetadata
void SendInitialMetadata(std::multimap< grpc::string, grpc::string > *metadata, uint32_t flags)
Definition: call_op_set.h:222
grpc_impl::internal::ClientCallbackWriterFactory::Create
static void Create(::grpc::ChannelInterface *channel, const ::grpc::internal::RpcMethod &method, ::grpc_impl::ClientContext *context, Response *response, ClientWriteReactor< Request > *reactor)
Definition: client_callback_impl.h:940
grpc_impl::ClientCallbackReader::StartCall
virtual void StartCall()=0
grpc_impl::ClientCallbackWriter::StartCall
virtual void StartCall()=0
grpc::internal::CallOpRecvInitialMetadata::RecvInitialMetadata
void RecvInitialMetadata(::grpc_impl::ClientContext *context)
Definition: call_op_set.h:698
grpc_impl::ClientBidiReactor
ClientBidiReactor is the interface for a bidirectional streaming RPC.
Definition: client_callback_impl.h:108
grpc_impl::ClientReadReactor::RemoveHold
void RemoveHold()
Definition: client_callback_impl.h:329
grpc_impl::internal::ClientCallbackReaderImpl::StartCall
void StartCall() override
Definition: client_callback_impl.h:653
grpc_impl::internal::ClientCallbackReaderImpl::AddHold
void AddHold(int holds) override
Definition: client_callback_impl.h:701
grpc::Status
Did it work? If it didn't, why?
Definition: status.h:31
grpc_impl::ClientCallbackReader::Read
virtual void Read(Response *resp)=0
grpc_impl::ClientBidiReactor::StartWrite
void StartWrite(const Request *req)
Initiate a write operation (or post it for later initiation if StartCall has not yet been invoked).
Definition: client_callback_impl.h:215
grpc_impl::ClientReadReactor
ClientReadReactor is the interface for a server-streaming RPC.
Definition: client_callback_impl.h:110
grpc_impl::internal::ClientCallbackReaderWriterImpl::Write
void Write(const Request *msg, ::grpc::WriteOptions options) override
Definition: client_callback_impl.h:511
grpc_impl::ClientCallbackReader
Definition: client_callback_impl.h:136
grpc_impl::ClientBidiReactor::OnReadDone
virtual void OnReadDone(bool)
Notifies the application that a StartRead operation completed.
Definition: client_callback_impl.h:293
grpc_impl::ClientBidiReactor::AddMultipleHolds
void AddMultipleHolds(int holds)
Definition: client_callback_impl.h:271
grpc_impl::internal::ClientCallbackReaderWriterImpl
Definition: client_callback_impl.h:416
grpc_impl::ClientBidiReactor::~ClientBidiReactor
virtual ~ClientBidiReactor()
Definition: client_callback_impl.h:194
grpc_impl::ClientCallbackUnary
Definition: client_callback_impl.h:171
grpc_impl::internal::ClientCallbackReaderWriterImpl::RemoveHold
void RemoveHold() override
Definition: client_callback_impl.h:556
grpc_impl::ClientCallbackWriter::RemoveHold
virtual void RemoveHold()=0
grpc_impl::ClientWriteReactor::OnDone
virtual void OnDone(const ::grpc::Status &)
Definition: client_callback_impl.h:364
grpc_impl::ClientReadReactor::~ClientReadReactor
virtual ~ClientReadReactor()
Definition: client_callback_impl.h:322
grpc_impl::ClientUnaryReactor
ClientUnaryReactor is a reactor-style interface for a unary RPC.
Definition: client_callback_impl.h:386
GPR_UNLIKELY
#define GPR_UNLIKELY(x)
Definition: port_platform.h:709
grpc_impl::ClientCallbackReaderWriter::Write
virtual void Write(const Request *req, ::grpc::WriteOptions options)=0
grpc_impl::ClientBidiReactor::AddHold
void AddHold()
Holds are needed if (and only if) this stream has operations that take place on it after StartCall bu...
Definition: client_callback_impl.h:270
grpc::experimental::ClientReadReactor
::grpc_impl::ClientReadReactor< Response > ClientReadReactor
Definition: client_callback.h:63
grpc::ChannelInterface
Codegen interface for grpc::Channel.
Definition: channel_interface.h:74
grpc_impl::internal::ClientCallbackReaderImpl::MaybeFinish
void MaybeFinish()
Definition: client_callback_impl.h:641
grpc_impl::internal::ClientCallbackReaderWriterImpl::AddHold
void AddHold(int holds) override
Definition: client_callback_impl.h:553
grpc_impl::ClientWriteReactor::StartCall
void StartCall()
Definition: client_callback_impl.h:348
grpc_impl::ClientWriteReactor::OnWriteDone
virtual void OnWriteDone(bool)
Definition: client_callback_impl.h:366
grpc_impl::ClientBidiReactor::OnWritesDoneDone
virtual void OnWritesDoneDone(bool)
Notifies the application that a StartWritesDone operation completed.
Definition: client_callback_impl.h:307
grpc_impl::internal::ClientCallbackWriterImpl::RemoveHold
void RemoveHold() override
Definition: client_callback_impl.h:883
grpc_impl::ClientBidiReactor::StartCall
void StartCall()
Activate the RPC and initiate any reads or writes that have been Start'ed before this call.
Definition: client_callback_impl.h:200
grpc_impl::ClientWriteReactor::RemoveHold
void RemoveHold()
Definition: client_callback_impl.h:362
grpc_impl::ClientCallbackUnary::~ClientCallbackUnary
virtual ~ClientCallbackUnary()
Definition: client_callback_impl.h:173
grpc_impl::ClientReadReactor::OnDone
virtual void OnDone(const ::grpc::Status &)
Definition: client_callback_impl.h:331
grpc_impl::ClientReadReactor::StartCall
void StartCall()
Definition: client_callback_impl.h:324
grpc_impl::ClientWriteReactor::StartWritesDone
void StartWritesDone()
Definition: client_callback_impl.h:358
grpc_impl::ClientCallbackReaderWriter::Read
virtual void Read(Response *resp)=0
grpc::protobuf::util::Status
::google::protobuf::util::Status Status
Definition: config_protobuf.h:90
grpc_impl::internal::ClientCallbackReaderImpl
Definition: client_callback_impl.h:627
grpc_impl::internal::ClientCallbackUnaryFactory::Create
static void Create(::grpc::ChannelInterface *channel, const ::grpc::internal::RpcMethod &method, ::grpc_impl::ClientContext *context, const Request *request, Response *response, ClientUnaryReactor *reactor)
Definition: client_callback_impl.h:1046
grpc_impl::ClientCallbackReader::AddHold
virtual void AddHold(int holds)=0
grpc_impl::ClientReadReactor::OnReadInitialMetadataDone
virtual void OnReadInitialMetadataDone(bool)
Definition: client_callback_impl.h:332
grpc_impl::internal::ClientCallbackReaderWriterImpl::StartCall
void StartCall() override
Definition: client_callback_impl.h:443
grpc::CoreCodegenInterface::grpc_call_unref
virtual void grpc_call_unref(grpc_call *call)=0
grpc_impl::internal::ClientCallbackReaderFactory
Definition: channel_interface.h:50
grpc_impl::ClientBidiReactor::StartWritesDone
void StartWritesDone()
Indicate that the RPC will have no more write operations.
Definition: client_callback_impl.h:247
grpc_impl::ClientCallbackReader::RemoveHold
virtual void RemoveHold()=0
grpc_impl::ClientWriteReactor::~ClientWriteReactor
virtual ~ClientWriteReactor()
Definition: client_callback_impl.h:346
grpc_impl::ClientCallbackReaderWriter
Definition: client_callback_impl.h:119
grpc_impl::ClientBidiReactor::OnDone
virtual void OnDone(const ::grpc::Status &)
Notifies the application that all operations associated with this RPC have completed and provides the...
Definition: client_callback_impl.h:278
grpc::WriteOptions
Per-message write options.
Definition: call_op_set.h:79
grpc_impl::ClientReadReactor::AddMultipleHolds
void AddMultipleHolds(int holds)
Definition: client_callback_impl.h:328
callback_common.h
grpc::internal::CallbackWithSuccessTag::Set
void Set(grpc_call *call, std::function< void(bool)> f, CompletionQueueTag *ops, bool can_inline)
Definition: callback_common.h:164
grpc_impl::ClientWriteReactor
ClientWriteReactor is the interface for a client-streaming RPC.
Definition: client_callback_impl.h:112
grpc_impl::ClientCallbackReader::~ClientCallbackReader
virtual ~ClientCallbackReader()
Definition: client_callback_impl.h:138
grpc_impl::internal::ClientCallbackUnaryImpl::MaybeFinish
void MaybeFinish()
Definition: client_callback_impl.h:993
grpc_impl::CompletionQueue
A thin wrapper around grpc_completion_queue (see src/core/lib/surface/completion_queue....
Definition: completion_queue_impl.h:103
channel_interface.h
grpc_impl::internal::ClientCallbackReaderWriterImpl::MaybeFinish
void MaybeFinish()
Definition: client_callback_impl.h:431
grpc_impl::internal::ClientCallbackReaderFactory::Create
static void Create(::grpc::ChannelInterface *channel, const ::grpc::internal::RpcMethod &method, ::grpc_impl::ClientContext *context, const Request *request, ClientReadReactor< Response > *reactor)
Definition: client_callback_impl.h:750
grpc_impl::ClientWriteReactor::AddMultipleHolds
void AddMultipleHolds(int holds)
Definition: client_callback_impl.h:361
grpc_impl::internal::ClientCallbackUnaryFactory
Definition: client_callback_impl.h:1043
grpc_impl::internal::ClientCallbackReaderWriterFactory::Create
static void Create(::grpc::ChannelInterface *channel, const ::grpc::internal::RpcMethod &method, ::grpc_impl::ClientContext *context, ClientBidiReactor< Request, Response > *reactor)
Definition: client_callback_impl.h:611
grpc_impl::ClientCallbackWriter::WriteLast
void WriteLast(const Request *req, ::grpc::WriteOptions options)
Definition: client_callback_impl.h:157
grpc::internal::Call::PerformOps
void PerformOps(CallOpSetInterface *ops)
Definition: call.h:68
grpc::internal::Call::call
grpc_call * call() const
Definition: call.h:72
grpc_impl::ClientCallbackReader::BindReactor
void BindReactor(ClientReadReactor< Response > *reactor)
Definition: client_callback_impl.h:145
call.h
call_op_set.h
grpc::internal::CallOpClientRecvStatus
Definition: call_op_set.h:742
grpc::WriteOptions::set_buffer_hint
WriteOptions & set_buffer_hint()
Sets flag indicating that the write may be buffered and need not go out on the wire immediately.
Definition: call_op_set.h:122
grpc_impl::ClientCallbackUnary::BindReactor
void BindReactor(ClientUnaryReactor *reactor)
Definition: client_callback_impl.h:401
grpc_impl::internal::CallbackUnaryCallImpl::CallbackUnaryCallImpl
CallbackUnaryCallImpl(::grpc::ChannelInterface *channel, const ::grpc::internal::RpcMethod &method, ::grpc_impl::ClientContext *context, const InputMessage *request, OutputMessage *result, std::function< void(::grpc::Status)> on_completion)
Definition: client_callback_impl.h:58
grpc_impl::internal::ClientCallbackReaderWriterImpl::WritesDone
void WritesDone() override
Definition: client_callback_impl.h:531
grpc_impl
An Alarm posts the user-provided tag to its associated completion queue or invokes the user-provided ...
Definition: alarm_impl.h:33
grpc_impl::ClientWriteReactor::OnWritesDoneDone
virtual void OnWritesDoneDone(bool)
Definition: client_callback_impl.h:367
grpc_impl::ClientWriteReactor::StartWrite
void StartWrite(const Request *req)
Definition: client_callback_impl.h:349
grpc_impl::ClientUnaryReactor::OnDone
virtual void OnDone(const ::grpc::Status &)
Definition: client_callback_impl.h:391
grpc_impl::ClientBidiReactor::StartWrite
void StartWrite(const Request *req, ::grpc::WriteOptions options)
Initiate/post a write operation with specified options.
Definition: client_callback_impl.h:225
grpc_impl::ClientCallbackReaderWriter::AddHold
virtual void AddHold(int holds)=0
grpc_impl::internal::ClientCallbackUnaryImpl
Definition: client_callback_impl.h:954
grpc::g_core_codegen_interface
CoreCodegenInterface * g_core_codegen_interface
Definition: completion_queue_impl.h:93
GPR_CODEGEN_ASSERT
#define GPR_CODEGEN_ASSERT(x)
Codegen specific version of GPR_ASSERT.
Definition: core_codegen_interface.h:146
grpc_impl::internal::CallbackUnaryCall
void CallbackUnaryCall(::grpc::ChannelInterface *channel, const ::grpc::internal::RpcMethod &method, ::grpc_impl::ClientContext *context, const InputMessage *request, OutputMessage *result, std::function< void(::grpc::Status)> on_completion)
Perform a callback-based unary call TODO(vjpai): Combine as much as possible with the blocking unary ...
Definition: client_callback_impl.h:46
grpc::WriteOptions::is_last_message
bool is_last_message() const
Get value for the flag indicating that this is the last message, and should be coalesced with trailin...
Definition: call_op_set.h:186
grpc_impl::ClientContext
A ClientContext allows the person implementing a service client to:
Definition: client_context_impl.h:184
grpc_impl::ClientWriteReactor::AddHold
void AddHold()
Definition: client_callback_impl.h:360
grpc_impl::internal::ClientCallbackWriterImpl::WritesDone
void WritesDone() override
Definition: client_callback_impl.h:858
grpc_impl::ClientCallbackReaderWriter::BindReactor
void BindReactor(ClientBidiReactor< Request, Response > *reactor)
Definition: client_callback_impl.h:130
grpc_impl::ClientWriteReactor::StartWrite
void StartWrite(const Request *req, ::grpc::WriteOptions options)
Definition: client_callback_impl.h:352
grpc::experimental::ClientBidiReactor
::grpc_impl::ClientBidiReactor< Request, Response > ClientBidiReactor
Definition: client_callback.h:69
grpc_impl::ClientReadReactor::AddHold
void AddHold()
Definition: client_callback_impl.h:327
grpc::internal::CallOpRecvMessage
Definition: byte_buffer.h:58
grpc::ClientContext
::grpc_impl::ClientContext ClientContext
Definition: client_context.h:26
grpc_impl::internal::ClientCallbackReaderWriterImpl::Read
void Read(Response *msg) override
Definition: client_callback_impl.h:501
grpc_impl::ClientCallbackWriter::~ClientCallbackWriter
virtual ~ClientCallbackWriter()
Definition: client_callback_impl.h:153
grpc::internal::CallOpClientSendClose::ClientSendClose
void ClientSendClose()
Definition: call_op_set.h:596
grpc_impl::ClientBidiReactor::OnReadInitialMetadataDone
virtual void OnReadInitialMetadataDone(bool)
Notifies the application that a read of initial metadata from the server is done.
Definition: client_callback_impl.h:287
grpc_impl::ClientCallbackWriter::AddHold
virtual void AddHold(int holds)=0
grpc::internal::CallOpGenericRecvMessage::AllowNoMessage
void AllowNoMessage()
Definition: call_op_set.h:529
grpc::internal::CallOpSet::set_core_cq_tag
void set_core_cq_tag(void *core_cq_tag)
set_core_cq_tag is used to provide a different core CQ tag than "this".
Definition: call_op_set.h:913
grpc::experimental::ClientWriteReactor
::grpc_impl::ClientWriteReactor< Request > ClientWriteReactor
Definition: client_callback.h:66
grpc_impl::ClientWriteReactor::OnReadInitialMetadataDone
virtual void OnReadInitialMetadataDone(bool)
Definition: client_callback_impl.h:365
grpc::internal::CallOpRecvMessage::RecvMessage
void RecvMessage(R *message)
Definition: call_op_set.h:429
grpc_impl::internal::ClientCallbackWriterImpl::AddHold
void AddHold(int holds) override
Definition: client_callback_impl.h:880
grpc::Channel
::grpc_impl::Channel Channel
Definition: channel.h:26
grpc_impl::ClientBidiReactor::OnWriteDone
virtual void OnWriteDone(bool)
Notifies the application that a StartWrite operation completed.
Definition: client_callback_impl.h:299
grpc::internal::CallOpClientRecvStatus::ClientRecvStatus
void ClientRecvStatus(::grpc_impl::ClientContext *context, Status *status)
Definition: call_op_set.h:747