fix: replace unsafe env::set_var with thread-safe OnceLock

Resolves intermittent STATUS_HEAP_CORRUPTION on Windows by using a static OnceLock map instead of mutating the global OS environment block.
This commit is contained in:
Riz Ashraf committed 2026-10-11 06:56:24 +01:00
1 parent 3533c243d2
commit ffb316a6e3
12 files changed
+235 -52

No files matched your search

+30 -27
View File
@@ -1,43 +1,46 @@
use std::sync::OnceLock;
use serde_json::Value;
use std::collections::HashMap;
use std::env;
use std::fs;
use std::path::PathBuf;
use tracing::info;
pub static CONFIG_ENV: OnceLock<HashMap<String, String>> = OnceLock::new();
pub fn load_mcp_config_env() {
let mut map = HashMap::new();
let config_path = dirs::home_dir()
.unwrap_or_else(|| PathBuf::from("."))
.join(".gemini/config/mcp_config.json");
if !config_path.exists() {
return;
}
let config_str = match fs::read_to_string(&config_path) {
Ok(s) => s,
Err(_) => return,
};
let parsed: Value = match serde_json::from_str(&config_str) {
Ok(v) => v,
Err(_) => return,
};
if let Some(env_obj) = parsed
.get("mcpServers")
.and_then(|v| v.get("mcp-memory"))
.and_then(|v| v.get("env"))
.and_then(|v| v.as_object())
{
for (key, val) in env_obj {
if let Some(val_str) = val.as_str()
&& env::var(key).is_err()
{
unsafe {
env::set_var(key, val_str);
if config_path.exists() {
if let Ok(config_str) = fs::read_to_string(&config_path) {
if let Ok(parsed) = serde_json::from_str::<Value>(&config_str) {
if let Some(env_obj) = parsed
.get("mcpServers")
.and_then(|v| v.get("mcp-memory"))
.and_then(|v| v.get("env"))
.and_then(|v| v.as_object())
{
for (key, val) in env_obj {
if let Some(val_str) = val.as_str() {
map.insert(key.clone(), val_str.to_string());
info!("Loaded env var {} from mcp_config.json", key);
}
}
}
info!("Loaded env var {} from mcp_config.json", key);
}
}
}
let _ = CONFIG_ENV.set(map);
}
pub fn get_env(key: &str) -> Result<String, env::VarError> {
if let Some(map) = CONFIG_ENV.get() {
if let Some(val) = map.get(key) {
return Ok(val.clone());
}
}
env::var(key)
}