GRPC C++  1.30.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 
271  void AddHold() { AddMultipleHolds(1); }
272  void AddMultipleHolds(int holds) {
273  GPR_CODEGEN_DEBUG_ASSERT(holds > 0);
274  stream_->AddHold(holds);
275  }
276  void RemoveHold() { stream_->RemoveHold(); }
277 
285  virtual void OnDone(const ::grpc::Status& /*s*/) {}
286 
295  virtual void OnReadInitialMetadataDone(bool /*ok*/) {}
296 
301  virtual void OnReadDone(bool /*ok*/) {}
302 
308  virtual void OnWriteDone(bool /*ok*/) {}
309 
317  virtual void OnWritesDoneDone(bool /*ok*/) {}
318 
319  private:
320  friend class ClientCallbackReaderWriter<Request, Response>;
321  void BindStream(ClientCallbackReaderWriter<Request, Response>* stream) {
322  stream_ = stream;
323  }
325 };
326 
329 template <class Response>
330 class ClientReadReactor {
331  public:
332  virtual ~ClientReadReactor() {}
333 
334  void StartCall() { reader_->StartCall(); }
335  void StartRead(Response* resp) { reader_->Read(resp); }
336 
337  void AddHold() { AddMultipleHolds(1); }
338  void AddMultipleHolds(int holds) {
339  GPR_CODEGEN_DEBUG_ASSERT(holds > 0);
340  reader_->AddHold(holds);
341  }
342  void RemoveHold() { reader_->RemoveHold(); }
343 
344  virtual void OnDone(const ::grpc::Status& /*s*/) {}
345  virtual void OnReadInitialMetadataDone(bool /*ok*/) {}
346  virtual void OnReadDone(bool /*ok*/) {}
347 
348  private:
349  friend class ClientCallbackReader<Response>;
350  void BindReader(ClientCallbackReader<Response>* reader) { reader_ = reader; }
352 };
353 
356 template <class Request>
357 class ClientWriteReactor {
358  public:
359  virtual ~ClientWriteReactor() {}
360 
361  void StartCall() { writer_->StartCall(); }
362  void StartWrite(const Request* req) {
363  StartWrite(req, ::grpc::WriteOptions());
364  }
365  void StartWrite(const Request* req, ::grpc::WriteOptions options) {
366  writer_->Write(req, std::move(options));
367  }
368  void StartWriteLast(const Request* req, ::grpc::WriteOptions options) {
369  StartWrite(req, std::move(options.set_last_message()));
370  }
371  void StartWritesDone() { writer_->WritesDone(); }
372 
373  void AddHold() { AddMultipleHolds(1); }
374  void AddMultipleHolds(int holds) {
375  GPR_CODEGEN_DEBUG_ASSERT(holds > 0);
376  writer_->AddHold(holds);
377  }
378  void RemoveHold() { writer_->RemoveHold(); }
379 
380  virtual void OnDone(const ::grpc::Status& /*s*/) {}
381  virtual void OnReadInitialMetadataDone(bool /*ok*/) {}
382  virtual void OnWriteDone(bool /*ok*/) {}
383  virtual void OnWritesDoneDone(bool /*ok*/) {}
384 
385  private:
386  friend class ClientCallbackWriter<Request>;
387  void BindWriter(ClientCallbackWriter<Request>* writer) { writer_ = writer; }
389 };
390 
403  public:
404  virtual ~ClientUnaryReactor() {}
405 
406  void StartCall() { call_->StartCall(); }
407  virtual void OnDone(const ::grpc::Status& /*s*/) {}
408  virtual void OnReadInitialMetadataDone(bool /*ok*/) {}
409 
410  private:
411  friend class ClientCallbackUnary;
412  void BindCall(ClientCallbackUnary* call) { call_ = call; }
413  ClientCallbackUnary* call_;
414 };
415 
416 // Define function out-of-line from class to avoid forward declaration issue
418  reactor->BindCall(this);
419 }
420 
421 namespace internal {
422 
423 // Forward declare factory classes for friendship
424 template <class Request, class Response>
425 class ClientCallbackReaderWriterFactory;
426 template <class Response>
427 class ClientCallbackReaderFactory;
428 template <class Request>
429 class ClientCallbackWriterFactory;
430 
431 template <class Request, class Response>
433  : public ClientCallbackReaderWriter<Request, Response> {
434  public:
435  // always allocated against a call arena, no memory free required
436  static void operator delete(void* /*ptr*/, std::size_t size) {
438  }
439 
440  // This operator should never be called as the memory should be freed as part
441  // of the arena destruction. It only exists to provide a matching operator
442  // delete to the operator new so that some compilers will not complain (see
443  // https://github.com/grpc/grpc/issues/11301) Note at the time of adding this
444  // there are no tests catching the compiler warning.
445  static void operator delete(void*, void*) { GPR_CODEGEN_ASSERT(false); }
446 
447  void MaybeFinish() {
448  if (GPR_UNLIKELY(callbacks_outstanding_.fetch_sub(
449  1, std::memory_order_acq_rel) == 1)) {
450  ::grpc::Status s = std::move(finish_status_);
451  auto* reactor = reactor_;
452  auto* call = call_.call();
455  reactor->OnDone(s);
456  }
457  }
458 
459  void StartCall() override {
460  // This call initiates two batches, plus any backlog, each with a callback
461  // 1. Send initial metadata (unless corked) + recv initial metadata
462  // 2. Any read backlog
463  // 3. Any write backlog
464  // 4. Recv trailing metadata, on_completion callback
465  started_ = true;
466 
467  start_tag_.Set(call_.call(),
468  [this](bool ok) {
469  reactor_->OnReadInitialMetadataDone(ok);
470  MaybeFinish();
471  },
472  &start_ops_, /*can_inline=*/false);
473  if (!start_corked_) {
474  start_ops_.SendInitialMetadata(&context_->send_initial_metadata_,
475  context_->initial_metadata_flags());
476  }
477  start_ops_.RecvInitialMetadata(context_);
478  start_ops_.set_core_cq_tag(&start_tag_);
479  call_.PerformOps(&start_ops_);
480 
481  // Also set up the read and write tags so that they don't have to be set up
482  // each time
483  write_tag_.Set(call_.call(),
484  [this](bool ok) {
485  reactor_->OnWriteDone(ok);
486  MaybeFinish();
487  },
488  &write_ops_, /*can_inline=*/false);
489  write_ops_.set_core_cq_tag(&write_tag_);
490 
491  read_tag_.Set(call_.call(),
492  [this](bool ok) {
493  reactor_->OnReadDone(ok);
494  MaybeFinish();
495  },
496  &read_ops_, /*can_inline=*/false);
497  read_ops_.set_core_cq_tag(&read_tag_);
498  if (read_ops_at_start_) {
499  call_.PerformOps(&read_ops_);
500  }
501 
502  if (write_ops_at_start_) {
503  call_.PerformOps(&write_ops_);
504  }
505 
506  if (writes_done_ops_at_start_) {
507  call_.PerformOps(&writes_done_ops_);
508  }
509 
510  finish_tag_.Set(call_.call(), [this](bool /*ok*/) { MaybeFinish(); },
511  &finish_ops_, /*can_inline=*/false);
512  finish_ops_.ClientRecvStatus(context_, &finish_status_);
513  finish_ops_.set_core_cq_tag(&finish_tag_);
514  call_.PerformOps(&finish_ops_);
515  }
516 
517  void Read(Response* msg) override {
518  read_ops_.RecvMessage(msg);
519  callbacks_outstanding_.fetch_add(1, std::memory_order_relaxed);
520  if (started_) {
521  call_.PerformOps(&read_ops_);
522  } else {
523  read_ops_at_start_ = true;
524  }
525  }
526 
527  void Write(const Request* msg, ::grpc::WriteOptions options) override {
528  if (start_corked_) {
529  write_ops_.SendInitialMetadata(&context_->send_initial_metadata_,
530  context_->initial_metadata_flags());
531  start_corked_ = false;
532  }
533 
534  if (options.is_last_message()) {
535  options.set_buffer_hint();
536  write_ops_.ClientSendClose();
537  }
538  // TODO(vjpai): don't assert
539  GPR_CODEGEN_ASSERT(write_ops_.SendMessagePtr(msg, options).ok());
540  callbacks_outstanding_.fetch_add(1, std::memory_order_relaxed);
541  if (started_) {
542  call_.PerformOps(&write_ops_);
543  } else {
544  write_ops_at_start_ = true;
545  }
546  }
547  void WritesDone() override {
548  if (start_corked_) {
549  writes_done_ops_.SendInitialMetadata(&context_->send_initial_metadata_,
550  context_->initial_metadata_flags());
551  start_corked_ = false;
552  }
553  writes_done_ops_.ClientSendClose();
554  writes_done_tag_.Set(call_.call(),
555  [this](bool ok) {
556  reactor_->OnWritesDoneDone(ok);
557  MaybeFinish();
558  },
559  &writes_done_ops_, /*can_inline=*/false);
560  writes_done_ops_.set_core_cq_tag(&writes_done_tag_);
561  callbacks_outstanding_.fetch_add(1, std::memory_order_relaxed);
562  if (started_) {
563  call_.PerformOps(&writes_done_ops_);
564  } else {
565  writes_done_ops_at_start_ = true;
566  }
567  }
568 
569  void AddHold(int holds) override {
570  callbacks_outstanding_.fetch_add(holds, std::memory_order_relaxed);
571  }
572  void RemoveHold() override { MaybeFinish(); }
573 
574  private:
575  friend class ClientCallbackReaderWriterFactory<Request, Response>;
576 
578  ::grpc_impl::ClientContext* context,
580  : context_(context),
581  call_(call),
582  reactor_(reactor),
583  start_corked_(context_->initial_metadata_corked_) {
584  this->BindReactor(reactor);
585  }
586 
587  ::grpc_impl::ClientContext* const context_;
588  grpc::internal::Call call_;
589  ClientBidiReactor<Request, Response>* const reactor_;
590 
593  start_ops_;
595  bool start_corked_;
596 
599  ::grpc::Status finish_status_;
600 
604  write_ops_;
606  bool write_ops_at_start_{false};
607 
610  writes_done_ops_;
612  bool writes_done_ops_at_start_{false};
613 
615  read_ops_;
617  bool read_ops_at_start_{false};
618 
619  // Minimum of 2 callbacks to pre-register for start and finish
620  std::atomic<intptr_t> callbacks_outstanding_{2};
621  bool started_{false};
622 };
623 
624 template <class Request, class Response>
625 class ClientCallbackReaderWriterFactory {
626  public:
627  static void Create(::grpc::ChannelInterface* channel,
628  const ::grpc::internal::RpcMethod& method,
629  ::grpc_impl::ClientContext* context,
631  grpc::internal::Call call =
632  channel->CreateCall(method, context, channel->CallbackCQ());
633 
638  reactor);
639  }
640 };
641 
642 template <class Response>
644  public:
645  // always allocated against a call arena, no memory free required
646  static void operator delete(void* /*ptr*/, std::size_t size) {
648  }
649 
650  // This operator should never be called as the memory should be freed as part
651  // of the arena destruction. It only exists to provide a matching operator
652  // delete to the operator new so that some compilers will not complain (see
653  // https://github.com/grpc/grpc/issues/11301) Note at the time of adding this
654  // there are no tests catching the compiler warning.
655  static void operator delete(void*, void*) { GPR_CODEGEN_ASSERT(false); }
656 
657  void MaybeFinish() {
658  if (GPR_UNLIKELY(callbacks_outstanding_.fetch_sub(
659  1, std::memory_order_acq_rel) == 1)) {
660  ::grpc::Status s = std::move(finish_status_);
661  auto* reactor = reactor_;
662  auto* call = call_.call();
663  this->~ClientCallbackReaderImpl();
665  reactor->OnDone(s);
666  }
667  }
668 
669  void StartCall() override {
670  // This call initiates two batches, plus any backlog, each with a callback
671  // 1. Send initial metadata (unless corked) + recv initial metadata
672  // 2. Any backlog
673  // 3. Recv trailing metadata, on_completion callback
674  started_ = true;
675 
676  start_tag_.Set(call_.call(),
677  [this](bool ok) {
678  reactor_->OnReadInitialMetadataDone(ok);
679  MaybeFinish();
680  },
681  &start_ops_, /*can_inline=*/false);
682  start_ops_.SendInitialMetadata(&context_->send_initial_metadata_,
683  context_->initial_metadata_flags());
684  start_ops_.RecvInitialMetadata(context_);
685  start_ops_.set_core_cq_tag(&start_tag_);
686  call_.PerformOps(&start_ops_);
687 
688  // Also set up the read tag so it doesn't have to be set up each time
689  read_tag_.Set(call_.call(),
690  [this](bool ok) {
691  reactor_->OnReadDone(ok);
692  MaybeFinish();
693  },
694  &read_ops_, /*can_inline=*/false);
695  read_ops_.set_core_cq_tag(&read_tag_);
696  if (read_ops_at_start_) {
697  call_.PerformOps(&read_ops_);
698  }
699 
700  finish_tag_.Set(call_.call(), [this](bool /*ok*/) { MaybeFinish(); },
701  &finish_ops_, /*can_inline=*/false);
702  finish_ops_.ClientRecvStatus(context_, &finish_status_);
703  finish_ops_.set_core_cq_tag(&finish_tag_);
704  call_.PerformOps(&finish_ops_);
705  }
706 
707  void Read(Response* msg) override {
708  read_ops_.RecvMessage(msg);
709  callbacks_outstanding_.fetch_add(1, std::memory_order_relaxed);
710  if (started_) {
711  call_.PerformOps(&read_ops_);
712  } else {
713  read_ops_at_start_ = true;
714  }
715  }
716 
717  void AddHold(int holds) override {
718  callbacks_outstanding_.fetch_add(holds, std::memory_order_relaxed);
719  }
720  void RemoveHold() override { MaybeFinish(); }
721 
722  private:
723  friend class ClientCallbackReaderFactory<Response>;
724 
725  template <class Request>
727  ::grpc_impl::ClientContext* context,
728  Request* request,
730  : context_(context), call_(call), reactor_(reactor) {
731  this->BindReactor(reactor);
732  // TODO(vjpai): don't assert
733  GPR_CODEGEN_ASSERT(start_ops_.SendMessagePtr(request).ok());
734  start_ops_.ClientSendClose();
735  }
736 
737  ::grpc_impl::ClientContext* const context_;
738  grpc::internal::Call call_;
739  ClientReadReactor<Response>* const reactor_;
740 
745  start_ops_;
747 
750  ::grpc::Status finish_status_;
751 
753  read_ops_;
755  bool read_ops_at_start_{false};
756 
757  // Minimum of 2 callbacks to pre-register for start and finish
758  std::atomic<intptr_t> callbacks_outstanding_{2};
759  bool started_{false};
760 };
761 
762 template <class Response>
763 class ClientCallbackReaderFactory {
764  public:
765  template <class Request>
766  static void Create(::grpc::ChannelInterface* channel,
767  const ::grpc::internal::RpcMethod& method,
768  ::grpc_impl::ClientContext* context,
769  const Request* request,
770  ClientReadReactor<Response>* reactor) {
771  grpc::internal::Call call =
772  channel->CreateCall(method, context, channel->CallbackCQ());
773 
776  call.call(), sizeof(ClientCallbackReaderImpl<Response>)))
777  ClientCallbackReaderImpl<Response>(call, context, request, reactor);
778  }
779 };
780 
781 template <class Request>
783  public:
784  // always allocated against a call arena, no memory free required
785  static void operator delete(void* /*ptr*/, std::size_t size) {
787  }
788 
789  // This operator should never be called as the memory should be freed as part
790  // of the arena destruction. It only exists to provide a matching operator
791  // delete to the operator new so that some compilers will not complain (see
792  // https://github.com/grpc/grpc/issues/11301) Note at the time of adding this
793  // there are no tests catching the compiler warning.
794  static void operator delete(void*, void*) { GPR_CODEGEN_ASSERT(false); }
795 
796  void MaybeFinish() {
797  if (GPR_UNLIKELY(callbacks_outstanding_.fetch_sub(
798  1, std::memory_order_acq_rel) == 1)) {
799  ::grpc::Status s = std::move(finish_status_);
800  auto* reactor = reactor_;
801  auto* call = call_.call();
802  this->~ClientCallbackWriterImpl();
804  reactor->OnDone(s);
805  }
806  }
807 
808  void StartCall() override {
809  // This call initiates two batches, plus any backlog, each with a callback
810  // 1. Send initial metadata (unless corked) + recv initial metadata
811  // 2. Any backlog
812  // 3. Recv trailing metadata, on_completion callback
813  started_ = true;
814 
815  start_tag_.Set(call_.call(),
816  [this](bool ok) {
817  reactor_->OnReadInitialMetadataDone(ok);
818  MaybeFinish();
819  },
820  &start_ops_, /*can_inline=*/false);
821  if (!start_corked_) {
822  start_ops_.SendInitialMetadata(&context_->send_initial_metadata_,
823  context_->initial_metadata_flags());
824  }
825  start_ops_.RecvInitialMetadata(context_);
826  start_ops_.set_core_cq_tag(&start_tag_);
827  call_.PerformOps(&start_ops_);
828 
829  // Also set up the read and write tags so that they don't have to be set up
830  // each time
831  write_tag_.Set(call_.call(),
832  [this](bool ok) {
833  reactor_->OnWriteDone(ok);
834  MaybeFinish();
835  },
836  &write_ops_, /*can_inline=*/false);
837  write_ops_.set_core_cq_tag(&write_tag_);
838 
839  if (write_ops_at_start_) {
840  call_.PerformOps(&write_ops_);
841  }
842 
843  if (writes_done_ops_at_start_) {
844  call_.PerformOps(&writes_done_ops_);
845  }
846 
847  finish_tag_.Set(call_.call(), [this](bool /*ok*/) { MaybeFinish(); },
848  &finish_ops_, /*can_inline=*/false);
849  finish_ops_.ClientRecvStatus(context_, &finish_status_);
850  finish_ops_.set_core_cq_tag(&finish_tag_);
851  call_.PerformOps(&finish_ops_);
852  }
853 
854  void Write(const Request* msg, ::grpc::WriteOptions options) override {
855  if (start_corked_) {
856  write_ops_.SendInitialMetadata(&context_->send_initial_metadata_,
857  context_->initial_metadata_flags());
858  start_corked_ = false;
859  }
860 
861  if (options.is_last_message()) {
862  options.set_buffer_hint();
863  write_ops_.ClientSendClose();
864  }
865  // TODO(vjpai): don't assert
866  GPR_CODEGEN_ASSERT(write_ops_.SendMessagePtr(msg, options).ok());
867  callbacks_outstanding_.fetch_add(1, std::memory_order_relaxed);
868  if (started_) {
869  call_.PerformOps(&write_ops_);
870  } else {
871  write_ops_at_start_ = true;
872  }
873  }
874  void WritesDone() override {
875  if (start_corked_) {
876  writes_done_ops_.SendInitialMetadata(&context_->send_initial_metadata_,
877  context_->initial_metadata_flags());
878  start_corked_ = false;
879  }
880  writes_done_ops_.ClientSendClose();
881  writes_done_tag_.Set(call_.call(),
882  [this](bool ok) {
883  reactor_->OnWritesDoneDone(ok);
884  MaybeFinish();
885  },
886  &writes_done_ops_, /*can_inline=*/false);
887  writes_done_ops_.set_core_cq_tag(&writes_done_tag_);
888  callbacks_outstanding_.fetch_add(1, std::memory_order_relaxed);
889  if (started_) {
890  call_.PerformOps(&writes_done_ops_);
891  } else {
892  writes_done_ops_at_start_ = true;
893  }
894  }
895 
896  void AddHold(int holds) override {
897  callbacks_outstanding_.fetch_add(holds, std::memory_order_relaxed);
898  }
899  void RemoveHold() override { MaybeFinish(); }
900 
901  private:
902  friend class ClientCallbackWriterFactory<Request>;
903 
904  template <class Response>
906  ::grpc_impl::ClientContext* context,
907  Response* response,
909  : context_(context),
910  call_(call),
911  reactor_(reactor),
912  start_corked_(context_->initial_metadata_corked_) {
913  this->BindReactor(reactor);
914  finish_ops_.RecvMessage(response);
915  finish_ops_.AllowNoMessage();
916  }
917 
918  ::grpc_impl::ClientContext* const context_;
919  grpc::internal::Call call_;
920  ClientWriteReactor<Request>* const reactor_;
921 
924  start_ops_;
926  bool start_corked_;
927 
930  finish_ops_;
932  ::grpc::Status finish_status_;
933 
937  write_ops_;
939  bool write_ops_at_start_{false};
940 
943  writes_done_ops_;
945  bool writes_done_ops_at_start_{false};
946 
947  // Minimum of 2 callbacks to pre-register for start and finish
948  std::atomic<intptr_t> callbacks_outstanding_{2};
949  bool started_{false};
950 };
951 
952 template <class Request>
953 class ClientCallbackWriterFactory {
954  public:
955  template <class Response>
956  static void Create(::grpc::ChannelInterface* channel,
957  const ::grpc::internal::RpcMethod& method,
958  ::grpc_impl::ClientContext* context, Response* response,
959  ClientWriteReactor<Request>* reactor) {
960  grpc::internal::Call call =
961  channel->CreateCall(method, context, channel->CallbackCQ());
962 
965  call.call(), sizeof(ClientCallbackWriterImpl<Request>)))
966  ClientCallbackWriterImpl<Request>(call, context, response, reactor);
967  }
968 };
969 
971  public:
972  // always allocated against a call arena, no memory free required
973  static void operator delete(void* /*ptr*/, std::size_t size) {
975  }
976 
977  // This operator should never be called as the memory should be freed as part
978  // of the arena destruction. It only exists to provide a matching operator
979  // delete to the operator new so that some compilers will not complain (see
980  // https://github.com/grpc/grpc/issues/11301) Note at the time of adding this
981  // there are no tests catching the compiler warning.
982  static void operator delete(void*, void*) { GPR_CODEGEN_ASSERT(false); }
983 
984  void StartCall() override {
985  // This call initiates two batches, each with a callback
986  // 1. Send initial metadata + write + writes done + recv initial metadata
987  // 2. Read message, recv trailing metadata
988  started_ = true;
989 
990  start_tag_.Set(call_.call(),
991  [this](bool ok) {
992  reactor_->OnReadInitialMetadataDone(ok);
993  MaybeFinish();
994  },
995  &start_ops_, /*can_inline=*/false);
996  start_ops_.SendInitialMetadata(&context_->send_initial_metadata_,
997  context_->initial_metadata_flags());
998  start_ops_.RecvInitialMetadata(context_);
999  start_ops_.set_core_cq_tag(&start_tag_);
1000  call_.PerformOps(&start_ops_);
1001 
1002  finish_tag_.Set(call_.call(), [this](bool /*ok*/) { MaybeFinish(); },
1003  &finish_ops_, /*can_inline=*/false);
1004  finish_ops_.ClientRecvStatus(context_, &finish_status_);
1005  finish_ops_.set_core_cq_tag(&finish_tag_);
1006  call_.PerformOps(&finish_ops_);
1007  }
1008 
1009  void MaybeFinish() {
1010  if (GPR_UNLIKELY(callbacks_outstanding_.fetch_sub(
1011  1, std::memory_order_acq_rel) == 1)) {
1012  ::grpc::Status s = std::move(finish_status_);
1013  auto* reactor = reactor_;
1014  auto* call = call_.call();
1015  this->~ClientCallbackUnaryImpl();
1017  reactor->OnDone(s);
1018  }
1019  }
1020 
1021  private:
1023 
1024  template <class Request, class Response>
1026  ::grpc_impl::ClientContext* context, Request* request,
1027  Response* response, ClientUnaryReactor* reactor)
1028  : context_(context), call_(call), reactor_(reactor) {
1029  this->BindReactor(reactor);
1030  // TODO(vjpai): don't assert
1031  GPR_CODEGEN_ASSERT(start_ops_.SendMessagePtr(request).ok());
1032  start_ops_.ClientSendClose();
1033  finish_ops_.RecvMessage(response);
1034  finish_ops_.AllowNoMessage();
1035  }
1036 
1037  ::grpc_impl::ClientContext* const context_;
1038  grpc::internal::Call call_;
1039  ClientUnaryReactor* const reactor_;
1040 
1045  start_ops_;
1047 
1050  finish_ops_;
1052  ::grpc::Status finish_status_;
1053 
1054  // This call will have 2 callbacks: start and finish
1055  std::atomic<intptr_t> callbacks_outstanding_{2};
1056  bool started_{false};
1057 };
1058 
1060  public:
1061  template <class Request, class Response>
1062  static void Create(::grpc::ChannelInterface* channel,
1063  const ::grpc::internal::RpcMethod& method,
1064  ::grpc_impl::ClientContext* context,
1065  const Request* request, Response* response,
1066  ClientUnaryReactor* reactor) {
1067  grpc::internal::Call call =
1068  channel->CreateCall(method, context, channel->CallbackCQ());
1069 
1071 
1073  call.call(), sizeof(ClientCallbackUnaryImpl)))
1074  ClientCallbackUnaryImpl(call, context, request, response, reactor);
1075  }
1076 };
1077 
1078 } // namespace internal
1079 } // namespace grpc_impl
1080 #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:808
grpc::internal::CallOpRecvInitialMetadata
Definition: call_op_set.h:719
grpc_impl::internal::ClientCallbackReaderImpl::RemoveHold
void RemoveHold() override
Definition: client_callback_impl.h:720
grpc_impl::internal::ClientCallbackWriterImpl::Write
void Write(const Request *msg, ::grpc::WriteOptions options) override
Definition: client_callback_impl.h:854
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:617
grpc_impl::ClientUnaryReactor::StartCall
void StartCall()
Definition: client_callback_impl.h:406
grpc_impl::internal::ClientCallbackWriterImpl
Definition: client_callback_impl.h:782
grpc_impl::ClientReadReactor::OnReadDone
virtual void OnReadDone(bool)
Definition: client_callback_impl.h:346
grpc_impl::internal::ClientCallbackReaderImpl::Read
void Read(Response *msg) override
Definition: client_callback_impl.h:707
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:524
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:849
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:796
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:408
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:527
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:368
grpc_impl::internal::CallbackUnaryCallImpl
Definition: channel_interface.h:38
grpc_impl::ClientUnaryReactor::~ClientUnaryReactor
virtual ~ClientUnaryReactor()
Definition: client_callback_impl.h:404
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:984
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:276
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:335
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:956
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:723
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:342
grpc_impl::internal::ClientCallbackReaderImpl::StartCall
void StartCall() override
Definition: client_callback_impl.h:669
grpc_impl::internal::ClientCallbackReaderImpl::AddHold
void AddHold(int holds) override
Definition: client_callback_impl.h:717
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:527
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:301
grpc_impl::ClientBidiReactor::AddMultipleHolds
void AddMultipleHolds(int holds)
Definition: client_callback_impl.h:272
grpc_impl::internal::ClientCallbackReaderWriterImpl
Definition: client_callback_impl.h:432
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:572
grpc_impl::ClientCallbackWriter::RemoveHold
virtual void RemoveHold()=0
grpc_impl::ClientWriteReactor::OnDone
virtual void OnDone(const ::grpc::Status &)
Definition: client_callback_impl.h:380
grpc_impl::ClientReadReactor::~ClientReadReactor
virtual ~ClientReadReactor()
Definition: client_callback_impl.h:332
grpc_impl::ClientUnaryReactor
ClientUnaryReactor is a reactor-style interface for a unary RPC.
Definition: client_callback_impl.h:402
GPR_UNLIKELY
#define GPR_UNLIKELY(x)
Definition: port_platform.h:713
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:271
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:657
grpc_impl::internal::ClientCallbackReaderWriterImpl::AddHold
void AddHold(int holds) override
Definition: client_callback_impl.h:569
grpc_impl::ClientWriteReactor::StartCall
void StartCall()
Definition: client_callback_impl.h:361
grpc_impl::ClientWriteReactor::OnWriteDone
virtual void OnWriteDone(bool)
Definition: client_callback_impl.h:382
grpc_impl::ClientBidiReactor::OnWritesDoneDone
virtual void OnWritesDoneDone(bool)
Notifies the application that a StartWritesDone operation completed.
Definition: client_callback_impl.h:317
grpc_impl::internal::ClientCallbackWriterImpl::RemoveHold
void RemoveHold() override
Definition: client_callback_impl.h:899
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:378
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:344
grpc_impl::ClientReadReactor::StartCall
void StartCall()
Definition: client_callback_impl.h:334
grpc_impl::ClientWriteReactor::StartWritesDone
void StartWritesDone()
Definition: client_callback_impl.h:371
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:643
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:1062
grpc_impl::ClientCallbackReader::AddHold
virtual void AddHold(int holds)=0
grpc_impl::ClientReadReactor::OnReadInitialMetadataDone
virtual void OnReadInitialMetadataDone(bool)
Definition: client_callback_impl.h:345
grpc_impl::internal::ClientCallbackReaderWriterImpl::StartCall
void StartCall() override
Definition: client_callback_impl.h:459
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:359
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 all Holds ha...
Definition: client_callback_impl.h:285
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:338
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:1009
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:447
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:766
grpc_impl::ClientWriteReactor::AddMultipleHolds
void AddMultipleHolds(int holds)
Definition: client_callback_impl.h:374
grpc_impl::internal::ClientCallbackUnaryFactory
Definition: client_callback_impl.h:1059
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:627
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:767
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:417
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:547
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:383
grpc_impl::ClientWriteReactor::StartWrite
void StartWrite(const Request *req)
Definition: client_callback_impl.h:362
grpc_impl::ClientUnaryReactor::OnDone
virtual void OnDone(const ::grpc::Status &)
Definition: client_callback_impl.h:407
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:970
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:373
grpc_impl::internal::ClientCallbackWriterImpl::WritesDone
void WritesDone() override
Definition: client_callback_impl.h:874
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:365
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:337
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:517
grpc_impl::ClientCallbackWriter::~ClientCallbackWriter
virtual ~ClientCallbackWriter()
Definition: client_callback_impl.h:153
grpc::internal::CallOpClientSendClose::ClientSendClose
void ClientSendClose()
Definition: call_op_set.h:621
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:295
grpc_impl::ClientCallbackWriter::AddHold
virtual void AddHold(int holds)=0
grpc::internal::CallOpGenericRecvMessage::AllowNoMessage
void AllowNoMessage()
Definition: call_op_set.h:536
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:938
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:381
grpc::internal::CallOpRecvMessage::RecvMessage
void RecvMessage(R *message)
Definition: call_op_set.h:424
grpc_impl::internal::ClientCallbackWriterImpl::AddHold
void AddHold(int holds) override
Definition: client_callback_impl.h:896
grpc::Channel
::grpc_impl::Channel Channel
Definition: channel.h:26
grpc_impl::ClientBidiReactor::OnWriteDone
virtual void OnWriteDone(bool)
Notifies the application that a StartWrite or StartWriteLast operation completed.
Definition: client_callback_impl.h:308
GPR_CODEGEN_DEBUG_ASSERT
#define GPR_CODEGEN_DEBUG_ASSERT(x)
Codegen specific version of GPR_DEBUG_ASSERT.
Definition: core_codegen_interface.h:155
grpc::internal::CallOpClientRecvStatus::ClientRecvStatus
void ClientRecvStatus(::grpc_impl::ClientContext *context, Status *status)
Definition: call_op_set.h:772