[core] Ensure ChannelArgs::SetObject only allows conforming shared_ptr<T> classes (#35008)
ChannelArgs shared_ptr only supports types that extend `enable_shared_from_this`. `args.SetObject<shared_ptr<X>>(x)` with a non-comforming type X will now fail with something like:
```
./src/core/lib/channel/channel_args.h:453:12: error: no matching member function for call to 'Set'
return Set(ChannelArgNameTraits<T>::ChannelArgName(), std::move(p));
^~~
test/core/channel/channel_args_test.cc:352:32: note: in instantiation of function template specialization 'grpc_core::ChannelArgs::SetObject<X>' requested here
grpc_core::ChannelArgs b = a.SetObject(x);
^
..
```
Closes #35008
COPYBARA_INTEGRATE_REVIEW=https://github.com/grpc/grpc/pull/35008 from drfloob:channel-args-cant-set-unsupported-shared-ptr-type dc93f27ac7
PiperOrigin-RevId: 586766674
This commit is contained in:
parent
f9e56a9467
commit
be4d2a6d8b
|
|
@ -125,6 +125,16 @@ struct ChannelArgTypeTraits<
|
|||
};
|
||||
};
|
||||
|
||||
// Define a check for shared_ptr supported types, which must extend
|
||||
// enable_shared_from_this.
|
||||
template <typename T>
|
||||
struct SupportedSharedPtrType
|
||||
: std::integral_constant<
|
||||
bool, std::is_base_of<std::enable_shared_from_this<T>, T>::value> {};
|
||||
template <>
|
||||
struct SupportedSharedPtrType<grpc_event_engine::experimental::EventEngine>
|
||||
: std::true_type {};
|
||||
|
||||
// Specialization for shared_ptr
|
||||
// Incurs an allocation because shared_ptr.release is not a thing.
|
||||
template <typename T>
|
||||
|
|
@ -174,18 +184,12 @@ struct ChannelArgTypeTraits<T,
|
|||
};
|
||||
|
||||
// GetObject support for shared_ptr and RefCountedPtr
|
||||
template <typename T>
|
||||
struct WrapInSharedPtr
|
||||
: std::integral_constant<
|
||||
bool, std::is_base_of<std::enable_shared_from_this<T>, T>::value> {};
|
||||
template <>
|
||||
struct WrapInSharedPtr<grpc_event_engine::experimental::EventEngine>
|
||||
: std::true_type {};
|
||||
template <typename T, typename Ignored = void /* for SFINAE */>
|
||||
struct GetObjectImpl;
|
||||
// std::shared_ptr implementation
|
||||
template <typename T>
|
||||
struct GetObjectImpl<T, absl::enable_if_t<WrapInSharedPtr<T>::value, void>> {
|
||||
struct GetObjectImpl<
|
||||
T, absl::enable_if_t<SupportedSharedPtrType<T>::value, void>> {
|
||||
using Result = T*;
|
||||
using ReffedResult = std::shared_ptr<T>;
|
||||
using StoredType = std::shared_ptr<T>*;
|
||||
|
|
@ -205,7 +209,8 @@ struct GetObjectImpl<T, absl::enable_if_t<WrapInSharedPtr<T>::value, void>> {
|
|||
};
|
||||
// RefCountedPtr
|
||||
template <typename T>
|
||||
struct GetObjectImpl<T, absl::enable_if_t<!WrapInSharedPtr<T>::value, void>> {
|
||||
struct GetObjectImpl<
|
||||
T, absl::enable_if_t<!SupportedSharedPtrType<T>::value, void>> {
|
||||
using Result = T*;
|
||||
using ReffedResult = RefCountedPtr<T>;
|
||||
using StoredType = Result;
|
||||
|
|
@ -391,6 +396,9 @@ class ChannelArgs {
|
|||
decltype(ChannelArgTypeTraits<std::shared_ptr<T>>::VTable())>::value,
|
||||
ChannelArgs>
|
||||
Set(absl::string_view name, std::shared_ptr<T> value) const {
|
||||
static_assert(SupportedSharedPtrType<T>::value,
|
||||
"Type T must extend std::enable_shared_from_this to be added "
|
||||
"into ChannelArgs as a shared_ptr<T>");
|
||||
auto* store_value = new std::shared_ptr<T>(value);
|
||||
return Set(
|
||||
name,
|
||||
|
|
|
|||
|
|
@ -48,7 +48,9 @@ namespace experimental {
|
|||
|
||||
// EventEngine implementation to be used by fuzzers.
|
||||
// It's only allowed to have one FuzzingEventEngine instantiated at a time.
|
||||
class FuzzingEventEngine : public EventEngine {
|
||||
class FuzzingEventEngine
|
||||
: public EventEngine,
|
||||
public std::enable_shared_from_this<FuzzingEventEngine> {
|
||||
public:
|
||||
struct Options {
|
||||
Duration max_delay_run_after = std::chrono::seconds(30);
|
||||
|
|
|
|||
|
|
@ -71,7 +71,8 @@ absl::Status ErrorToAbslStatus(
|
|||
}
|
||||
|
||||
class FuzzingResolverEventEngine
|
||||
: public grpc_event_engine::experimental::AbortingEventEngine {
|
||||
: public grpc_event_engine::experimental::AbortingEventEngine,
|
||||
public std::enable_shared_from_this<FuzzingResolverEventEngine> {
|
||||
public:
|
||||
explicit FuzzingResolverEventEngine(
|
||||
const event_engine_client_channel_resolver::Msg& msg,
|
||||
|
|
|
|||
Loading…
Reference in New Issue