|
|
|
@ -344,6 +344,48 @@ struct AddOpImpl< |
|
|
|
|
} |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
// $VALUE_HANDLE $INTERCEPTOR_NAME($VALUE_HANDLE, FilterType*)
|
|
|
|
|
template <typename FilterType, typename T, |
|
|
|
|
T (FilterType::Call::*impl)(T, FilterType*)> |
|
|
|
|
struct AddOpImpl<FilterType, T, T (FilterType::Call::*)(T, FilterType*), impl> { |
|
|
|
|
static void Add(FilterType* channel_data, size_t call_offset, |
|
|
|
|
Layout<FallibleOperator<T>>& to) { |
|
|
|
|
to.Add( |
|
|
|
|
0, 0, |
|
|
|
|
FallibleOperator<T>{ |
|
|
|
|
channel_data, |
|
|
|
|
call_offset, |
|
|
|
|
[](void*, void* call_data, void* channel_data, |
|
|
|
|
T value) -> Poll<ResultOr<T>> { |
|
|
|
|
return ResultOr<T>{ |
|
|
|
|
(static_cast<typename FilterType::Call*>(call_data)->*impl)( |
|
|
|
|
std::move(value), static_cast<FilterType*>(channel_data)), |
|
|
|
|
nullptr}; |
|
|
|
|
}, |
|
|
|
|
nullptr, |
|
|
|
|
nullptr, |
|
|
|
|
}); |
|
|
|
|
} |
|
|
|
|
static void Add(FilterType* channel_data, size_t call_offset, |
|
|
|
|
Layout<InfallibleOperator<T>>& to) { |
|
|
|
|
to.Add( |
|
|
|
|
0, 0, |
|
|
|
|
InfallibleOperator<T>{ |
|
|
|
|
channel_data, |
|
|
|
|
call_offset, |
|
|
|
|
[](void*, void* call_data, void* channel_data, T value) -> Poll<T> { |
|
|
|
|
(static_cast<typename FilterType::Call*>(call_data)->*impl)( |
|
|
|
|
*value, static_cast<FilterType*>(channel_data)); |
|
|
|
|
return ( |
|
|
|
|
static_cast<typename FilterType::Call*>(call_data)->*impl)( |
|
|
|
|
std::move(value), static_cast<FilterType*>(channel_data)); |
|
|
|
|
}, |
|
|
|
|
nullptr, |
|
|
|
|
nullptr, |
|
|
|
|
}); |
|
|
|
|
} |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
// absl::Status $INTERCEPTOR_NAME($VALUE_TYPE&)
|
|
|
|
|
template <typename FilterType, typename T, |
|
|
|
|
absl::Status (FilterType::Call::*impl)(typename T::element_type&)> |
|
|
|
@ -369,6 +411,52 @@ struct AddOpImpl<FilterType, T, |
|
|
|
|
nullptr, |
|
|
|
|
}); |
|
|
|
|
} |
|
|
|
|
static void Add(FilterType* channel_data, size_t call_offset, |
|
|
|
|
Layout<InfallibleOperator<T>>& to) { |
|
|
|
|
to.Add( |
|
|
|
|
0, 0, |
|
|
|
|
InfallibleOperator<T>{ |
|
|
|
|
channel_data, |
|
|
|
|
call_offset, |
|
|
|
|
[](void*, void* call_data, void*, T value) -> Poll<T> { |
|
|
|
|
auto r = |
|
|
|
|
(static_cast<typename FilterType::Call*>(call_data)->*impl)( |
|
|
|
|
*value); |
|
|
|
|
if (r.ok()) return std::move(value); |
|
|
|
|
return StatusCast<ServerMetadataHandle>(std::move(r)); |
|
|
|
|
}, |
|
|
|
|
nullptr, |
|
|
|
|
nullptr, |
|
|
|
|
}); |
|
|
|
|
} |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
// absl::Status $INTERCEPTOR_NAME(const $VALUE_TYPE&)
|
|
|
|
|
template <typename FilterType, typename T, |
|
|
|
|
absl::Status (FilterType::Call::*impl)( |
|
|
|
|
const typename T::element_type&)> |
|
|
|
|
struct AddOpImpl< |
|
|
|
|
FilterType, T, |
|
|
|
|
absl::Status (FilterType::Call::*)(const typename T::element_type&), impl> { |
|
|
|
|
static void Add(FilterType* channel_data, size_t call_offset, |
|
|
|
|
Layout<FallibleOperator<T>>& to) { |
|
|
|
|
to.Add( |
|
|
|
|
0, 0, |
|
|
|
|
FallibleOperator<T>{ |
|
|
|
|
channel_data, |
|
|
|
|
call_offset, |
|
|
|
|
[](void*, void* call_data, void*, T value) -> Poll<ResultOr<T>> { |
|
|
|
|
auto r = |
|
|
|
|
(static_cast<typename FilterType::Call*>(call_data)->*impl)( |
|
|
|
|
*value); |
|
|
|
|
if (r.ok()) return ResultOr<T>{std::move(value), nullptr}; |
|
|
|
|
return ResultOr<T>{ |
|
|
|
|
nullptr, StatusCast<ServerMetadataHandle>(std::move(r))}; |
|
|
|
|
}, |
|
|
|
|
nullptr, |
|
|
|
|
nullptr, |
|
|
|
|
}); |
|
|
|
|
} |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
// absl::Status $INTERCEPTOR_NAME($VALUE_TYPE&, FilterType*)
|
|
|
|
@ -401,6 +489,64 @@ struct AddOpImpl<FilterType, T, |
|
|
|
|
} |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
// absl::Status $INTERCEPTOR_NAME(const $VALUE_TYPE&, FilterType*)
|
|
|
|
|
template <typename FilterType, typename T, |
|
|
|
|
absl::Status (FilterType::Call::*impl)(typename T::element_type&, |
|
|
|
|
FilterType*)> |
|
|
|
|
struct AddOpImpl<FilterType, T, |
|
|
|
|
absl::Status (FilterType::Call::*)( |
|
|
|
|
const typename T::element_type&, FilterType*), |
|
|
|
|
impl> { |
|
|
|
|
static void Add(FilterType* channel_data, size_t call_offset, |
|
|
|
|
Layout<FallibleOperator<T>>& to) { |
|
|
|
|
to.Add( |
|
|
|
|
0, 0, |
|
|
|
|
FallibleOperator<T>{ |
|
|
|
|
channel_data, |
|
|
|
|
call_offset, |
|
|
|
|
[](void*, void* call_data, void* channel_data, |
|
|
|
|
T value) -> Poll<ResultOr<T>> { |
|
|
|
|
auto r = |
|
|
|
|
(static_cast<typename FilterType::Call*>(call_data)->*impl)( |
|
|
|
|
*value, static_cast<FilterType*>(channel_data)); |
|
|
|
|
if (IsStatusOk(r)) return ResultOr<T>{std::move(value), nullptr}; |
|
|
|
|
return ResultOr<T>{ |
|
|
|
|
nullptr, StatusCast<ServerMetadataHandle>(std::move(r))}; |
|
|
|
|
}, |
|
|
|
|
nullptr, |
|
|
|
|
nullptr, |
|
|
|
|
}); |
|
|
|
|
} |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
// absl::StatusOr<$VALUE_HANDLE> $INTERCEPTOR_NAME($VALUE_HANDLE, FilterType*)
|
|
|
|
|
template <typename FilterType, typename T, |
|
|
|
|
absl::StatusOr<T> (FilterType::Call::*impl)(T, FilterType*)> |
|
|
|
|
struct AddOpImpl<FilterType, T, |
|
|
|
|
absl::StatusOr<T> (FilterType::Call::*)(T, FilterType*), |
|
|
|
|
impl> { |
|
|
|
|
static void Add(FilterType* channel_data, size_t call_offset, |
|
|
|
|
Layout<FallibleOperator<T>>& to) { |
|
|
|
|
to.Add( |
|
|
|
|
0, 0, |
|
|
|
|
FallibleOperator<T>{ |
|
|
|
|
channel_data, |
|
|
|
|
call_offset, |
|
|
|
|
[](void*, void* call_data, void* channel_data, |
|
|
|
|
T value) -> Poll<ResultOr<T>> { |
|
|
|
|
auto r = |
|
|
|
|
(static_cast<typename FilterType::Call*>(call_data)->*impl)( |
|
|
|
|
std::move(value), static_cast<FilterType*>(channel_data)); |
|
|
|
|
if (IsStatusOk(r)) return ResultOr<T>{std::move(*r), nullptr}; |
|
|
|
|
return ResultOr<T>{ |
|
|
|
|
nullptr, StatusCast<ServerMetadataHandle>(std::move(r))}; |
|
|
|
|
}, |
|
|
|
|
nullptr, |
|
|
|
|
nullptr, |
|
|
|
|
}); |
|
|
|
|
} |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
// ServerMetadataHandle $INTERCEPTOR_NAME($VALUE_TYPE&)
|
|
|
|
|
template <typename FilterType, typename T, |
|
|
|
|
ServerMetadataHandle (FilterType::Call::*impl)( |
|
|
|
@ -430,6 +576,35 @@ struct AddOpImpl<FilterType, T, |
|
|
|
|
} |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
// ServerMetadataHandle $INTERCEPTOR_NAME(const $VALUE_TYPE&)
|
|
|
|
|
template <typename FilterType, typename T, |
|
|
|
|
ServerMetadataHandle (FilterType::Call::*impl)( |
|
|
|
|
const typename T::element_type&)> |
|
|
|
|
struct AddOpImpl<FilterType, T, |
|
|
|
|
ServerMetadataHandle (FilterType::Call::*)( |
|
|
|
|
const typename T::element_type&), |
|
|
|
|
impl> { |
|
|
|
|
static void Add(FilterType* channel_data, size_t call_offset, |
|
|
|
|
Layout<FallibleOperator<T>>& to) { |
|
|
|
|
to.Add( |
|
|
|
|
0, 0, |
|
|
|
|
FallibleOperator<T>{ |
|
|
|
|
channel_data, |
|
|
|
|
call_offset, |
|
|
|
|
[](void*, void* call_data, void*, T value) -> Poll<ResultOr<T>> { |
|
|
|
|
auto r = |
|
|
|
|
(static_cast<typename FilterType::Call*>(call_data)->*impl)( |
|
|
|
|
*value); |
|
|
|
|
if (r == nullptr) return ResultOr<T>{std::move(value), nullptr}; |
|
|
|
|
return ResultOr<T>{ |
|
|
|
|
nullptr, StatusCast<ServerMetadataHandle>(std::move(r))}; |
|
|
|
|
}, |
|
|
|
|
nullptr, |
|
|
|
|
nullptr, |
|
|
|
|
}); |
|
|
|
|
} |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
// ServerMetadataHandle $INTERCEPTOR_NAME($VALUE_TYPE&, FilterType*)
|
|
|
|
|
template <typename FilterType, typename T, |
|
|
|
|
ServerMetadataHandle (FilterType::Call::*impl)( |
|
|
|
@ -460,6 +635,36 @@ struct AddOpImpl<FilterType, T, |
|
|
|
|
} |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
// ServerMetadataHandle $INTERCEPTOR_NAME(const $VALUE_TYPE&, FilterType*)
|
|
|
|
|
template <typename FilterType, typename T, |
|
|
|
|
ServerMetadataHandle (FilterType::Call::*impl)( |
|
|
|
|
const typename T::element_type&, FilterType*)> |
|
|
|
|
struct AddOpImpl<FilterType, T, |
|
|
|
|
ServerMetadataHandle (FilterType::Call::*)( |
|
|
|
|
const typename T::element_type&, FilterType*), |
|
|
|
|
impl> { |
|
|
|
|
static void Add(FilterType* channel_data, size_t call_offset, |
|
|
|
|
Layout<FallibleOperator<T>>& to) { |
|
|
|
|
to.Add( |
|
|
|
|
0, 0, |
|
|
|
|
FallibleOperator<T>{ |
|
|
|
|
channel_data, |
|
|
|
|
call_offset, |
|
|
|
|
[](void*, void* call_data, void* channel_data, |
|
|
|
|
T value) -> Poll<ResultOr<T>> { |
|
|
|
|
auto r = |
|
|
|
|
(static_cast<typename FilterType::Call*>(call_data)->*impl)( |
|
|
|
|
*value, static_cast<FilterType*>(channel_data)); |
|
|
|
|
if (r == nullptr) return ResultOr<T>{std::move(value), nullptr}; |
|
|
|
|
return ResultOr<T>{ |
|
|
|
|
nullptr, StatusCast<ServerMetadataHandle>(std::move(r))}; |
|
|
|
|
}, |
|
|
|
|
nullptr, |
|
|
|
|
nullptr, |
|
|
|
|
}); |
|
|
|
|
} |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
// PROMISE_RETURNING(absl::Status) $INTERCEPTOR_NAME($VALUE_TYPE&)
|
|
|
|
|
template <typename FilterType, typename T, typename R, |
|
|
|
|
R (FilterType::Call::*impl)(typename T::element_type&)> |
|
|
|
@ -565,6 +770,11 @@ struct AddOpImpl< |
|
|
|
|
} |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
struct ChannelDataDestructor { |
|
|
|
|
void (*destroy)(void* channel_data); |
|
|
|
|
void* channel_data; |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
// StackData contains the main datastructures built up by this module.
|
|
|
|
|
// It's a complete representation of all the code that needs to be invoked
|
|
|
|
|
// to execute a call for a given set of filters.
|
|
|
|
@ -590,6 +800,9 @@ struct StackData { |
|
|
|
|
// We use a bespoke data structure here because finalizers can never be
|
|
|
|
|
// asynchronous.
|
|
|
|
|
std::vector<Finalizer> finalizers; |
|
|
|
|
// A list of functions to call when this stack data is destroyed
|
|
|
|
|
// (to capture ownership of channel data)
|
|
|
|
|
std::vector<ChannelDataDestructor> channel_data_destructors; |
|
|
|
|
|
|
|
|
|
// Add one filter to the list of filters, and update alignment.
|
|
|
|
|
// Returns the offset of the call data for this filter.
|
|
|
|
@ -721,7 +934,7 @@ struct StackData { |
|
|
|
|
|
|
|
|
|
template <typename FilterType> |
|
|
|
|
void AddFinalizer(FilterType*, size_t, const NoInterceptor* p) { |
|
|
|
|
GPR_DEBUG_ASSERT(p == &FilterType::OnFinalize); |
|
|
|
|
GPR_DEBUG_ASSERT(p == &FilterType::Call::OnFinalize); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
template <typename FilterType> |
|
|
|
@ -938,6 +1151,9 @@ class CallFilters { |
|
|
|
|
// It contains pointers to the individual filters, yet it does not own those
|
|
|
|
|
// pointers: it's expected that some other object will track that ownership.
|
|
|
|
|
class Stack : public RefCounted<Stack> { |
|
|
|
|
public: |
|
|
|
|
~Stack() override; |
|
|
|
|
|
|
|
|
|
private: |
|
|
|
|
friend class CallFilters; |
|
|
|
|
friend class StackBuilder; |
|
|
|
@ -949,6 +1165,8 @@ class CallFilters { |
|
|
|
|
// the stack, then call Build() to generate a ref counted Stack object.
|
|
|
|
|
class StackBuilder { |
|
|
|
|
public: |
|
|
|
|
~StackBuilder(); |
|
|
|
|
|
|
|
|
|
template <typename FilterType> |
|
|
|
|
void Add(FilterType* filter) { |
|
|
|
|
const size_t call_offset = data_.AddFilter<FilterType>(filter); |
|
|
|
@ -960,6 +1178,15 @@ class CallFilters { |
|
|
|
|
data_.AddFinalizer(filter, call_offset, &FilterType::Call::OnFinalize); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void AddOwnedObject(void (*destroy)(void* p), void* p) { |
|
|
|
|
data_.channel_data_destructors.push_back({destroy, p}); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
template <typename T> |
|
|
|
|
void AddOwnedObject(RefCountedPtr<T> p) { |
|
|
|
|
AddOwnedObject([](void* p) { static_cast<T*>(p)->Unref(); }, p.release()); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
RefCountedPtr<Stack> Build(); |
|
|
|
|
|
|
|
|
|
private: |
|
|
|
|