diff --git a/lib/base/array.cpp b/lib/base/array.cpp index 73adcb279..fe95f5d88 100644 --- a/lib/base/array.cpp +++ b/lib/base/array.cpp @@ -96,7 +96,7 @@ void Array::Add(Value value) */ Array::Iterator Array::Begin() { - ASSERT(OwnsLock()); + ASSERT(Frozen() || OwnsLock()); return m_Data.begin(); } @@ -110,7 +110,7 @@ Array::Iterator Array::Begin() */ Array::Iterator Array::End() { - ASSERT(OwnsLock()); + ASSERT(Frozen() || OwnsLock()); return m_Data.end(); } @@ -327,7 +327,12 @@ Array::Ptr Array::Unique() const void Array::Freeze() { ObjectLock olock(this); - m_Frozen = true; + m_Frozen.store(true, std::memory_order_release); +} + +bool Array::Frozen() const +{ + return m_Frozen.load(std::memory_order_acquire); } Value Array::GetFieldByName(const String& field, bool sandboxed, const DebugInfo& debugInfo) const diff --git a/lib/base/array.hpp b/lib/base/array.hpp index 9589d1901..fb8257c17 100644 --- a/lib/base/array.hpp +++ b/lib/base/array.hpp @@ -4,6 +4,7 @@ #define ARRAY_H #include "base/i2-base.hpp" +#include "base/atomic.hpp" #include "base/objectlock.hpp" #include "base/value.hpp" #include @@ -98,13 +99,14 @@ public: Array::Ptr Unique() const; void Freeze(); + bool Frozen() const; Value GetFieldByName(const String& field, bool sandboxed, const DebugInfo& debugInfo) const override; void SetFieldByName(const String& field, const Value& value, const DebugInfo& debugInfo) override; private: std::vector m_Data; /**< The data for the array. */ - bool m_Frozen{false}; + Atomic m_Frozen{false}; }; Array::Iterator begin(const Array::Ptr& x); diff --git a/lib/base/dictionary.cpp b/lib/base/dictionary.cpp index 89b6c4cbc..c45bee3d8 100644 --- a/lib/base/dictionary.cpp +++ b/lib/base/dictionary.cpp @@ -132,7 +132,7 @@ bool Dictionary::Contains(const String& key) const */ Dictionary::Iterator Dictionary::Begin() { - ASSERT(OwnsLock()); + ASSERT(Frozen() || OwnsLock()); return m_Data.begin(); } @@ -146,7 +146,7 @@ Dictionary::Iterator Dictionary::Begin() */ Dictionary::Iterator Dictionary::End() { - ASSERT(OwnsLock()); + ASSERT(Frozen() || OwnsLock()); return m_Data.end(); } @@ -276,7 +276,12 @@ String Dictionary::ToString() const void Dictionary::Freeze() { ObjectLock olock(this); - m_Frozen = true; + m_Frozen.store(true, std::memory_order_release); +} + +bool Dictionary::Frozen() const +{ + return m_Frozen.load(std::memory_order_acquire); } Value Dictionary::GetFieldByName(const String& field, bool, const DebugInfo& debugInfo) const diff --git a/lib/base/dictionary.hpp b/lib/base/dictionary.hpp index ba2fbe82c..f95bcc699 100644 --- a/lib/base/dictionary.hpp +++ b/lib/base/dictionary.hpp @@ -4,6 +4,7 @@ #define DICTIONARY_H #include "base/i2-base.hpp" +#include "base/atomic.hpp" #include "base/object.hpp" #include "base/value.hpp" #include @@ -69,6 +70,7 @@ public: String ToString() const override; void Freeze(); + bool Frozen() const; Value GetFieldByName(const String& field, bool sandboxed, const DebugInfo& debugInfo) const override; void SetFieldByName(const String& field, const Value& value, const DebugInfo& debugInfo) override; @@ -78,7 +80,7 @@ public: private: std::map m_Data; /**< The data for the dictionary. */ mutable std::shared_timed_mutex m_DataMutex; - bool m_Frozen{false}; + Atomic m_Frozen{false}; }; Dictionary::Iterator begin(const Dictionary::Ptr& x); diff --git a/lib/base/namespace.cpp b/lib/base/namespace.cpp index 1f53efc92..85ed7fa1d 100644 --- a/lib/base/namespace.cpp +++ b/lib/base/namespace.cpp @@ -119,7 +119,12 @@ void Namespace::Remove(const String& field) void Namespace::Freeze() { ObjectLock olock(this); - m_Frozen = true; + m_Frozen.store(true, std::memory_order_release); +} + +bool Namespace::Frozen() const +{ + return m_Frozen.load(std::memory_order_acquire); } std::shared_lock Namespace::ReadLockUnlessFrozen() const @@ -160,14 +165,14 @@ bool Namespace::GetOwnField(const String& field, Value *result) const Namespace::Iterator Namespace::Begin() { - ASSERT(OwnsLock()); + ASSERT(Frozen() || OwnsLock()); return m_Data.begin(); } Namespace::Iterator Namespace::End() { - ASSERT(OwnsLock()); + ASSERT(Frozen() || OwnsLock()); return m_Data.end(); } diff --git a/lib/base/namespace.hpp b/lib/base/namespace.hpp index 1a028e2c5..c7f1a7e0a 100644 --- a/lib/base/namespace.hpp +++ b/lib/base/namespace.hpp @@ -73,6 +73,7 @@ public: bool Contains(const String& field) const; void Remove(const String& field); void Freeze(); + bool Frozen() const; Iterator Begin(); Iterator End();