LCOV - code coverage report
Current view: top level - include/grpc++/impl - call.h (source / functions) Hit Total Coverage
Test: tmp.zDYK9MVh93 Lines: 196 200 98.0 %
Date: 2015-10-10 Functions: 245 370 66.2 %

          Line data    Source code
       1             : /*
       2             :  *
       3             :  * Copyright 2015, Google Inc.
       4             :  * All rights reserved.
       5             :  *
       6             :  * Redistribution and use in source and binary forms, with or without
       7             :  * modification, are permitted provided that the following conditions are
       8             :  * met:
       9             :  *
      10             :  *     * Redistributions of source code must retain the above copyright
      11             :  * notice, this list of conditions and the following disclaimer.
      12             :  *     * Redistributions in binary form must reproduce the above
      13             :  * copyright notice, this list of conditions and the following disclaimer
      14             :  * in the documentation and/or other materials provided with the
      15             :  * distribution.
      16             :  *     * Neither the name of Google Inc. nor the names of its
      17             :  * contributors may be used to endorse or promote products derived from
      18             :  * this software without specific prior written permission.
      19             :  *
      20             :  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
      21             :  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
      22             :  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
      23             :  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
      24             :  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
      25             :  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
      26             :  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
      27             :  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
      28             :  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
      29             :  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
      30             :  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
      31             :  *
      32             :  */
      33             : 
      34             : #ifndef GRPCXX_IMPL_CALL_H
      35             : #define GRPCXX_IMPL_CALL_H
      36             : 
      37             : #include <functional>
      38             : #include <memory>
      39             : #include <map>
      40             : #include <cstring>
      41             : 
      42             : #include <grpc/support/alloc.h>
      43             : #include <grpc++/client_context.h>
      44             : #include <grpc++/completion_queue.h>
      45             : #include <grpc++/impl/serialization_traits.h>
      46             : #include <grpc++/support/config.h>
      47             : #include <grpc++/support/status.h>
      48             : 
      49             : struct grpc_call;
      50             : struct grpc_op;
      51             : 
      52             : namespace grpc {
      53             : 
      54             : class ByteBuffer;
      55             : class Call;
      56             : 
      57             : void FillMetadataMap(
      58             :     grpc_metadata_array* arr,
      59             :     std::multimap<grpc::string_ref, grpc::string_ref>* metadata);
      60             : grpc_metadata* FillMetadataArray(
      61             :     const std::multimap<grpc::string, grpc::string>& metadata);
      62             : 
      63             : /// Per-message write options.
      64             : class WriteOptions {
      65             :  public:
      66     5629273 :   WriteOptions() : flags_(0) {}
      67             :   WriteOptions(const WriteOptions& other) : flags_(other.flags_) {}
      68             : 
      69             :   /// Clear all flags.
      70     2794932 :   inline void Clear() { flags_ = 0; }
      71             : 
      72             :   /// Returns raw flags bitset.
      73     2794894 :   inline gpr_uint32 flags() const { return flags_; }
      74             : 
      75             :   /// Sets flag for the disabling of compression for the next message write.
      76             :   ///
      77             :   /// \sa GRPC_WRITE_NO_COMPRESS
      78             :   inline WriteOptions& set_no_compression() {
      79             :     SetBit(GRPC_WRITE_NO_COMPRESS);
      80             :     return *this;
      81             :   }
      82             : 
      83             :   /// Clears flag for the disabling of compression for the next message write.
      84             :   ///
      85             :   /// \sa GRPC_WRITE_NO_COMPRESS
      86             :   inline WriteOptions& clear_no_compression() {
      87             :     ClearBit(GRPC_WRITE_NO_COMPRESS);
      88             :     return *this;
      89             :   }
      90             : 
      91             :   /// Get value for the flag indicating whether compression for the next
      92             :   /// message write is forcefully disabled.
      93             :   ///
      94             :   /// \sa GRPC_WRITE_NO_COMPRESS
      95             :   inline bool get_no_compression() const {
      96             :     return GetBit(GRPC_WRITE_NO_COMPRESS);
      97             :   }
      98             : 
      99             :   /// Sets flag indicating that the write may be buffered and need not go out on
     100             :   /// the wire immediately.
     101             :   ///
     102             :   /// \sa GRPC_WRITE_BUFFER_HINT
     103             :   inline WriteOptions& set_buffer_hint() {
     104             :     SetBit(GRPC_WRITE_BUFFER_HINT);
     105             :     return *this;
     106             :   }
     107             : 
     108             :   /// Clears flag indicating that the write may be buffered and need not go out
     109             :   /// on the wire immediately.
     110             :   ///
     111             :   /// \sa GRPC_WRITE_BUFFER_HINT
     112             :   inline WriteOptions& clear_buffer_hint() {
     113             :     ClearBit(GRPC_WRITE_BUFFER_HINT);
     114             :     return *this;
     115             :   }
     116             : 
     117             :   /// Get value for the flag indicating that the write may be buffered and need
     118             :   /// not go out on the wire immediately.
     119             :   ///
     120             :   /// \sa GRPC_WRITE_BUFFER_HINT
     121             :   inline bool get_buffer_hint() const { return GetBit(GRPC_WRITE_BUFFER_HINT); }
     122             : 
     123     3956466 :   WriteOptions& operator=(const WriteOptions& rhs) {
     124     3956466 :     flags_ = rhs.flags_;
     125     3956466 :     return *this;
     126             :   }
     127             : 
     128             :  private:
     129             :   void SetBit(const gpr_uint32 mask) { flags_ |= mask; }
     130             : 
     131             :   void ClearBit(const gpr_uint32 mask) { flags_ &= ~mask; }
     132             : 
     133             :   bool GetBit(const gpr_uint32 mask) const { return (flags_ & mask) != 0; }
     134             : 
     135             :   gpr_uint32 flags_;
     136             : };
     137             : 
     138             : /// Default argument for CallOpSet. I is unused by the class, but can be
     139             : /// used for generating multiple names for the same thing.
     140             : template <int I>
     141    24861812 : class CallNoOp {
     142             :  protected:
     143    12481570 :   void AddOp(grpc_op* ops, size_t* nops) {}
     144    12484672 :   void FinishOp(bool* status, int max_message_size) {}
     145             : };
     146             : 
     147             : class CallOpSendInitialMetadata {
     148             :  public:
     149     4091487 :   CallOpSendInitialMetadata() : send_(false) {}
     150             : 
     151     2596283 :   void SendInitialMetadata(
     152             :       const std::multimap<grpc::string, grpc::string>& metadata) {
     153     2596283 :     send_ = true;
     154     2596283 :     initial_metadata_count_ = metadata.size();
     155     2597168 :     initial_metadata_ = FillMetadataArray(metadata);
     156     2597125 :   }
     157             : 
     158             :  protected:
     159     2703125 :   void AddOp(grpc_op* ops, size_t* nops) {
     160     5406250 :     if (!send_) return;
     161     2595183 :     grpc_op* op = &ops[(*nops)++];
     162     2595183 :     op->op = GRPC_OP_SEND_INITIAL_METADATA;
     163     2595183 :     op->flags = 0;
     164     2595183 :     op->reserved = NULL;
     165     2595183 :     op->data.send_initial_metadata.count = initial_metadata_count_;
     166     2595183 :     op->data.send_initial_metadata.metadata = initial_metadata_;
     167             :   }
     168     2705803 :   void FinishOp(bool* status, int max_message_size) {
     169     5410504 :     if (!send_) return;
     170     2597861 :     gpr_free(initial_metadata_);
     171     2596759 :     send_ = false;
     172             :   }
     173             : 
     174             :   bool send_;
     175             :   size_t initial_metadata_count_;
     176             :   grpc_metadata* initial_metadata_;
     177             : };
     178             : 
     179     1165431 : class CallOpSendMessage {
     180             :  public:
     181     2846636 :   CallOpSendMessage() : send_buf_(nullptr), own_buf_(false) {}
     182             : 
     183             :   /// Send \a message using \a options for the write. The \a options are cleared
     184             :   /// after use.
     185             :   template <class M>
     186             :   Status SendMessage(const M& message,
     187             :                      const WriteOptions& options) GRPC_MUST_USE_RESULT;
     188             : 
     189             :   template <class M>
     190             :   Status SendMessage(const M& message) GRPC_MUST_USE_RESULT;
     191             : 
     192             :  protected:
     193     2794196 :   void AddOp(grpc_op* ops, size_t* nops) {
     194     5588588 :     if (send_buf_ == nullptr) return;
     195     2794176 :     grpc_op* op = &ops[(*nops)++];
     196     2794176 :     op->op = GRPC_OP_SEND_MESSAGE;
     197     2794176 :     op->flags = write_options_.flags();
     198     2794917 :     op->reserved = NULL;
     199     2794917 :     op->data.send_message = send_buf_;
     200             :     // Flags are per-message: clear them after use.
     201     2794917 :     write_options_.Clear();
     202             :   }
     203     2795521 :   void FinishOp(bool* status, int max_message_size) {
     204     2795521 :     if (own_buf_) grpc_byte_buffer_destroy(send_buf_);
     205     2795497 :     send_buf_ = nullptr;
     206     2795497 :   }
     207             : 
     208             :  private:
     209             :   grpc_byte_buffer* send_buf_;
     210             :   WriteOptions write_options_;
     211             :   bool own_buf_;
     212             : };
     213             : 
     214             : template <class M>
     215     2795662 : Status CallOpSendMessage::SendMessage(const M& message,
     216             :                                       const WriteOptions& options) {
     217     2795662 :   write_options_ = options;
     218     2795681 :   return SerializationTraits<M>::Serialize(message, &send_buf_, &own_buf_);
     219             : }
     220             : 
     221             : template <class M>
     222     2650498 : Status CallOpSendMessage::SendMessage(const M& message) {
     223     2650498 :   return SendMessage(message, WriteOptions());
     224             : }
     225             : 
     226             : template <class R>
     227             : class CallOpRecvMessage {
     228             :  public:
     229     1507580 :   CallOpRecvMessage() : got_message(false), message_(nullptr) {}
     230             : 
     231     1496715 :   void RecvMessage(R* message) { message_ = message; }
     232             : 
     233             :   bool got_message;
     234             : 
     235             :  protected:
     236     1496547 :   void AddOp(grpc_op* ops, size_t* nops) {
     237     2993094 :     if (message_ == nullptr) return;
     238     1496547 :     grpc_op* op = &ops[(*nops)++];
     239     1496547 :     op->op = GRPC_OP_RECV_MESSAGE;
     240     1496547 :     op->flags = 0;
     241     1496547 :     op->reserved = NULL;
     242     1496547 :     op->data.recv_message = &recv_buf_;
     243             :   }
     244             : 
     245     1496786 :   void FinishOp(bool* status, int max_message_size) {
     246     2993666 :     if (message_ == nullptr) return;
     247     1496786 :     if (recv_buf_) {
     248     1496697 :       if (*status) {
     249     1496697 :         got_message = true;
     250     1496697 :         *status = SerializationTraits<R>::Deserialize(recv_buf_, message_,
     251             :                                                       max_message_size).ok();
     252             :       } else {
     253           0 :         got_message = false;
     254           0 :         grpc_byte_buffer_destroy(recv_buf_);
     255             :       }
     256             :     } else {
     257          89 :       got_message = false;
     258          89 :       *status = false;
     259             :     }
     260     1496880 :     message_ = nullptr;
     261             :   }
     262             : 
     263             :  private:
     264             :   R* message_;
     265             :   grpc_byte_buffer* recv_buf_;
     266             : };
     267             : 
     268             : namespace CallOpGenericRecvMessageHelper {
     269          10 : class DeserializeFunc {
     270             :  public:
     271             :   virtual Status Deserialize(grpc_byte_buffer* buf, int max_message_size) = 0;
     272             : };
     273             : 
     274             : template <class R>
     275             : class DeserializeFuncType GRPC_FINAL : public DeserializeFunc {
     276             :  public:
     277          10 :   DeserializeFuncType(R* message) : message_(message) {}
     278           6 :   Status Deserialize(grpc_byte_buffer* buf,
     279             :                      int max_message_size) GRPC_OVERRIDE {
     280           6 :     return SerializationTraits<R>::Deserialize(buf, message_, max_message_size);
     281             :   }
     282             : 
     283             :  private:
     284             :   R* message_;  // Not a managed pointer because management is external to this
     285             : };
     286             : }  // namespace CallOpGenericRecvMessageHelper
     287             : 
     288          10 : class CallOpGenericRecvMessage {
     289             :  public:
     290          10 :   CallOpGenericRecvMessage() : got_message(false) {}
     291             : 
     292             :   template <class R>
     293          10 :   void RecvMessage(R* message) {
     294          10 :     deserialize_.reset(
     295             :         new CallOpGenericRecvMessageHelper::DeserializeFuncType<R>(message));
     296          10 :   }
     297             : 
     298             :   bool got_message;
     299             : 
     300             :  protected:
     301          10 :   void AddOp(grpc_op* ops, size_t* nops) {
     302          20 :     if (!deserialize_) return;
     303          10 :     grpc_op* op = &ops[(*nops)++];
     304          10 :     op->op = GRPC_OP_RECV_MESSAGE;
     305          10 :     op->flags = 0;
     306          10 :     op->reserved = NULL;
     307          10 :     op->data.recv_message = &recv_buf_;
     308             :   }
     309             : 
     310          10 :   void FinishOp(bool* status, int max_message_size) {
     311          20 :     if (!deserialize_) return;
     312          10 :     if (recv_buf_) {
     313           6 :       if (*status) {
     314           6 :         got_message = true;
     315           6 :         *status = deserialize_->Deserialize(recv_buf_, max_message_size).ok();
     316             :       } else {
     317           0 :         got_message = false;
     318           0 :         grpc_byte_buffer_destroy(recv_buf_);
     319             :       }
     320             :     } else {
     321           4 :       got_message = false;
     322           4 :       *status = false;
     323             :     }
     324          10 :     deserialize_.reset();
     325             :   }
     326             : 
     327             :  private:
     328             :   std::unique_ptr<CallOpGenericRecvMessageHelper::DeserializeFunc> deserialize_;
     329             :   grpc_byte_buffer* recv_buf_;
     330             : };
     331             : 
     332             : class CallOpClientSendClose {
     333             :  public:
     334     1298453 :   CallOpClientSendClose() : send_(false) {}
     335             : 
     336     1299072 :   void ClientSendClose() { send_ = true; }
     337             : 
     338             :  protected:
     339     1299141 :   void AddOp(grpc_op* ops, size_t* nops) {
     340     2598282 :     if (!send_) return;
     341     1299141 :     grpc_op* op = &ops[(*nops)++];
     342     1299141 :     op->op = GRPC_OP_SEND_CLOSE_FROM_CLIENT;
     343     1299141 :     op->flags = 0;
     344     1299141 :     op->reserved = NULL;
     345             :   }
     346     1299119 :   void FinishOp(bool* status, int max_message_size) { send_ = false; }
     347             : 
     348             :  private:
     349             :   bool send_;
     350             : };
     351             : 
     352     2570549 : class CallOpServerSendStatus {
     353             :  public:
     354     1405298 :   CallOpServerSendStatus() : send_status_available_(false) {}
     355             : 
     356     1298970 :   void ServerSendStatus(
     357             :       const std::multimap<grpc::string, grpc::string>& trailing_metadata,
     358             :       const Status& status) {
     359     1298970 :     trailing_metadata_count_ = trailing_metadata.size();
     360     1299031 :     trailing_metadata_ = FillMetadataArray(trailing_metadata);
     361     1299032 :     send_status_available_ = true;
     362     1299032 :     send_status_code_ = static_cast<grpc_status_code>(status.error_code());
     363     1299027 :     send_status_details_ = status.error_message();
     364     1299089 :   }
     365             : 
     366             :  protected:
     367     1299036 :   void AddOp(grpc_op* ops, size_t* nops) {
     368     2598146 :     if (!send_status_available_) return;
     369     1299036 :     grpc_op* op = &ops[(*nops)++];
     370     1299036 :     op->op = GRPC_OP_SEND_STATUS_FROM_SERVER;
     371             :     op->data.send_status_from_server.trailing_metadata_count =
     372     1299036 :         trailing_metadata_count_;
     373     1299036 :     op->data.send_status_from_server.trailing_metadata = trailing_metadata_;
     374     1299036 :     op->data.send_status_from_server.status = send_status_code_;
     375             :     op->data.send_status_from_server.status_details =
     376     1299036 :         send_status_details_.empty() ? nullptr : send_status_details_.c_str();
     377     1299110 :     op->flags = 0;
     378     1299110 :     op->reserved = NULL;
     379             :   }
     380             : 
     381     1299108 :   void FinishOp(bool* status, int max_message_size) {
     382     2598212 :     if (!send_status_available_) return;
     383     1299108 :     gpr_free(trailing_metadata_);
     384     1299104 :     send_status_available_ = false;
     385             :   }
     386             : 
     387             :  private:
     388             :   bool send_status_available_;
     389             :   grpc_status_code send_status_code_;
     390             :   grpc::string send_status_details_;
     391             :   size_t trailing_metadata_count_;
     392             :   grpc_metadata* trailing_metadata_;
     393             : };
     394             : 
     395             : class CallOpRecvInitialMetadata {
     396             :  public:
     397     2519138 :   CallOpRecvInitialMetadata() : recv_initial_metadata_(nullptr) {}
     398             : 
     399     1299097 :   void RecvInitialMetadata(ClientContext* context) {
     400     1299097 :     context->initial_metadata_received_ = true;
     401     1299097 :     recv_initial_metadata_ = &context->recv_initial_metadata_;
     402     1299097 :   }
     403             : 
     404             :  protected:
     405     1406852 :   void AddOp(grpc_op* ops, size_t* nops) {
     406     2813704 :     if (!recv_initial_metadata_) return;
     407     1298932 :     memset(&recv_initial_metadata_arr_, 0, sizeof(recv_initial_metadata_arr_));
     408     1298932 :     grpc_op* op = &ops[(*nops)++];
     409     1298932 :     op->op = GRPC_OP_RECV_INITIAL_METADATA;
     410     1298932 :     op->data.recv_initial_metadata = &recv_initial_metadata_arr_;
     411     1298932 :     op->flags = 0;
     412     1298932 :     op->reserved = NULL;
     413             :   }
     414     1406665 :   void FinishOp(bool* status, int max_message_size) {
     415     2813679 :     if (recv_initial_metadata_ == nullptr) return;
     416     1298745 :     FillMetadataMap(&recv_initial_metadata_arr_, recv_initial_metadata_);
     417     1299094 :     recv_initial_metadata_ = nullptr;
     418             :   }
     419             : 
     420             :  private:
     421             :   std::multimap<grpc::string_ref, grpc::string_ref>* recv_initial_metadata_;
     422             :   grpc_metadata_array recv_initial_metadata_arr_;
     423             : };
     424             : 
     425             : class CallOpClientRecvStatus {
     426             :  public:
     427     1298935 :   CallOpClientRecvStatus() : recv_status_(nullptr) {}
     428             : 
     429     1297710 :   void ClientRecvStatus(ClientContext* context, Status* status) {
     430     1297710 :     recv_trailing_metadata_ = &context->trailing_metadata_;
     431     1297710 :     recv_status_ = status;
     432     1297710 :   }
     433             : 
     434             :  protected:
     435     1299138 :   void AddOp(grpc_op* ops, size_t* nops) {
     436     2598276 :     if (recv_status_ == nullptr) return;
     437             :     memset(&recv_trailing_metadata_arr_, 0,
     438     1299138 :            sizeof(recv_trailing_metadata_arr_));
     439     1299138 :     status_details_ = nullptr;
     440     1299138 :     status_details_capacity_ = 0;
     441     1299138 :     grpc_op* op = &ops[(*nops)++];
     442     1299138 :     op->op = GRPC_OP_RECV_STATUS_ON_CLIENT;
     443             :     op->data.recv_status_on_client.trailing_metadata =
     444     1299138 :         &recv_trailing_metadata_arr_;
     445     1299138 :     op->data.recv_status_on_client.status = &status_code_;
     446     1299138 :     op->data.recv_status_on_client.status_details = &status_details_;
     447             :     op->data.recv_status_on_client.status_details_capacity =
     448     1299138 :         &status_details_capacity_;
     449     1299138 :     op->flags = 0;
     450     1299138 :     op->reserved = NULL;
     451             :   }
     452             : 
     453     1298967 :   void FinishOp(bool* status, int max_message_size) {
     454     2598106 :     if (recv_status_ == nullptr) return;
     455     1298967 :     FillMetadataMap(&recv_trailing_metadata_arr_, recv_trailing_metadata_);
     456     3897036 :     *recv_status_ = Status(
     457             :         static_cast<StatusCode>(status_code_),
     458     1298886 :         status_details_ ? grpc::string(status_details_) : grpc::string());
     459     1299123 :     gpr_free(status_details_);
     460     1299139 :     recv_status_ = nullptr;
     461             :   }
     462             : 
     463             :  private:
     464             :   std::multimap<grpc::string_ref, grpc::string_ref>* recv_trailing_metadata_;
     465             :   Status* recv_status_;
     466             :   grpc_metadata_array recv_trailing_metadata_arr_;
     467             :   grpc_status_code status_code_;
     468             :   char* status_details_;
     469             :   size_t status_details_capacity_;
     470             : };
     471             : 
     472             : /// An abstract collection of call ops, used to generate the
     473             : /// grpc_call_op structure to pass down to the lower layers,
     474             : /// and as it is-a CompletionQueueTag, also massages the final
     475             : /// completion into the correct form for consumption in the C++
     476             : /// API.
     477    10278235 : class CallOpSetInterface : public CompletionQueueTag {
     478             :  public:
     479     7924932 :   CallOpSetInterface() : max_message_size_(0) {}
     480             :   /// Fills in grpc_op, starting from ops[*nops] and moving
     481             :   /// upwards.
     482             :   virtual void FillOps(grpc_op* ops, size_t* nops) = 0;
     483             : 
     484      200971 :   void set_max_message_size(int max_message_size) {
     485      200971 :     max_message_size_ = max_message_size;
     486      200971 :   }
     487             : 
     488             :  protected:
     489             :   int max_message_size_;
     490             : };
     491             : 
     492             : /// Primary implementaiton of CallOpSetInterface.
     493             : /// Since we cannot use variadic templates, we declare slots up to
     494             : /// the maximum count of ops we'll need in a set. We leverage the
     495             : /// empty base class optimization to slim this class (especially
     496             : /// when there are many unused slots used). To avoid duplicate base classes,
     497             : /// the template parmeter for CallNoOp is varied by argument position.
     498             : template <class Op1 = CallNoOp<1>, class Op2 = CallNoOp<2>,
     499             :           class Op3 = CallNoOp<3>, class Op4 = CallNoOp<4>,
     500             :           class Op5 = CallNoOp<5>, class Op6 = CallNoOp<6>>
     501     9027106 : class CallOpSet : public CallOpSetInterface,
     502             :                   public Op1,
     503             :                   public Op2,
     504             :                   public Op3,
     505             :                   public Op4,
     506             :                   public Op5,
     507             :                   public Op6 {
     508             :  public:
     509     6648076 :   CallOpSet() : return_tag_(this) {}
     510     4133011 :   void FillOps(grpc_op* ops, size_t* nops) GRPC_OVERRIDE {
     511     4133011 :     this->Op1::AddOp(ops, nops);
     512     4133402 :     this->Op2::AddOp(ops, nops);
     513     4133437 :     this->Op3::AddOp(ops, nops);
     514     4133364 :     this->Op4::AddOp(ops, nops);
     515     4132629 :     this->Op5::AddOp(ops, nops);
     516     4133352 :     this->Op6::AddOp(ops, nops);
     517     4133237 :   }
     518             : 
     519     4133334 :   bool FinalizeResult(void** tag, bool* status) GRPC_OVERRIDE {
     520     4133334 :     this->Op1::FinishOp(status, max_message_size_);
     521     4133366 :     this->Op2::FinishOp(status, max_message_size_);
     522     4133298 :     this->Op3::FinishOp(status, max_message_size_);
     523     4133431 :     this->Op4::FinishOp(status, max_message_size_);
     524     4133450 :     this->Op5::FinishOp(status, max_message_size_);
     525     4133449 :     this->Op6::FinishOp(status, max_message_size_);
     526     4133414 :     *tag = return_tag_;
     527     4133414 :     return true;
     528             :   }
     529             : 
     530     2384023 :   void set_output_tag(void* return_tag) { return_tag_ = return_tag; }
     531             : 
     532             :  private:
     533             :   void* return_tag_;
     534             : };
     535             : 
     536             : /// A CallOpSet that does not post completions to the completion queue.
     537             : ///
     538             : /// Allows hiding some completions that the C core must generate from
     539             : /// C++ users.
     540             : template <class Op1 = CallNoOp<1>, class Op2 = CallNoOp<2>,
     541             :           class Op3 = CallNoOp<3>, class Op4 = CallNoOp<4>,
     542             :           class Op5 = CallNoOp<5>, class Op6 = CallNoOp<6>>
     543     2278566 : class SneakyCallOpSet : public CallOpSet<Op1, Op2, Op3, Op4, Op5, Op6> {
     544             :  public:
     545     1139602 :   bool FinalizeResult(void** tag, bool* status) GRPC_OVERRIDE {
     546             :     typedef CallOpSet<Op1, Op2, Op3, Op4, Op5, Op6> Base;
     547     1139602 :     return Base::FinalizeResult(tag, status) && false;
     548             :   }
     549             : };
     550             : 
     551             : // Channel and Server implement this to allow them to hook performing ops
     552         341 : class CallHook {
     553             :  public:
     554         341 :   virtual ~CallHook() {}
     555             :   virtual void PerformOpsOnCall(CallOpSetInterface* ops, Call* call) = 0;
     556             : };
     557             : 
     558             : // Straightforward wrapping of the C call object
     559             : class Call GRPC_FINAL {
     560             :  public:
     561             :   /* call is owned by the caller */
     562             :   Call(grpc_call* call, CallHook* call_hook_, CompletionQueue* cq);
     563             :   Call(grpc_call* call, CallHook* call_hook_, CompletionQueue* cq,
     564             :        int max_message_size);
     565             : 
     566             :   void PerformOps(CallOpSetInterface* ops);
     567             : 
     568     5414921 :   grpc_call* call() { return call_; }
     569      304160 :   CompletionQueue* cq() { return cq_; }
     570             : 
     571      159512 :   int max_message_size() { return max_message_size_; }
     572             : 
     573             :  private:
     574             :   CallHook* call_hook_;
     575             :   CompletionQueue* cq_;
     576             :   grpc_call* call_;
     577             :   int max_message_size_;
     578             : };
     579             : 
     580             : }  // namespace grpc
     581             : 
     582             : #endif  // GRPCXX_IMPL_CALL_H

Generated by: LCOV version 1.10