1
1
Fork 0
mirror of https://github.com/NixOS/nix.git synced 2025-11-09 12:06:01 +01:00

Merge branch 'master' into eval-copy-less

This commit is contained in:
John Ericson 2025-10-13 11:52:42 -04:00 committed by GitHub
commit d2c0c0607c
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 72 additions and 42 deletions

View file

@ -508,8 +508,15 @@ private:
public: public:
/**
* @param lookupPath Only used during construction.
* @param store The store to use for instantiation
* @param fetchSettings Must outlive the lifetime of this EvalState!
* @param settings Must outlive the lifetime of this EvalState!
* @param buildStore The store to use for builds ("import from derivation", C API `nix_string_realise`)
*/
EvalState( EvalState(
const LookupPath & _lookupPath, const LookupPath & lookupPath,
ref<Store> store, ref<Store> store,
const fetchers::Settings & fetchSettings, const fetchers::Settings & fetchSettings,
const EvalSettings & settings, const EvalSettings & settings,

View file

@ -118,48 +118,57 @@ AwsCredentials getAwsCredentials(const std::string & profile)
// Get or create credential provider with caching // Get or create credential provider with caching
std::shared_ptr<Aws::Crt::Auth::ICredentialsProvider> provider; std::shared_ptr<Aws::Crt::Auth::ICredentialsProvider> provider;
// Try to find existing provider // Use try_emplace_and_cvisit for atomic get-or-create
credentialProviderCache.visit(profile, [&](const auto & pair) { provider = pair.second; }); // This prevents race conditions where multiple threads create providers
credentialProviderCache.try_emplace_and_cvisit(
profile,
nullptr, // Placeholder - will be replaced in f1 before any thread can see it
[&](auto & kv) {
// f1: Called atomically during insertion with non-const reference
// Other threads are blocked until we finish, so nullptr is never visible
debug(
"[pid=%d] creating new AWS credential provider for profile '%s'",
getpid(),
profile.empty() ? "(default)" : profile.c_str());
if (!provider) { try {
// Create new provider if not found initAwsCrt();
debug(
"[pid=%d] creating new AWS credential provider for profile '%s'",
getpid(),
profile.empty() ? "(default)" : profile.c_str());
try { if (profile.empty()) {
initAwsCrt(); Aws::Crt::Auth::CredentialsProviderChainDefaultConfig config;
config.Bootstrap = Aws::Crt::ApiHandle::GetOrCreateStaticDefaultClientBootstrap();
kv.second = Aws::Crt::Auth::CredentialsProvider::CreateCredentialsProviderChainDefault(config);
} else {
Aws::Crt::Auth::CredentialsProviderProfileConfig config;
config.Bootstrap = Aws::Crt::ApiHandle::GetOrCreateStaticDefaultClientBootstrap();
// This is safe because the underlying C library will copy this string
// c.f. https://github.com/awslabs/aws-c-auth/blob/main/source/credentials_provider_profile.c#L220
config.ProfileNameOverride = Aws::Crt::ByteCursorFromCString(profile.c_str());
kv.second = Aws::Crt::Auth::CredentialsProvider::CreateCredentialsProviderProfile(config);
}
if (profile.empty()) { if (!kv.second) {
Aws::Crt::Auth::CredentialsProviderChainDefaultConfig config; throw AwsAuthError(
config.Bootstrap = Aws::Crt::ApiHandle::GetOrCreateStaticDefaultClientBootstrap(); "Failed to create AWS credentials provider for %s",
provider = Aws::Crt::Auth::CredentialsProvider::CreateCredentialsProviderChainDefault(config); profile.empty() ? "default profile" : fmt("profile '%s'", profile));
} else { }
Aws::Crt::Auth::CredentialsProviderProfileConfig config;
config.Bootstrap = Aws::Crt::ApiHandle::GetOrCreateStaticDefaultClientBootstrap(); provider = kv.second;
// This is safe because the underlying C library will copy this string } catch (Error & e) {
// c.f. https://github.com/awslabs/aws-c-auth/blob/main/source/credentials_provider_profile.c#L220 // Exception during creation - remove the entry to allow retry
config.ProfileNameOverride = Aws::Crt::ByteCursorFromCString(profile.c_str()); credentialProviderCache.erase(profile);
provider = Aws::Crt::Auth::CredentialsProvider::CreateCredentialsProviderProfile(config); e.addTrace({}, "for AWS profile: %s", profile.empty() ? "(default)" : profile);
throw;
} catch (...) {
// Non-Error exception - still need to clean up
credentialProviderCache.erase(profile);
throw;
} }
} catch (Error & e) { },
e.addTrace( [&](const auto & kv) {
{}, // f2: Called if key already exists (const reference)
"while creating AWS credentials provider for %s", provider = kv.second;
profile.empty() ? "default profile" : fmt("profile '%s'", profile)); });
throw;
}
if (!provider) {
throw AwsAuthError(
"Failed to create AWS credentials provider for %s",
profile.empty() ? "default profile" : fmt("profile '%s'", profile));
}
// Insert into cache (try_emplace is thread-safe and won't overwrite if another thread added it)
credentialProviderCache.try_emplace(profile, provider);
}
return getCredentialsFromProvider(provider); return getCredentialsFromProvider(provider);
} }

View file

@ -192,13 +192,27 @@ public:
err.traces.push_front(trace); err.traces.push_front(trace);
} }
/**
* Prepends an item to the error trace, as is usual for extra context.
*
* @param pos Nullable source position to put in trace item
* @param fs Format string, see `HintFmt`
* @param args... Format string arguments.
*/
template<typename... Args> template<typename... Args>
void addTrace(std::shared_ptr<const Pos> && e, std::string_view fs, const Args &... args) void addTrace(std::shared_ptr<const Pos> && pos, std::string_view fs, const Args &... args)
{ {
addTrace(std::move(e), HintFmt(std::string(fs), args...)); addTrace(std::move(pos), HintFmt(std::string(fs), args...));
} }
void addTrace(std::shared_ptr<const Pos> && e, HintFmt hint, TracePrint print = TracePrint::Default); /**
* Prepends an item to the error trace, as is usual for extra context.
*
* @param pos Nullable source position to put in trace item
* @param hint Formatted error message
* @param print Optional, whether to always print (used by `addErrorContext`)
*/
void addTrace(std::shared_ptr<const Pos> && pos, HintFmt hint, TracePrint print = TracePrint::Default);
bool hasTrace() const bool hasTrace() const
{ {