From 9fbf0c60b583dae3d34598352c3c7614118cd035 Mon Sep 17 00:00:00 2001 From: Anna Henningsen Date: Fri, 22 Feb 2019 20:11:19 +0100 Subject: worker: use copy of process.env MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Instead of sharing the OS-backed store for all `process.env` instances, create a copy of `process.env` for every worker that is created. The copies do not interact. Native-addons do not see modifications to `process.env` from Worker threads, but child processes started from Workers do default to the Worker’s copy of `process.env`. This makes Workers behave like child processes as far as `process.env` is concerned, and an option corresponding to the `child_process` module’s `env` option is added to the constructor. Fixes: https://github.com/nodejs/node/issues/24947 PR-URL: https://github.com/nodejs/node/pull/26544 Reviewed-By: Ruben Bridgewater Reviewed-By: Vse Mozhet Byt Reviewed-By: Yongsheng Zhang Reviewed-By: James M Snell Reviewed-By: Benjamin Gruenbaum Reviewed-By: Joyee Cheung --- src/node_env_var.cc | 49 ++++++++++++++++++++++++------------------------- 1 file changed, 24 insertions(+), 25 deletions(-) (limited to 'src/node_env_var.cc') diff --git a/src/node_env_var.cc b/src/node_env_var.cc index 2df7275b17..b7b862304d 100644 --- a/src/node_env_var.cc +++ b/src/node_env_var.cc @@ -40,7 +40,7 @@ class RealEnvStore final : public KVStore { Local Enumerate(Isolate* isolate) const override; }; -class GenericKVStore final : public KVStore { +class MapKVStore final : public KVStore { public: Local Get(Isolate* isolate, Local key) const override; void Set(Isolate* isolate, Local key, Local value) override; @@ -50,8 +50,8 @@ class GenericKVStore final : public KVStore { std::shared_ptr Clone(Isolate* isolate) const override; - GenericKVStore() {} - GenericKVStore(const GenericKVStore& other) : map_(other.map_) {} + MapKVStore() {} + MapKVStore(const MapKVStore& other) : map_(other.map_) {} private: mutable Mutex mutex_; @@ -60,7 +60,7 @@ class GenericKVStore final : public KVStore { namespace per_process { Mutex env_var_mutex; -std::shared_ptr real_environment = std::make_shared(); +std::shared_ptr system_environment = std::make_shared(); } // namespace per_process Local RealEnvStore::Get(Isolate* isolate, @@ -207,7 +207,7 @@ std::shared_ptr KVStore::Clone(v8::Isolate* isolate) const { HandleScope handle_scope(isolate); Local context = isolate->GetCurrentContext(); - std::shared_ptr copy = KVStore::CreateGenericKVStore(); + std::shared_ptr copy = KVStore::CreateMapKVStore(); Local keys = Enumerate(isolate); uint32_t keys_length = keys->Length(); for (uint32_t i = 0; i < keys_length; i++) { @@ -218,9 +218,9 @@ std::shared_ptr KVStore::Clone(v8::Isolate* isolate) const { return copy; } -Local GenericKVStore::Get(Isolate* isolate, Local key) const { +Local MapKVStore::Get(Isolate* isolate, Local key) const { Mutex::ScopedLock lock(mutex_); - String::Utf8Value str(isolate, key); + Utf8Value str(isolate, key); auto it = map_.find(std::string(*str, str.length())); if (it == map_.end()) return Local(); return String::NewFromUtf8(isolate, it->second.data(), @@ -228,31 +228,30 @@ Local GenericKVStore::Get(Isolate* isolate, Local key) const { .ToLocalChecked(); } -void GenericKVStore::Set(Isolate* isolate, Local key, - Local value) { +void MapKVStore::Set(Isolate* isolate, Local key, Local value) { Mutex::ScopedLock lock(mutex_); - String::Utf8Value key_str(isolate, key); - String::Utf8Value value_str(isolate, value); + Utf8Value key_str(isolate, key); + Utf8Value value_str(isolate, value); if (*key_str != nullptr && *value_str != nullptr) { map_[std::string(*key_str, key_str.length())] = std::string(*value_str, value_str.length()); } } -int32_t GenericKVStore::Query(Isolate* isolate, Local key) const { +int32_t MapKVStore::Query(Isolate* isolate, Local key) const { Mutex::ScopedLock lock(mutex_); - String::Utf8Value str(isolate, key); + Utf8Value str(isolate, key); auto it = map_.find(std::string(*str, str.length())); return it == map_.end() ? -1 : 0; } -void GenericKVStore::Delete(Isolate* isolate, Local key) { +void MapKVStore::Delete(Isolate* isolate, Local key) { Mutex::ScopedLock lock(mutex_); - String::Utf8Value str(isolate, key); + Utf8Value str(isolate, key); map_.erase(std::string(*str, str.length())); } -Local GenericKVStore::Enumerate(Isolate* isolate) const { +Local MapKVStore::Enumerate(Isolate* isolate) const { Mutex::ScopedLock lock(mutex_); std::vector> values; values.reserve(map_.size()); @@ -265,12 +264,12 @@ Local GenericKVStore::Enumerate(Isolate* isolate) const { return Array::New(isolate, values.data(), values.size()); } -std::shared_ptr GenericKVStore::Clone(Isolate* isolate) const { - return std::make_shared(*this); +std::shared_ptr MapKVStore::Clone(Isolate* isolate) const { + return std::make_shared(*this); } -std::shared_ptr KVStore::CreateGenericKVStore() { - return std::make_shared(); +std::shared_ptr KVStore::CreateMapKVStore() { + return std::make_shared(); } Maybe KVStore::AssignFromObject(Local context, @@ -307,7 +306,7 @@ static void EnvGetter(Local property, } CHECK(property->IsString()); info.GetReturnValue().Set( - env->envvars()->Get(env->isolate(), property.As())); + env->env_vars()->Get(env->isolate(), property.As())); } static void EnvSetter(Local property, @@ -338,7 +337,7 @@ static void EnvSetter(Local property, return; } - env->envvars()->Set(env->isolate(), key, value_string); + env->env_vars()->Set(env->isolate(), key, value_string); // Whether it worked or not, always return value. info.GetReturnValue().Set(value); @@ -348,7 +347,7 @@ static void EnvQuery(Local property, const PropertyCallbackInfo& info) { Environment* env = Environment::GetCurrent(info); if (property->IsString()) { - int32_t rc = env->envvars()->Query(env->isolate(), property.As()); + int32_t rc = env->env_vars()->Query(env->isolate(), property.As()); if (rc != -1) info.GetReturnValue().Set(rc); } } @@ -357,7 +356,7 @@ static void EnvDeleter(Local property, const PropertyCallbackInfo& info) { Environment* env = Environment::GetCurrent(info); if (property->IsString()) { - env->envvars()->Delete(env->isolate(), property.As()); + env->env_vars()->Delete(env->isolate(), property.As()); } // process.env never has non-configurable properties, so always @@ -369,7 +368,7 @@ static void EnvEnumerator(const PropertyCallbackInfo& info) { Environment* env = Environment::GetCurrent(info); info.GetReturnValue().Set( - env->envvars()->Enumerate(env->isolate())); + env->env_vars()->Enumerate(env->isolate())); } MaybeLocal CreateEnvVarProxy(Local context, -- cgit v1.2.3