GRPC C++  1.39.1
channel_filter.h
Go to the documentation of this file.
1 /*
2  *
3  * Copyright 2016 gRPC authors.
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  */
18 
19 #ifndef GRPCXX_CHANNEL_FILTER_H
20 #define GRPCXX_CHANNEL_FILTER_H
21 
22 #include <grpc/grpc.h>
23 #include <grpc/support/alloc.h>
25 
26 #include <functional>
27 #include <vector>
28 
32 
41 
42 namespace grpc {
43 
46  public:
50  explicit MetadataBatch(grpc_metadata_batch* batch) : batch_(batch) {}
51 
52  grpc_metadata_batch* batch() const { return batch_; }
53 
57  grpc_linked_mdelem* AddMetadata(const string& key, const string& value);
58 
59  class const_iterator : public std::iterator<std::bidirectional_iterator_tag,
60  const grpc_mdelem> {
61  public:
62  const grpc_mdelem& operator*() const { return elem_->md; }
63  grpc_mdelem operator->() const { return elem_->md; }
64 
66  elem_ = elem_->next;
67  return *this;
68  }
70  const_iterator tmp(*this);
71  operator++();
72  return tmp;
73  }
75  elem_ = elem_->prev;
76  return *this;
77  }
79  const_iterator tmp(*this);
80  operator--();
81  return tmp;
82  }
83 
84  bool operator==(const const_iterator& other) const {
85  return elem_ == other.elem_;
86  }
87  bool operator!=(const const_iterator& other) const {
88  return elem_ != other.elem_;
89  }
90 
91  private:
92  friend class MetadataBatch;
93  explicit const_iterator(grpc_linked_mdelem* elem) : elem_(elem) {}
94 
95  grpc_linked_mdelem* elem_;
96  };
97 
98  const_iterator begin() const { return const_iterator(batch_->list.head); }
99  const_iterator end() const { return const_iterator(nullptr); }
100 
101  private:
102  grpc_metadata_batch* batch_; // Not owned.
103 };
104 
106 class TransportOp {
107  public:
111  explicit TransportOp(grpc_transport_op* op) : op_(op) {}
112 
113  grpc_transport_op* op() const { return op_; }
114 
115  // TODO(roth): Add a C++ wrapper for grpc_error?
117  return op_->disconnect_with_error;
118  }
119  bool send_goaway() const { return op_->goaway_error != GRPC_ERROR_NONE; }
120 
121  // TODO(roth): Add methods for additional fields as needed.
122 
123  private:
124  grpc_transport_op* op_; // Not owned.
125 };
126 
129  public:
134  : op_(op),
135  send_initial_metadata_(
138  : nullptr),
139  send_trailing_metadata_(
142  : nullptr),
143  recv_initial_metadata_(
146  : nullptr),
147  recv_trailing_metadata_(
150  : nullptr) {}
151 
152  grpc_transport_stream_op_batch* op() const { return op_; }
153 
154  grpc_closure* on_complete() const { return op_->on_complete; }
156 
158  return op_->send_initial_metadata ? &send_initial_metadata_ : nullptr;
159  }
161  return op_->send_trailing_metadata ? &send_trailing_metadata_ : nullptr;
162  }
164  return op_->recv_initial_metadata ? &recv_initial_metadata_ : nullptr;
165  }
167  return op_->recv_trailing_metadata ? &recv_trailing_metadata_ : nullptr;
168  }
169 
170  uint32_t* send_initial_metadata_flags() const {
172  .send_initial_metadata_flags
173  : nullptr;
174  }
175 
177  return op_->recv_initial_metadata
178  ? op_->payload->recv_initial_metadata.recv_initial_metadata_ready
179  : nullptr;
180  }
182  op_->payload->recv_initial_metadata.recv_initial_metadata_ready = closure;
183  }
184 
186  return op_->send_message ? &op_->payload->send_message.send_message
187  : nullptr;
188  }
191  op_->send_message = true;
192  op_->payload->send_message.send_message = std::move(send_message);
193  }
194 
196  return op_->recv_message ? op_->payload->recv_message.recv_message
197  : nullptr;
198  }
201  op_->recv_message = true;
202  op_->payload->recv_message.recv_message = recv_message;
203  }
204 
206  return static_cast<census_context*>(
208  }
209 
210  const gpr_atm* get_peer_string() const {
211  if (op_->send_initial_metadata &&
212  op_->payload->send_initial_metadata.peer_string != nullptr) {
213  return op_->payload->send_initial_metadata.peer_string;
214  } else if (op_->recv_initial_metadata &&
215  op_->payload->recv_initial_metadata.peer_string != nullptr) {
216  return op_->payload->recv_initial_metadata.peer_string;
217  } else {
218  return nullptr;
219  }
220  }
221 
222  private:
223  grpc_transport_stream_op_batch* op_; // Not owned.
224  MetadataBatch send_initial_metadata_;
225  MetadataBatch send_trailing_metadata_;
226  MetadataBatch recv_initial_metadata_;
227  MetadataBatch recv_trailing_metadata_;
228 };
229 
231 class ChannelData {
232  public:
234  virtual ~ChannelData() {}
235 
236  // TODO(roth): Come up with a more C++-like API for the channel element.
237 
240  grpc_channel_element_args* /*args*/) {
241  return GRPC_ERROR_NONE;
242  }
243 
244  // Called before destruction.
245  virtual void Destroy(grpc_channel_element* /*elem*/) {}
246 
247  virtual void StartTransportOp(grpc_channel_element* elem, TransportOp* op);
248 
249  virtual void GetInfo(grpc_channel_element* elem,
250  const grpc_channel_info* channel_info);
251 };
252 
254 class CallData {
255  public:
256  CallData() {}
257  virtual ~CallData() {}
258 
259  // TODO(roth): Come up with a more C++-like API for the call element.
260 
263  const grpc_call_element_args* /*args*/) {
264  return GRPC_ERROR_NONE;
265  }
266 
267  // Called before destruction.
268  virtual void Destroy(grpc_call_element* /*elem*/,
269  const grpc_call_final_info* /*final_info*/,
270  grpc_closure* /*then_call_closure*/) {}
271 
275 
277  virtual void SetPollsetOrPollsetSet(grpc_call_element* elem,
278  grpc_polling_entity* pollent);
279 };
280 
281 namespace internal {
282 
283 // Defines static members for passing to C core.
284 // Members of this class correspond to the members of the C
285 // grpc_channel_filter struct.
286 template <typename ChannelDataType, typename CallDataType>
287 class ChannelFilter final {
288  public:
289  static const size_t channel_data_size = sizeof(ChannelDataType);
290 
293  // Construct the object in the already-allocated memory.
294  ChannelDataType* channel_data = new (elem->channel_data) ChannelDataType();
295  return channel_data->Init(elem, args);
296  }
297 
299  ChannelDataType* channel_data =
300  static_cast<ChannelDataType*>(elem->channel_data);
301  channel_data->Destroy(elem);
302  channel_data->~ChannelDataType();
303  }
304 
306  grpc_transport_op* op) {
307  ChannelDataType* channel_data =
308  static_cast<ChannelDataType*>(elem->channel_data);
309  TransportOp op_wrapper(op);
310  channel_data->StartTransportOp(elem, &op_wrapper);
311  }
312 
314  const grpc_channel_info* channel_info) {
315  ChannelDataType* channel_data =
316  static_cast<ChannelDataType*>(elem->channel_data);
317  channel_data->GetInfo(elem, channel_info);
318  }
319 
320  static const size_t call_data_size = sizeof(CallDataType);
321 
323  const grpc_call_element_args* args) {
324  // Construct the object in the already-allocated memory.
325  CallDataType* call_data = new (elem->call_data) CallDataType();
326  return call_data->Init(elem, args);
327  }
328 
330  const grpc_call_final_info* final_info,
331  grpc_closure* then_call_closure) {
332  CallDataType* call_data = static_cast<CallDataType*>(elem->call_data);
333  call_data->Destroy(elem, final_info, then_call_closure);
334  call_data->~CallDataType();
335  }
336 
339  CallDataType* call_data = static_cast<CallDataType*>(elem->call_data);
340  TransportStreamOpBatch op_wrapper(op);
341  call_data->StartTransportStreamOpBatch(elem, &op_wrapper);
342  }
343 
345  grpc_polling_entity* pollent) {
346  CallDataType* call_data = static_cast<CallDataType*>(elem->call_data);
347  call_data->SetPollsetOrPollsetSet(elem, pollent);
348  }
349 };
350 
351 struct FilterRecord {
353  int priority;
354  std::function<bool(const grpc_channel_args&)> include_filter;
356 };
357 extern std::vector<FilterRecord>* channel_filters;
358 
361 
362 } // namespace internal
363 
374 template <typename ChannelDataType, typename CallDataType>
376  const char* name, grpc_channel_stack_type stack_type, int priority,
377  std::function<bool(const grpc_channel_args&)> include_filter) {
378  // If we haven't been called before, initialize channel_filters and
379  // call grpc_register_plugin().
380  if (internal::channel_filters == nullptr) {
383  internal::channel_filters = new std::vector<internal::FilterRecord>();
384  }
385  // Add an entry to channel_filters. The filter will be added when the
386  // C-core initialization code calls ChannelFilterPluginInit().
388  internal::FilterRecord filter_record = {
389  stack_type,
390  priority,
391  include_filter,
392  {FilterType::StartTransportStreamOpBatch, FilterType::StartTransportOp,
393  FilterType::call_data_size, FilterType::InitCallElement,
394  FilterType::SetPollsetOrPollsetSet, FilterType::DestroyCallElement,
395  FilterType::channel_data_size, FilterType::InitChannelElement,
396  FilterType::DestroyChannelElement, FilterType::GetChannelInfo, name}};
397  internal::channel_filters->push_back(filter_record);
398 }
399 
400 } // namespace grpc
401 
402 #endif // GRPCXX_CHANNEL_FILTER_H
struct census_context census_context
A Census Context is a handle used by Census to represent the current tracing and stats collection inf...
Definition: census.h:34
grpc_channel_stack_type
Definition: channel_stack_type.h:26
Represents call data.
Definition: channel_filter.h:254
virtual grpc_error_handle Init(grpc_call_element *, const grpc_call_element_args *)
Initializes the call data.
Definition: channel_filter.h:262
virtual void SetPollsetOrPollsetSet(grpc_call_element *elem, grpc_polling_entity *pollent)
Sets a pollset or pollset set.
Definition: channel_filter.cc:59
virtual void Destroy(grpc_call_element *, const grpc_call_final_info *, grpc_closure *)
Definition: channel_filter.h:268
virtual void StartTransportStreamOpBatch(grpc_call_element *elem, TransportStreamOpBatch *op)
Starts a new stream operation.
Definition: channel_filter.cc:54
CallData()
Definition: channel_filter.h:256
virtual ~CallData()
Definition: channel_filter.h:257
Represents channel data.
Definition: channel_filter.h:231
ChannelData()
Definition: channel_filter.h:233
virtual grpc_error_handle Init(grpc_channel_element *, grpc_channel_element_args *)
Initializes the channel data.
Definition: channel_filter.h:239
virtual void GetInfo(grpc_channel_element *elem, const grpc_channel_info *channel_info)
Definition: channel_filter.cc:47
virtual void StartTransportOp(grpc_channel_element *elem, TransportOp *op)
Definition: channel_filter.cc:42
virtual void Destroy(grpc_channel_element *)
Definition: channel_filter.h:245
virtual ~ChannelData()
Definition: channel_filter.h:234
Definition: channel_filter.h:60
bool operator==(const const_iterator &other) const
Definition: channel_filter.h:84
const_iterator & operator--()
Definition: channel_filter.h:74
const grpc_mdelem & operator*() const
Definition: channel_filter.h:62
const_iterator & operator++()
Definition: channel_filter.h:65
const_iterator operator++(int)
Definition: channel_filter.h:69
bool operator!=(const const_iterator &other) const
Definition: channel_filter.h:87
const_iterator operator--(int)
Definition: channel_filter.h:78
grpc_mdelem operator->() const
Definition: channel_filter.h:63
A C++ wrapper for the grpc_metadata_batch struct.
Definition: channel_filter.h:45
const_iterator end() const
Definition: channel_filter.h:99
const_iterator begin() const
Definition: channel_filter.h:98
grpc_metadata_batch * batch() const
Definition: channel_filter.h:52
MetadataBatch(grpc_metadata_batch *batch)
Borrows a pointer to batch, but does NOT take ownership.
Definition: channel_filter.h:50
grpc_linked_mdelem * AddMetadata(const string &key, const string &value)
Adds metadata and returns the newly allocated storage.
Definition: channel_filter.cc:30
A C++ wrapper for the grpc_transport_op struct.
Definition: channel_filter.h:106
TransportOp(grpc_transport_op *op)
Borrows a pointer to op, but does NOT take ownership.
Definition: channel_filter.h:111
grpc_error_handle disconnect_with_error() const
Definition: channel_filter.h:116
grpc_transport_op * op() const
Definition: channel_filter.h:113
bool send_goaway() const
Definition: channel_filter.h:119
A C++ wrapper for the grpc_transport_stream_op_batch struct.
Definition: channel_filter.h:128
TransportStreamOpBatch(grpc_transport_stream_op_batch *op)
Borrows a pointer to op, but does NOT take ownership.
Definition: channel_filter.h:133
grpc_transport_stream_op_batch * op() const
Definition: channel_filter.h:152
void set_recv_message(grpc_core::OrphanablePtr< grpc_core::ByteStream > *recv_message)
Definition: channel_filter.h:199
grpc_core::OrphanablePtr< grpc_core::ByteStream > * send_message() const
Definition: channel_filter.h:185
uint32_t * send_initial_metadata_flags() const
Definition: channel_filter.h:170
grpc_core::OrphanablePtr< grpc_core::ByteStream > * recv_message() const
Definition: channel_filter.h:195
MetadataBatch * recv_initial_metadata()
Definition: channel_filter.h:163
void set_recv_initial_metadata_ready(grpc_closure *closure)
Definition: channel_filter.h:181
void set_on_complete(grpc_closure *closure)
Definition: channel_filter.h:155
census_context * get_census_context() const
Definition: channel_filter.h:205
void set_send_message(grpc_core::OrphanablePtr< grpc_core::ByteStream > send_message)
Definition: channel_filter.h:189
MetadataBatch * send_trailing_metadata()
Definition: channel_filter.h:160
const gpr_atm * get_peer_string() const
Definition: channel_filter.h:210
MetadataBatch * recv_trailing_metadata()
Definition: channel_filter.h:166
grpc_closure * on_complete() const
Definition: channel_filter.h:154
MetadataBatch * send_initial_metadata()
Definition: channel_filter.h:157
grpc_closure * recv_initial_metadata_ready() const
Definition: channel_filter.h:176
Definition: channel_filter.h:287
static void DestroyChannelElement(grpc_channel_element *elem)
Definition: channel_filter.h:298
static void StartTransportOp(grpc_channel_element *elem, grpc_transport_op *op)
Definition: channel_filter.h:305
static grpc_error_handle InitChannelElement(grpc_channel_element *elem, grpc_channel_element_args *args)
Definition: channel_filter.h:291
static grpc_error_handle InitCallElement(grpc_call_element *elem, const grpc_call_element_args *args)
Definition: channel_filter.h:322
static const size_t call_data_size
Definition: channel_filter.h:320
static void DestroyCallElement(grpc_call_element *elem, const grpc_call_final_info *final_info, grpc_closure *then_call_closure)
Definition: channel_filter.h:329
static void StartTransportStreamOpBatch(grpc_call_element *elem, grpc_transport_stream_op_batch *op)
Definition: channel_filter.h:337
static const size_t channel_data_size
Definition: channel_filter.h:289
static void SetPollsetOrPollsetSet(grpc_call_element *elem, grpc_polling_entity *pollent)
Definition: channel_filter.h:344
static void GetChannelInfo(grpc_channel_element *elem, const grpc_channel_info *channel_info)
Definition: channel_filter.h:313
struct connected_channel_channel_data channel_data
struct connected_channel_call_data call_data
@ GRPC_CONTEXT_TRACING
Value is a census_context.
Definition: context.h:33
#define GRPC_ERROR_NONE
The following "special" errors can be propagated without allocating memory.
Definition: error.h:228
GRPCAPI void grpc_register_plugin(void(*init)(void), void(*destroy)(void))
Registers a plugin to be initialized and destroyed with the library.
Definition: init.cc:119
intptr_t gpr_atm
Definition: atm_gcc_atomic.h:30
std::vector< FilterRecord > * channel_filters
Definition: channel_filter.cc:69
void ChannelFilterPluginShutdown()
Definition: channel_filter.cc:94
void ChannelFilterPluginInit()
Definition: channel_filter.cc:86
std::unique_ptr< T, Deleter > OrphanablePtr
Definition: orphanable.h:67
An Alarm posts the user-provided tag to its associated completion queue or invokes the user-provided ...
Definition: alarm.h:33
void RegisterChannelFilter(const char *name, grpc_channel_stack_type stack_type, int priority, std::function< bool(const grpc_channel_args &)> include_filter)
Registers a new filter.
Definition: channel_filter.h:375
grpc_closure closure
Definition: server.cc:460
Definition: channel_filter.h:351
grpc_channel_filter filter
Definition: channel_filter.h:355
int priority
Definition: channel_filter.h:353
std::function< bool(const grpc_channel_args &)> include_filter
Definition: channel_filter.h:354
grpc_channel_stack_type stack_type
Definition: channel_filter.h:352
void * value
Definition: context.h:45
Definition: channel_stack.h:76
Definition: channel_stack.h:174
void * call_data
Definition: channel_stack.h:177
Information about the call upon completion.
Definition: channel_stack.h:91
An array of arguments that can be passed around.
Definition: grpc_types.h:132
Definition: channel_stack.h:68
Definition: channel_stack.h:166
void * channel_data
Definition: channel_stack.h:168
Definition: channel_stack.h:107
Information requested from the channel.
Definition: grpc_types.h:704
A closure over a grpc_iomgr_cb_func.
Definition: closure.h:56
Definition: error_internal.h:41
Definition: metadata_batch.h:36
struct grpc_linked_mdelem * prev
Definition: metadata_batch.h:41
grpc_mdelem md
Definition: metadata_batch.h:39
struct grpc_linked_mdelem * next
Definition: metadata_batch.h:40
grpc_linked_mdelem * head
Definition: metadata_batch.h:48
Definition: metadata.h:98
Definition: metadata_batch.h:52
grpc_mdelem_list list
Metadata elements in this batch.
Definition: metadata_batch.h:54
Definition: polling_entity.h:37
Transport op: a set of operations to perform on a transport as a whole.
Definition: transport.h:332
grpc_error_handle disconnect_with_error
should the transport be disconnected Error contract: the transport that gets this op must cause disco...
Definition: transport.h:344
grpc_error_handle goaway_error
what should the goaway contain? Error contract: the transport that gets this op must cause goaway_err...
Definition: transport.h:348
grpc_metadata_batch * recv_initial_metadata
Definition: transport.h:274
grpc_core::OrphanablePtr< grpc_core::ByteStream > send_message
Definition: transport.h:258
grpc_core::OrphanablePtr< grpc_core::ByteStream > * recv_message
Definition: transport.h:297
grpc_metadata_batch * send_initial_metadata
Definition: transport.h:231
grpc_call_context_element * context
Definition: transport.h:328
Definition: transport.h:163
grpc_transport_stream_op_batch_payload * payload
Values for the stream op (fields set are determined by flags above)
Definition: transport.h:186
bool recv_message
Receive message data from the stream, into provided byte stream.
Definition: transport.h:201
bool recv_trailing_metadata
Receive trailing metadata from the stream, into provided metadata batch.
Definition: transport.h:205
grpc_closure * on_complete
Should be scheduled when all of the non-recv operations in the batch are complete.
Definition: transport.h:183
bool send_trailing_metadata
Send trailing metadata to the peer, from the provided metadata batch.
Definition: transport.h:192
bool send_message
Send message data to the peer, from the provided byte stream.
Definition: transport.h:195
bool send_initial_metadata
Send initial metadata to the peer, from the provided metadata batch.
Definition: transport.h:189
bool recv_initial_metadata
Receive initial metadata from the stream, into provided metadata batch.
Definition: transport.h:198