GRPC Core  18.0.0
client_channel.h
Go to the documentation of this file.
1 //
2 // Copyright 2015 gRPC authors.
3 //
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 //
8 // http://www.apache.org/licenses/LICENSE-2.0
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
15 //
16 
17 #ifndef GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_CLIENT_CHANNEL_H
18 #define GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_CLIENT_CHANNEL_H
19 
21 
22 #include <map>
23 #include <memory>
24 #include <set>
25 #include <string>
26 
27 #include "absl/status/status.h"
28 #include "absl/types/optional.h"
29 
30 #include <grpc/support/log.h>
31 
48 
49 //
50 // Client channel filter
51 //
52 
53 // A client channel is a channel that begins disconnected, and can connect
54 // to some endpoint on demand. If that endpoint disconnects, it will be
55 // connected to again later.
56 //
57 // Calls on a disconnected client channel are queued until a connection is
58 // established.
59 
60 // Channel arg key for server URI string.
61 #define GRPC_ARG_SERVER_URI "grpc.server_uri"
62 
63 // Channel arg containing a pointer to the ClientChannel object.
64 #define GRPC_ARG_CLIENT_CHANNEL "grpc.internal.client_channel"
65 
66 // Channel arg containing a pointer to the ServiceConfig object.
67 #define GRPC_ARG_SERVICE_CONFIG_OBJ "grpc.internal.service_config_obj"
68 
69 // Max number of batches that can be pending on a call at any given
70 // time. This includes one batch for each of the following ops:
71 // recv_initial_metadata
72 // send_initial_metadata
73 // recv_message
74 // send_message
75 // recv_trailing_metadata
76 // send_trailing_metadata
77 #define MAX_PENDING_BATCHES 6
78 
79 namespace grpc_core {
80 
82  public:
84 
85  class LoadBalancedCall;
86 
87  // Returns the ClientChannel object from channel, or null if channel
88  // is not a client channel.
89  static ClientChannel* GetFromChannel(grpc_channel* channel);
90 
92 
93  // Starts a one-time connectivity state watch. When the channel's state
94  // becomes different from *state, sets *state to the new state and
95  // schedules on_complete. The watcher_timer_init callback is invoked as
96  // soon as the watch is actually started (i.e., after hopping into the
97  // client channel combiner). I/O will be serviced via pollent.
98  //
99  // This is intended to be used when starting a watch from outside of C-core
100  // via grpc_channel_watch_connectivity_state(). It should not be used
101  // by other callers.
104  grpc_closure* on_complete,
105  grpc_closure* watcher_timer_init) {
106  new ExternalConnectivityWatcher(this, pollent, state, on_complete,
107  watcher_timer_init);
108  }
109 
110  // Cancels a pending external watcher previously added by
111  // AddExternalConnectivityWatcher().
113  ExternalConnectivityWatcher::RemoveWatcherFromExternalWatchersMap(
114  this, on_complete, /*cancel=*/true);
115  }
116 
118  MutexLock lock(&external_watchers_mu_);
119  return static_cast<int>(external_watchers_.size());
120  }
121 
122  // Starts and stops a connectivity watch. The watcher will be initially
123  // notified as soon as the state changes from initial_state and then on
124  // every subsequent state change until either the watch is stopped or
125  // it is notified that the state has changed to SHUTDOWN.
126  //
127  // This is intended to be used when starting watches from code inside of
128  // C-core (e.g., for a nested control plane channel for things like xds).
130  grpc_connectivity_state initial_state,
134 
136  const grpc_call_element_args& args, grpc_polling_entity* pollent,
137  grpc_closure* on_call_destruction_complete);
138 
139  private:
140  class CallData;
141  class ResolverResultHandler;
142  class SubchannelWrapper;
143  class ClientChannelControlHelper;
144  class ConnectivityWatcherAdder;
145  class ConnectivityWatcherRemover;
146 
147  // Represents a pending connectivity callback from an external caller
148  // via grpc_client_channel_watch_connectivity_state().
149  class ExternalConnectivityWatcher : public ConnectivityStateWatcherInterface {
150  public:
151  ExternalConnectivityWatcher(ClientChannel* chand,
152  grpc_polling_entity pollent,
154  grpc_closure* on_complete,
155  grpc_closure* watcher_timer_init);
156 
157  ~ExternalConnectivityWatcher() override;
158 
159  // Removes the watcher from the external_watchers_ map.
160  static void RemoveWatcherFromExternalWatchersMap(ClientChannel* chand,
161  grpc_closure* on_complete,
162  bool cancel);
163 
164  void Notify(grpc_connectivity_state state,
165  const absl::Status& /* status */) override;
166 
167  void Cancel();
168 
169  private:
170  // Adds the watcher to state_tracker_. Consumes the ref that is passed to it
171  // from Start().
172  void AddWatcherLocked()
173  ABSL_EXCLUSIVE_LOCKS_REQUIRED(chand_->work_serializer_);
174  void RemoveWatcherLocked()
175  ABSL_EXCLUSIVE_LOCKS_REQUIRED(chand_->work_serializer_);
176 
177  ClientChannel* chand_;
178  grpc_polling_entity pollent_;
179  grpc_connectivity_state initial_state_;
180  grpc_connectivity_state* state_;
181  grpc_closure* on_complete_;
182  grpc_closure* watcher_timer_init_;
183  Atomic<bool> done_{false};
184  };
185 
186  struct ResolverQueuedCall {
187  grpc_call_element* elem;
188  ResolverQueuedCall* next = nullptr;
189  };
190  struct LbQueuedCall {
191  LoadBalancedCall* lb_call;
192  LbQueuedCall* next = nullptr;
193  };
194 
195  ClientChannel(grpc_channel_element_args* args, grpc_error_handle* error);
196  ~ClientChannel();
197 
198  // Filter vtable functions.
199  static grpc_error_handle Init(grpc_channel_element* elem,
201  static void Destroy(grpc_channel_element* elem);
202  static void StartTransportOp(grpc_channel_element* elem,
203  grpc_transport_op* op);
204  static void GetChannelInfo(grpc_channel_element* elem,
205  const grpc_channel_info* info);
206 
207  // Note: Does NOT return a new ref.
208  grpc_error_handle disconnect_error() const {
209  return disconnect_error_.Load(MemoryOrder::ACQUIRE);
210  }
211 
212  // Note: All methods with "Locked" suffix must be invoked from within
213  // work_serializer_.
214 
215  void OnResolverResultChangedLocked(Resolver::Result result)
216  ABSL_EXCLUSIVE_LOCKS_REQUIRED(work_serializer_);
217  void OnResolverErrorLocked(grpc_error_handle error)
218  ABSL_EXCLUSIVE_LOCKS_REQUIRED(work_serializer_);
219 
220  void CreateOrUpdateLbPolicyLocked(
221  RefCountedPtr<LoadBalancingPolicy::Config> lb_policy_config,
222  Resolver::Result result) ABSL_EXCLUSIVE_LOCKS_REQUIRED(work_serializer_);
223  OrphanablePtr<LoadBalancingPolicy> CreateLbPolicyLocked(
224  const grpc_channel_args& args)
225  ABSL_EXCLUSIVE_LOCKS_REQUIRED(work_serializer_);
226 
227  void UpdateStateAndPickerLocked(
228  grpc_connectivity_state state, const absl::Status& status,
229  const char* reason,
230  std::unique_ptr<LoadBalancingPolicy::SubchannelPicker> picker)
231  ABSL_EXCLUSIVE_LOCKS_REQUIRED(work_serializer_);
232 
233  void UpdateServiceConfigInControlPlaneLocked(
234  RefCountedPtr<ServiceConfig> service_config,
235  RefCountedPtr<ConfigSelector> config_selector,
236  const internal::ClientChannelGlobalParsedConfig* parsed_service_config,
237  const char* lb_policy_name)
238  ABSL_EXCLUSIVE_LOCKS_REQUIRED(work_serializer_);
239 
240  void UpdateServiceConfigInDataPlaneLocked()
241  ABSL_EXCLUSIVE_LOCKS_REQUIRED(work_serializer_);
242 
243  void CreateResolverLocked() ABSL_EXCLUSIVE_LOCKS_REQUIRED(work_serializer_);
244  void DestroyResolverAndLbPolicyLocked()
245  ABSL_EXCLUSIVE_LOCKS_REQUIRED(work_serializer_);
246 
247  grpc_error_handle DoPingLocked(grpc_transport_op* op)
248  ABSL_EXCLUSIVE_LOCKS_REQUIRED(work_serializer_);
249 
250  void StartTransportOpLocked(grpc_transport_op* op)
251  ABSL_EXCLUSIVE_LOCKS_REQUIRED(work_serializer_);
252 
253  void TryToConnectLocked() ABSL_EXCLUSIVE_LOCKS_REQUIRED(work_serializer_);
254 
255  // These methods all require holding resolution_mu_.
256  void AddResolverQueuedCall(ResolverQueuedCall* call,
257  grpc_polling_entity* pollent)
258  ABSL_EXCLUSIVE_LOCKS_REQUIRED(resolution_mu_);
259  void RemoveResolverQueuedCall(ResolverQueuedCall* to_remove,
260  grpc_polling_entity* pollent)
261  ABSL_EXCLUSIVE_LOCKS_REQUIRED(resolution_mu_);
262 
263  // These methods all require holding data_plane_mu_.
264  void AddLbQueuedCall(LbQueuedCall* call, grpc_polling_entity* pollent)
265  ABSL_EXCLUSIVE_LOCKS_REQUIRED(data_plane_mu_);
266  void RemoveLbQueuedCall(LbQueuedCall* to_remove, grpc_polling_entity* pollent)
267  ABSL_EXCLUSIVE_LOCKS_REQUIRED(data_plane_mu_);
268  RefCountedPtr<ConnectedSubchannel> GetConnectedSubchannelInDataPlane(
269  SubchannelInterface* subchannel) const
270  ABSL_EXCLUSIVE_LOCKS_REQUIRED(data_plane_mu_);
271 
272  //
273  // Fields set at construction and never modified.
274  //
275  const bool deadline_checking_enabled_;
276  const bool enable_retries_;
277  grpc_channel_stack* owning_stack_;
278  ClientChannelFactory* client_channel_factory_;
279  const grpc_channel_args* channel_args_;
280  RefCountedPtr<ServiceConfig> default_service_config_;
281  std::string server_name_;
282  UniquePtr<char> target_uri_;
283  channelz::ChannelNode* channelz_node_;
284  grpc_pollset_set* interested_parties_;
285 
286  //
287  // Fields related to name resolution. Guarded by resolution_mu_.
288  //
289  mutable Mutex resolution_mu_;
290  // Linked list of calls queued waiting for resolver result.
291  ResolverQueuedCall* resolver_queued_calls_ ABSL_GUARDED_BY(resolution_mu_) =
292  nullptr;
293  // Data from service config.
294  grpc_error_handle resolver_transient_failure_error_
295  ABSL_GUARDED_BY(resolution_mu_) = GRPC_ERROR_NONE;
296  bool received_service_config_data_ ABSL_GUARDED_BY(resolution_mu_) = false;
297  RefCountedPtr<ServiceConfig> service_config_ ABSL_GUARDED_BY(resolution_mu_);
298  RefCountedPtr<ConfigSelector> config_selector_
299  ABSL_GUARDED_BY(resolution_mu_);
300  RefCountedPtr<DynamicFilters> dynamic_filters_
301  ABSL_GUARDED_BY(resolution_mu_);
302 
303  //
304  // Fields used in the data plane. Guarded by data_plane_mu_.
305  //
306  mutable Mutex data_plane_mu_;
307  std::unique_ptr<LoadBalancingPolicy::SubchannelPicker> picker_
308  ABSL_GUARDED_BY(data_plane_mu_);
309  // Linked list of calls queued waiting for LB pick.
310  LbQueuedCall* lb_queued_calls_ ABSL_GUARDED_BY(data_plane_mu_) = nullptr;
311 
312  //
313  // Fields used in the control plane. Guarded by work_serializer.
314  //
315  std::shared_ptr<WorkSerializer> work_serializer_;
316  ConnectivityStateTracker state_tracker_ ABSL_GUARDED_BY(work_serializer_);
317  OrphanablePtr<Resolver> resolver_ ABSL_GUARDED_BY(work_serializer_);
318  bool previous_resolution_contained_addresses_
319  ABSL_GUARDED_BY(work_serializer_) = false;
320  RefCountedPtr<ServiceConfig> saved_service_config_
321  ABSL_GUARDED_BY(work_serializer_);
322  RefCountedPtr<ConfigSelector> saved_config_selector_
323  ABSL_GUARDED_BY(work_serializer_);
324  absl::optional<std::string> health_check_service_name_
325  ABSL_GUARDED_BY(work_serializer_);
326  OrphanablePtr<LoadBalancingPolicy> lb_policy_
327  ABSL_GUARDED_BY(work_serializer_);
328  RefCountedPtr<SubchannelPoolInterface> subchannel_pool_
329  ABSL_GUARDED_BY(work_serializer_);
330  // The number of SubchannelWrapper instances referencing a given Subchannel.
331  std::map<Subchannel*, int> subchannel_refcount_map_
332  ABSL_GUARDED_BY(work_serializer_);
333  // The set of SubchannelWrappers that currently exist.
334  // No need to hold a ref, since the map is updated in the control-plane
335  // work_serializer when the SubchannelWrappers are created and destroyed.
336  std::set<SubchannelWrapper*> subchannel_wrappers_
337  ABSL_GUARDED_BY(work_serializer_);
338  // Pending ConnectedSubchannel updates for each SubchannelWrapper.
339  // Updates are queued here in the control plane work_serializer and then
340  // applied in the data plane mutex when the picker is updated.
341  std::map<RefCountedPtr<SubchannelWrapper>, RefCountedPtr<ConnectedSubchannel>>
342  pending_subchannel_updates_ ABSL_GUARDED_BY(work_serializer_);
343  int keepalive_time_ ABSL_GUARDED_BY(work_serializer_) = -1;
344 
345  //
346  // Fields accessed from both data plane mutex and control plane
347  // work_serializer.
348  //
349  Atomic<grpc_error_handle> disconnect_error_;
350 
351  //
352  // Fields guarded by a mutex, since they need to be accessed
353  // synchronously via get_channel_info().
354  //
355  Mutex info_mu_;
356  UniquePtr<char> info_lb_policy_name_ ABSL_GUARDED_BY(info_mu_);
357  UniquePtr<char> info_service_config_json_ ABSL_GUARDED_BY(info_mu_);
358 
359  //
360  // Fields guarded by a mutex, since they need to be accessed
361  // synchronously via grpc_channel_num_external_connectivity_watchers().
362  //
363  mutable Mutex external_watchers_mu_;
364  std::map<grpc_closure*, RefCountedPtr<ExternalConnectivityWatcher>>
365  external_watchers_ ABSL_GUARDED_BY(external_watchers_mu_);
366 };
367 
368 //
369 // ClientChannel::LoadBalancedCall
370 //
371 
372 // This object is ref-counted, but it cannot inherit from RefCounted<>,
373 // because it is allocated on the arena and can't free its memory when
374 // its refcount goes to zero. So instead, it manually implements the
375 // same API as RefCounted<>, so that it can be used with RefCountedPtr<>.
378  public:
379  // If on_call_destruction_complete is non-null, then it will be
380  // invoked once the LoadBalancedCall is completely destroyed.
381  // If it is null, then the caller is responsible for checking whether
382  // the LB call has a subchannel call and ensuring that the
383  // on_call_destruction_complete closure passed down from the surface
384  // is not invoked until after the subchannel call stack is destroyed.
386  grpc_polling_entity* pollent,
387  grpc_closure* on_call_destruction_complete);
388  ~LoadBalancedCall() override;
389 
390  void StartTransportStreamOpBatch(grpc_transport_stream_op_batch* batch);
391 
392  // Invoked by channel for queued LB picks when the picker is updated.
393  static void PickSubchannel(void* arg, grpc_error_handle error);
394  // Helper function for performing an LB pick while holding the data plane
395  // mutex. Returns true if the pick is complete, in which case the caller
396  // must invoke PickDone() or AsyncPickDone() with the returned error.
397  bool PickSubchannelLocked(grpc_error_handle* error)
398  ABSL_EXCLUSIVE_LOCKS_REQUIRED(&ClientChannel::data_plane_mu_);
399  // Schedules a callback to process the completed pick. The callback
400  // will not run until after this method returns.
402 
404  return subchannel_call_;
405  }
406 
407  private:
408  class LbQueuedCallCanceller;
409  class Metadata;
410  class LbCallState;
411 
412  // Returns the index into pending_batches_ to be used for batch.
413  static size_t GetBatchIndex(grpc_transport_stream_op_batch* batch);
414  void PendingBatchesAdd(grpc_transport_stream_op_batch* batch);
415  static void FailPendingBatchInCallCombiner(void* arg,
417  // A predicate type and some useful implementations for PendingBatchesFail().
418  typedef bool (*YieldCallCombinerPredicate)(
419  const CallCombinerClosureList& closures);
420  static bool YieldCallCombiner(const CallCombinerClosureList& /*closures*/) {
421  return true;
422  }
423  static bool NoYieldCallCombiner(const CallCombinerClosureList& /*closures*/) {
424  return false;
425  }
426  static bool YieldCallCombinerIfPendingBatchesFound(
427  const CallCombinerClosureList& closures) {
428  return closures.size() > 0;
429  }
430  // Fails all pending batches.
431  // If yield_call_combiner_predicate returns true, assumes responsibility for
432  // yielding the call combiner.
433  void PendingBatchesFail(
435  YieldCallCombinerPredicate yield_call_combiner_predicate);
436  static void ResumePendingBatchInCallCombiner(void* arg,
437  grpc_error_handle ignored);
438  // Resumes all pending batches on subchannel_call_.
439  void PendingBatchesResume();
440 
441  static void RecvTrailingMetadataReadyForLoadBalancingPolicy(
442  void* arg, grpc_error_handle error);
443  void InjectRecvTrailingMetadataReadyForLoadBalancingPolicy(
445 
446  void CreateSubchannelCall();
447  // Invoked when a pick is completed, on both success or failure.
448  static void PickDone(void* arg, grpc_error_handle error);
449  // Removes the call from the channel's list of queued picks if present.
450  void MaybeRemoveCallFromLbQueuedCallsLocked()
451  ABSL_EXCLUSIVE_LOCKS_REQUIRED(&ClientChannel::data_plane_mu_);
452  // Adds the call to the channel's list of queued picks if not already present.
453  void MaybeAddCallToLbQueuedCallsLocked()
454  ABSL_EXCLUSIVE_LOCKS_REQUIRED(&ClientChannel::data_plane_mu_);
455 
456  ClientChannel* chand_;
457 
458  // TODO(roth): Instead of duplicating these fields in every filter
459  // that uses any one of them, we should store them in the call
460  // context. This will save per-call memory overhead.
461  grpc_slice path_; // Request path.
462  gpr_cycle_counter call_start_time_;
463  grpc_millis deadline_;
464  Arena* arena_;
465  grpc_call_stack* owning_call_;
466  CallCombiner* call_combiner_;
467  grpc_call_context_element* call_context_;
468  grpc_polling_entity* pollent_;
469  grpc_closure* on_call_destruction_complete_;
470 
471  // Set when we get a cancel_stream op.
472  grpc_error_handle cancel_error_ = GRPC_ERROR_NONE;
473 
474  // Set when we fail inside the LB call.
475  grpc_error_handle failure_error_ = GRPC_ERROR_NONE;
476 
477  grpc_closure pick_closure_;
478 
479  // Accessed while holding ClientChannel::data_plane_mu_.
480  ClientChannel::LbQueuedCall queued_call_
481  ABSL_GUARDED_BY(&ClientChannel::data_plane_mu_);
482  bool queued_pending_lb_pick_ ABSL_GUARDED_BY(&ClientChannel::data_plane_mu_) =
483  false;
484  LbQueuedCallCanceller* lb_call_canceller_
485  ABSL_GUARDED_BY(&ClientChannel::data_plane_mu_) = nullptr;
486 
487  RefCountedPtr<ConnectedSubchannel> connected_subchannel_;
488  const LoadBalancingPolicy::BackendMetricData* backend_metric_data_ = nullptr;
489  std::function<void(grpc_error_handle, LoadBalancingPolicy::MetadataInterface*,
490  LoadBalancingPolicy::CallState*)>
491  lb_recv_trailing_metadata_ready_;
492 
493  RefCountedPtr<SubchannelCall> subchannel_call_;
494 
495  // For intercepting recv_trailing_metadata_ready for the LB policy.
496  grpc_metadata_batch* recv_trailing_metadata_ = nullptr;
497  grpc_closure recv_trailing_metadata_ready_;
498  grpc_closure* original_recv_trailing_metadata_ready_ = nullptr;
499 
500  // Batches are added to this list when received from above.
501  // They are removed when we are done handling the batch (i.e., when
502  // either we have invoked all of the batch's callbacks or we have
503  // passed the batch down to the subchannel call and are not
504  // intercepting any of its callbacks).
505  grpc_transport_stream_op_batch* pending_batches_[MAX_PENDING_BATCHES] = {};
506 };
507 
508 } // namespace grpc_core
509 
510 #endif // GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_CLIENT_CHANNEL_H
ClusterWatcher * watcher
Definition: cds.cc:112
Definition: connectivity_state.h:66
Definition: atomic.h:40
Definition: call_combiner.h:144
Definition: client_channel.h:377
RefCountedPtr< SubchannelCall > subchannel_call() const
Definition: client_channel.h:403
bool PickSubchannelLocked(grpc_error_handle *error) ABSL_EXCLUSIVE_LOCKS_REQUIRED(&ClientChannel voi AsyncPickDone)(grpc_error_handle error)
Definition: client_channel.h:401
Definition: client_channel.h:81
static ClientChannel * GetFromChannel(grpc_channel *channel)
Definition: client_channel.cc:1040
void AddExternalConnectivityWatcher(grpc_polling_entity pollent, grpc_connectivity_state *state, grpc_closure *on_complete, grpc_closure *watcher_timer_init)
Definition: client_channel.h:102
RefCountedPtr< LoadBalancedCall > CreateLoadBalancedCall(const grpc_call_element_args &args, grpc_polling_entity *pollent, grpc_closure *on_call_destruction_complete)
Definition: client_channel.cc:1173
int NumExternalConnectivityWatchers() const
Definition: client_channel.h:117
void RemoveConnectivityWatcher(AsyncConnectivityStateWatcherInterface *watcher)
Definition: client_channel.cc:1855
void AddConnectivityWatcher(grpc_connectivity_state initial_state, OrphanablePtr< AsyncConnectivityStateWatcherInterface > watcher)
Definition: client_channel.cc:1849
void CancelExternalConnectivityWatcher(grpc_closure *on_complete)
Definition: client_channel.h:112
static const grpc_channel_filter kFilterVtable
Definition: client_channel.h:83
grpc_connectivity_state CheckConnectivityState(bool try_to_connect)
Definition: client_channel.cc:1833
Definition: connectivity_state.h:51
Definition: sync.h:85
Definition: ref_counted.h:205
Definition: ref_counted.h:282
Definition: ref_counted_ptr.h:35
#define MAX_PENDING_BATCHES
Definition: client_channel.h:77
#define GRPC_ERROR_NONE
The following "special" errors can be propagated without allocating memory.
Definition: error.h:228
int64_t grpc_millis
Definition: exec_ctx.h:37
grpc_connectivity_state
Connectivity state of a channel.
Definition: connectivity_state.h:27
grpc_error_handle error
Definition: lame_client.cc:54
Round Robin Policy.
Definition: backend_metric.cc:26
std::unique_ptr< T, DefaultDeleteChar > UniquePtr
Definition: memory.h:47
@ kUnrefCallDtor
Definition: ref_counted.h:231
std::unique_ptr< T, Deleter > OrphanablePtr
Definition: orphanable.h:67
struct grpc_pollset_set grpc_pollset_set
Definition: pollset_set.h:31
grpc_transport_stream_op_batch * batch
Definition: retry_filter.cc:208
RefCountedPtr< SubchannelInterface > subchannel
Definition: ring_hash.cc:213
Definition: context.h:44
Definition: channel_stack.h:76
Definition: channel_stack.h:174
Definition: channel_stack.h:192
An array of arguments that can be passed around.
Definition: grpc_types.h:132
Definition: channel_stack.h:68
Definition: channel_stack.h:166
Definition: channel_stack.h:107
Information requested from the channel.
Definition: grpc_types.h:704
Definition: channel_stack.h:182
Definition: channel.h:105
A closure over a grpc_iomgr_cb_func.
Definition: closure.h:56
Definition: error_internal.h:41
Definition: metadata_batch.h:52
Definition: polling_entity.h:37
A grpc_slice s, if initialized, represents the byte range s.bytes[0..s.length-1].
Definition: slice.h:60
Transport op: a set of operations to perform on a transport as a whole.
Definition: transport.h:332
Definition: transport.h:163