|
|
|
@ -20,6 +20,8 @@ |
|
|
|
|
#include <atomic> |
|
|
|
|
#include <functional> |
|
|
|
|
|
|
|
|
|
#include <grpc/support/log.h> |
|
|
|
|
|
|
|
|
|
#include "src/core/lib/channel/channel_args_preconditioning.h" |
|
|
|
|
#include "src/core/lib/resolver/resolver_registry.h" |
|
|
|
|
#include "src/core/lib/security/credentials/channel_creds_registry.h" |
|
|
|
@ -76,6 +78,50 @@ class CoreConfiguration { |
|
|
|
|
CoreConfiguration* Build(); |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
// Stores a builder for RegisterBuilder
|
|
|
|
|
struct RegisteredBuilder { |
|
|
|
|
std::function<void(Builder*)> builder; |
|
|
|
|
RegisteredBuilder* next; |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
// Temporarily replaces core configuration with what is built from the
|
|
|
|
|
// provided BuildFunc that takes (Builder*) and returns void.
|
|
|
|
|
// Requires no concurrent Get() be called. Restores current core
|
|
|
|
|
// configuration when this object is destroyed. The default builder
|
|
|
|
|
// is not backed up or restored.
|
|
|
|
|
//
|
|
|
|
|
// Useful for running multiple tests back to back in the same process
|
|
|
|
|
// without side effects from previous tests.
|
|
|
|
|
class WithSubstituteBuilder { |
|
|
|
|
public: |
|
|
|
|
template <typename BuildFunc> |
|
|
|
|
explicit WithSubstituteBuilder(BuildFunc build) { |
|
|
|
|
// Build core configuration to replace.
|
|
|
|
|
Builder builder; |
|
|
|
|
build(&builder); |
|
|
|
|
CoreConfiguration* p = builder.Build(); |
|
|
|
|
|
|
|
|
|
// Backup current core configuration and replace/reset.
|
|
|
|
|
config_restore_ = |
|
|
|
|
CoreConfiguration::config_.exchange(p, std::memory_order_acquire); |
|
|
|
|
builders_restore_ = CoreConfiguration::builders_.exchange( |
|
|
|
|
nullptr, std::memory_order_acquire); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
~WithSubstituteBuilder() { |
|
|
|
|
// Reset and restore.
|
|
|
|
|
Reset(); |
|
|
|
|
GPR_ASSERT(CoreConfiguration::config_.exchange( |
|
|
|
|
config_restore_, std::memory_order_acquire) == nullptr); |
|
|
|
|
GPR_ASSERT(CoreConfiguration::builders_.exchange( |
|
|
|
|
builders_restore_, std::memory_order_acquire) == nullptr); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private: |
|
|
|
|
CoreConfiguration* config_restore_; |
|
|
|
|
RegisteredBuilder* builders_restore_; |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
// Lifetime methods
|
|
|
|
|
|
|
|
|
|
// Get the core configuration; if it does not exist, create it.
|
|
|
|
@ -87,36 +133,11 @@ class CoreConfiguration { |
|
|
|
|
return BuildNewAndMaybeSet(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Build a special core configuration.
|
|
|
|
|
// Requires no concurrent Get() be called.
|
|
|
|
|
// Doesn't call the regular BuildCoreConfiguration function, instead calls
|
|
|
|
|
// `build`.
|
|
|
|
|
// BuildFunc is a callable that takes a Builder* and returns void.
|
|
|
|
|
// We use a template instead of std::function<void(Builder*)> to avoid
|
|
|
|
|
// including std::function in this widely used header, and to ensure no code
|
|
|
|
|
// is generated in programs that do not use this function.
|
|
|
|
|
// This is sometimes useful for testing.
|
|
|
|
|
template <typename BuildFunc> |
|
|
|
|
static void BuildSpecialConfiguration(BuildFunc build) { |
|
|
|
|
// Build bespoke configuration
|
|
|
|
|
Builder builder; |
|
|
|
|
build(&builder); |
|
|
|
|
CoreConfiguration* p = builder.Build(); |
|
|
|
|
// Swap in final configuration, deleting anything that was already present.
|
|
|
|
|
delete config_.exchange(p, std::memory_order_release); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Attach a registration function globally.
|
|
|
|
|
// Each registration function is called *in addition to*
|
|
|
|
|
// BuildCoreConfiguration for the default core configuration. When using
|
|
|
|
|
// BuildSpecialConfiguration, one can use CallRegisteredBuilders to call them.
|
|
|
|
|
// Must be called before a configuration is built.
|
|
|
|
|
// BuildCoreConfiguration for the default core configuration.
|
|
|
|
|
static void RegisterBuilder(std::function<void(Builder*)> builder); |
|
|
|
|
|
|
|
|
|
// Call all registered builders.
|
|
|
|
|
// See RegisterBuilder for why you might want to call this.
|
|
|
|
|
static void CallRegisteredBuilders(Builder* builder); |
|
|
|
|
|
|
|
|
|
// Drop the core configuration. Users must ensure no other threads are
|
|
|
|
|
// accessing the configuration.
|
|
|
|
|
// Clears any dynamically registered builders.
|
|
|
|
@ -128,10 +149,8 @@ class CoreConfiguration { |
|
|
|
|
template <typename BuildFunc, typename RunFunc> |
|
|
|
|
static void RunWithSpecialConfiguration(BuildFunc build_configuration, |
|
|
|
|
RunFunc code_to_run) { |
|
|
|
|
Reset(); |
|
|
|
|
BuildSpecialConfiguration(build_configuration); |
|
|
|
|
WithSubstituteBuilder builder(build_configuration); |
|
|
|
|
code_to_run(); |
|
|
|
|
Reset(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Accessors
|
|
|
|
@ -165,12 +184,6 @@ class CoreConfiguration { |
|
|
|
|
private: |
|
|
|
|
explicit CoreConfiguration(Builder* builder); |
|
|
|
|
|
|
|
|
|
// Stores a builder for RegisterBuilder
|
|
|
|
|
struct RegisteredBuilder { |
|
|
|
|
std::function<void(Builder*)> builder; |
|
|
|
|
RegisteredBuilder* next; |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
// Create a new CoreConfiguration, and either set it or throw it away.
|
|
|
|
|
// We allow multiple CoreConfiguration's to be created in parallel.
|
|
|
|
|
static const CoreConfiguration& BuildNewAndMaybeSet(); |
|
|
|
|