diff --git a/src/node_threadsafe_cow.h b/src/node_threadsafe_cow.h index 8cfdd006b12f..4d823b23f59d 100644 --- a/src/node_threadsafe_cow.h +++ b/src/node_threadsafe_cow.h @@ -6,7 +6,9 @@ #include "util.h" #include "uv.h" -#include // std::shared_ptr +#include +#include // std::shared_ptr +#include #include // std::forward namespace node { @@ -17,6 +19,8 @@ template class CopyOnWrite final { public: template + requires(!(sizeof...(Args) == 1 && + (std::same_as> || ...))) explicit CopyOnWrite(Args&&... args) : data_(std::make_shared(std::forward(args)...)) {} @@ -57,6 +61,10 @@ class ThreadsafeCopyOnWrite final { public: template + requires( + !(sizeof...(Args) == 1 && + (std::same_as> || + ...))) ThreadsafeCopyOnWrite(Args&&... args) : impl_(T(std::forward(args)...)) {} diff --git a/test/cctest/test_per_process.cc b/test/cctest/test_per_process.cc index 7a6f53d56222..dce250e18f8d 100644 --- a/test/cctest/test_per_process.cc +++ b/test/cctest/test_per_process.cc @@ -6,6 +6,8 @@ #include +using node::CopyOnWrite; +using node::ThreadsafeCopyOnWrite; using node::builtins::BuiltinLoader; using node::builtins::BuiltinSourceMap; @@ -18,6 +20,26 @@ class PerProcessTest : public ::testing::Test { namespace { +TEST(CopyOnWriteTest, CopiesFromNonConstLvalue) { + CopyOnWrite original(42); + CopyOnWrite copy(original); + + *copy.write() = 43; + + EXPECT_EQ(*original, 42); + EXPECT_EQ(*copy, 43); +} + +TEST(ThreadsafeCopyOnWriteTest, CopiesFromNonConstLvalue) { + ThreadsafeCopyOnWrite original(42); + ThreadsafeCopyOnWrite copy(original); + + *copy.write() = 43; + + EXPECT_EQ(*original.read(), 42); + EXPECT_EQ(*copy.read(), 43); +} + TEST_F(PerProcessTest, EmbeddedSources) { const auto& sources = PerProcessTest::get_sources_for_test(); ASSERT_TRUE(std::any_of(sources.cbegin(), sources.cend(), [](auto p) {