dynamic_filters.cc
Go to the documentation of this file.
1 //
2 // Copyright 2020 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 
18 
20 
21 #include <stddef.h>
22 
23 #include <new>
24 #include <string>
25 #include <utility>
26 
27 #include "absl/status/status.h"
28 
29 #include <grpc/support/alloc.h>
30 #include <grpc/support/log.h>
31 
35 #include "src/core/lib/gpr/alloc.h"
37 
38 // Conversion between call and call stack.
39 #define CALL_TO_CALL_STACK(call) \
40  (grpc_call_stack*)((char*)(call) + GPR_ROUND_UP_TO_ALIGNMENT_SIZE( \
41  sizeof(DynamicFilters::Call)))
42 #define CALL_STACK_TO_CALL(callstack) \
43  (DynamicFilters::Call*)(((char*)(call_stack)) - \
44  GPR_ROUND_UP_TO_ALIGNMENT_SIZE( \
45  sizeof(DynamicFilters::Call)))
46 
47 namespace grpc_core {
48 
49 //
50 // DynamicFilters::Call
51 //
52 
54  : channel_stack_(std::move(args.channel_stack)) {
55  grpc_call_stack* call_stack = CALL_TO_CALL_STACK(this);
56  const grpc_call_element_args call_args = {
57  call_stack, /* call_stack */
58  nullptr, /* server_transport_data */
59  args.context, /* context */
60  args.path, /* path */
61  args.start_time, /* start_time */
62  args.deadline, /* deadline */
63  args.arena, /* arena */
64  args.call_combiner /* call_combiner */
65  };
66  *error = grpc_call_stack_init(channel_stack_->channel_stack_, 1, Destroy,
67  this, &call_args);
69  gpr_log(GPR_ERROR, "error: %s", grpc_error_std_string(*error).c_str());
70  return;
71  }
73 }
74 
77  grpc_call_stack* call_stack = CALL_TO_CALL_STACK(this);
78  grpc_call_element* top_elem = grpc_call_stack_element(call_stack, 0);
79  GRPC_CALL_LOG_OP(GPR_INFO, top_elem, batch);
80  top_elem->filter->start_transport_stream_op_batch(top_elem, batch);
81 }
82 
84  GPR_ASSERT(after_call_stack_destroy_ == nullptr);
85  GPR_ASSERT(closure != nullptr);
86  after_call_stack_destroy_ = closure;
87 }
88 
92 }
93 
95  const DebugLocation& location, const char* reason) {
96  IncrementRefCount(location, reason);
98 }
99 
101  GRPC_CALL_STACK_UNREF(CALL_TO_CALL_STACK(this), "dynamic-filters-unref");
102 }
103 
105  const char* reason) {
107 }
108 
110  DynamicFilters::Call* self = static_cast<DynamicFilters::Call*>(arg);
111  // Keep some members before destroying the subchannel call.
112  grpc_closure* after_call_stack_destroy = self->after_call_stack_destroy_;
113  RefCountedPtr<DynamicFilters> channel_stack = std::move(self->channel_stack_);
114  // Destroy the subchannel call.
115  self->~Call();
116  // Destroy the call stack. This should be after destroying the call, because
117  // call->after_call_stack_destroy(), if not null, will free the call arena.
119  after_call_stack_destroy);
120  // Automatically reset channel_stack. This should be after destroying the call
121  // stack, because destroying call stack needs access to the channel stack.
122 }
123 
126 }
127 
129  const char* reason) {
131 }
132 
133 //
134 // DynamicFilters
135 //
136 
137 namespace {
138 
139 void DestroyChannelStack(void* arg, grpc_error_handle /*error*/) {
140  grpc_channel_stack* channel_stack = static_cast<grpc_channel_stack*>(arg);
141  grpc_channel_stack_destroy(channel_stack);
142  gpr_free(channel_stack);
143 }
144 
145 std::pair<grpc_channel_stack*, grpc_error_handle> CreateChannelStack(
146  const grpc_channel_args* args,
147  std::vector<const grpc_channel_filter*> filters) {
148  // Allocate memory for channel stack.
149  const size_t channel_stack_size =
150  grpc_channel_stack_size(filters.data(), filters.size());
151  grpc_channel_stack* channel_stack =
152  reinterpret_cast<grpc_channel_stack*>(gpr_zalloc(channel_stack_size));
153  // Initialize stack.
155  /*initial_refs=*/1, DestroyChannelStack, channel_stack, filters.data(),
156  filters.size(), args, "DynamicFilters", channel_stack);
157  if (!GRPC_ERROR_IS_NONE(error)) {
158  gpr_log(GPR_ERROR, "error initializing client internal stack: %s",
160  grpc_channel_stack_destroy(channel_stack);
161  gpr_free(channel_stack);
162  return {nullptr, error};
163  }
164  return {channel_stack, GRPC_ERROR_NONE};
165 }
166 
167 } // namespace
168 
170  const grpc_channel_args* args,
171  std::vector<const grpc_channel_filter*> filters) {
172  // Attempt to create channel stack from requested filters.
173  auto p = CreateChannelStack(args, std::move(filters));
174  if (!GRPC_ERROR_IS_NONE(p.second)) {
175  // Channel stack creation failed with requested filters.
176  // Create with lame filter instead.
177  grpc_error_handle error = p.second;
178  grpc_arg error_arg = MakeLameClientErrorArg(&error);
179  grpc_channel_args* new_args =
180  grpc_channel_args_copy_and_add(args, &error_arg, 1);
182  p = CreateChannelStack(new_args, {&LameClientFilter::kFilter});
183  GPR_ASSERT(GRPC_ERROR_IS_NONE(p.second));
184  grpc_channel_args_destroy(new_args);
185  }
186  return MakeRefCounted<DynamicFilters>(p.first);
187 }
188 
190  GRPC_CHANNEL_STACK_UNREF(channel_stack_, "~DynamicFilters");
191 }
192 
195  size_t allocation_size = GPR_ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(Call)) +
197  Call* call = static_cast<Call*>(args.arena->Alloc(allocation_size));
198  new (call) Call(std::move(args), error);
200 }
201 
202 } // namespace grpc_core
grpc_arg
Definition: grpc_types.h:103
trace.h
GPR_INFO
#define GPR_INFO
Definition: include/grpc/impl/codegen/log.h:56
GRPC_ERROR_NONE
#define GRPC_ERROR_NONE
Definition: error.h:234
log.h
lame_client.h
grpc_core::DebugLocation
Definition: debug_location.h:31
grpc_channel_stack
Definition: channel_stack.h:202
grpc_core::LameClientFilter::kFilter
static const grpc_channel_filter kFilter
Definition: lame_client.h:49
grpc_core
Definition: call_metric_recorder.h:31
grpc_call_stack_set_pollset_or_pollset_set
void grpc_call_stack_set_pollset_or_pollset_set(grpc_call_stack *call_stack, grpc_polling_entity *pollent)
Definition: channel_stack.cc:219
GRPC_CHANNEL_STACK_UNREF
#define GRPC_CHANNEL_STACK_UNREF(channel_stack, reason)
Definition: channel_stack.h:299
grpc_core::MakeLameClientErrorArg
grpc_arg MakeLameClientErrorArg(grpc_error_handle *error)
Definition: lame_client.cc:123
gpr_free
GPRAPI void gpr_free(void *ptr)
Definition: alloc.cc:51
error
grpc_error_handle error
Definition: retry_filter.cc:499
grpc_core::DynamicFilters::Call::Unref
void Unref()
Definition: dynamic_filters.cc:100
grpc_call_stack_init
grpc_error_handle grpc_call_stack_init(grpc_channel_stack *channel_stack, int initial_refs, grpc_iomgr_cb_func destroy, void *destroy_arg, const grpc_call_element_args *elem_args)
Definition: channel_stack.cc:180
grpc_call_stack_element
grpc_call_element * grpc_call_stack_element(grpc_call_stack *call_stack, size_t index)
Definition: channel_stack.cc:100
grpc_channel_stack_destroy
void grpc_channel_stack_destroy(grpc_channel_stack *stack)
Definition: channel_stack.cc:166
grpc_call_element
Definition: channel_stack.h:194
grpc_core::DynamicFilters::Call
Definition: dynamic_filters.h:46
grpc_channel_args
Definition: grpc_types.h:132
GRPC_CALL_LOG_OP
#define GRPC_CALL_LOG_OP(sev, elem, op)
Definition: channel_stack.h:374
grpc_core::DynamicFilters::Create
static RefCountedPtr< DynamicFilters > Create(const grpc_channel_args *args, std::vector< const grpc_channel_filter * > filters)
Definition: dynamic_filters.cc:169
grpc_core::DynamicFilters::Call::Ref
RefCountedPtr< Call > Ref() GRPC_MUST_USE_RESULT
Definition: dynamic_filters.cc:89
call
FilterStackCall * call
Definition: call.cc:750
alloc.h
CALL_TO_CALL_STACK
#define CALL_TO_CALL_STACK(call)
Definition: dynamic_filters.cc:39
gpr_zalloc
GPRAPI void * gpr_zalloc(size_t size)
Definition: alloc.cc:40
grpc_core::DynamicFilters::channel_stack_
grpc_channel_stack * channel_stack_
Definition: dynamic_filters.h:104
grpc_channel_stack::call_stack_size
size_t call_stack_size
Definition: channel_stack.h:208
grpc_core::RefCounted< DynamicFilters >::IncrementRefCount
void IncrementRefCount()
Definition: ref_counted.h:339
GPR_ROUND_UP_TO_ALIGNMENT_SIZE
#define GPR_ROUND_UP_TO_ALIGNMENT_SIZE(x)
Given a size, round up to the next multiple of sizeof(void*).
Definition: src/core/lib/gpr/alloc.h:25
GRPC_CALL_STACK_UNREF
#define GRPC_CALL_STACK_UNREF(call_stack, reason)
Definition: channel_stack.h:295
grpc_core::DynamicFilters::CreateCall
RefCountedPtr< Call > CreateCall(Call::Args args, grpc_error_handle *error)
Definition: dynamic_filters.cc:193
asyncio_get_stats.args
args
Definition: asyncio_get_stats.py:40
grpc_core::RefCountedPtr
Definition: ref_counted_ptr.h:35
absl::move
constexpr absl::remove_reference_t< T > && move(T &&t) noexcept
Definition: abseil-cpp/absl/utility/utility.h:221
GPR_ASSERT
#define GPR_ASSERT(x)
Definition: include/grpc/impl/codegen/log.h:94
gen_stats_data.c_str
def c_str(s, encoding='ascii')
Definition: gen_stats_data.py:38
channel_stack.h
grpc_call_stack
Definition: channel_stack.h:233
grpc_call_element::filter
const grpc_channel_filter * filter
Definition: channel_stack.h:195
gpr_log
GPRAPI void gpr_log(const char *file, int line, gpr_log_severity severity, const char *format,...) GPR_PRINT_FORMAT_CHECK(4
GPR_UNLIKELY
#define GPR_UNLIKELY(x)
Definition: impl/codegen/port_platform.h:770
closure
grpc_closure closure
Definition: src/core/lib/surface/server.cc:466
grpc_core::DynamicFilters::Call::StartTransportStreamOpBatch
void StartTransportStreamOpBatch(grpc_transport_stream_op_batch *batch)
Definition: dynamic_filters.cc:75
grpc_channel_args_destroy
void grpc_channel_args_destroy(grpc_channel_args *a)
Definition: channel_args.cc:360
arg
Definition: cmdline.cc:40
grpc_call_stack_destroy
void grpc_call_stack_destroy(grpc_call_stack *stack, const grpc_call_final_info *final_info, grpc_closure *then_schedule_closure)
Definition: channel_stack.cc:236
grpc_core::DynamicFilters::~DynamicFilters
~DynamicFilters() override
Definition: dynamic_filters.cc:189
channel_stack_
RefCountedPtr< grpc_channel_stack > channel_stack_
Definition: filter_fuzzer.cc:570
grpc_call_element_args
Definition: channel_stack.h:80
batch
grpc_transport_stream_op_batch * batch
Definition: retry_filter.cc:243
GPR_ERROR
#define GPR_ERROR
Definition: include/grpc/impl/codegen/log.h:57
grpc_core::DynamicFilters::Call::Args
Definition: dynamic_filters.h:48
grpc_channel_filter::start_transport_stream_op_batch
void(* start_transport_stream_op_batch)(grpc_call_element *elem, grpc_transport_stream_op_batch *op)
Definition: channel_stack.h:114
grpc_core::DynamicFilters::Call::IncrementRefCount
void IncrementRefCount()
Definition: dynamic_filters.cc:124
grpc_channel_stack_size
size_t grpc_channel_stack_size(const grpc_channel_filter **filters, size_t filter_count)
Definition: channel_stack.cc:51
tests.unit._server_ssl_cert_config_test.Call
Call
Definition: _server_ssl_cert_config_test.py:70
grpc_core::DynamicFilters::Call::Call
Call(Args args, grpc_error_handle *error)
Definition: dynamic_filters.cc:53
grpc_error_std_string
std::string grpc_error_std_string(grpc_error_handle error)
Definition: error.cc:944
alloc.h
std
Definition: grpcpp/impl/codegen/async_unary_call.h:407
grpc_core::DynamicFilters::Call::Destroy
static void Destroy(void *arg, grpc_error_handle error)
Definition: dynamic_filters.cc:109
dynamic_filters.h
grpc_channel_stack_init
grpc_error_handle grpc_channel_stack_init(int initial_refs, grpc_iomgr_cb_func destroy, void *destroy_arg, const grpc_channel_filter **filters, size_t filter_count, const grpc_channel_args *channel_args, const char *name, grpc_channel_stack *stack)
Definition: channel_stack.cc:105
arg
struct arg arg
closure
Definition: proxy.cc:59
GRPC_ERROR_UNREF
#define GRPC_ERROR_UNREF(err)
Definition: error.h:262
channel_args.h
grpc_error
Definition: error_internal.h:42
GRPC_CALL_STACK_REF
#define GRPC_CALL_STACK_REF(call_stack, reason)
Definition: channel_stack.h:293
self
PHP_PROTO_OBJECT_FREE_END PHP_PROTO_OBJECT_DTOR_END intern self
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/map.c:543
grpc_transport_stream_op_batch
Definition: transport.h:284
grpc_closure
Definition: closure.h:56
grpc_core::DynamicFilters::Call::channel_stack_
RefCountedPtr< DynamicFilters > channel_stack_
Definition: dynamic_filters.h:88
grpc_core::DynamicFilters::Call::SetAfterCallStackDestroy
void SetAfterCallStackDestroy(grpc_closure *closure)
Definition: dynamic_filters.cc:83
grpc_channel_args_copy_and_add
grpc_channel_args * grpc_channel_args_copy_and_add(const grpc_channel_args *src, const grpc_arg *to_add, size_t num_to_add)
Definition: channel_args.cc:224
GRPC_ERROR_IS_NONE
#define GRPC_ERROR_IS_NONE(err)
Definition: error.h:241
port_platform.h


grpc
Author(s):
autogenerated on Fri May 16 2025 02:58:17