Do not require olock on frozen Namespace, Dictionary & Array

This commit is contained in:
Yonas Habteab 2025-07-03 12:09:16 +02:00
parent 2461e0415d
commit 57726fbb66
6 changed files with 31 additions and 11 deletions

View File

@ -96,7 +96,7 @@ void Array::Add(Value value)
*/ */
Array::Iterator Array::Begin() Array::Iterator Array::Begin()
{ {
ASSERT(OwnsLock()); ASSERT(Frozen() || OwnsLock());
return m_Data.begin(); return m_Data.begin();
} }
@ -110,7 +110,7 @@ Array::Iterator Array::Begin()
*/ */
Array::Iterator Array::End() Array::Iterator Array::End()
{ {
ASSERT(OwnsLock()); ASSERT(Frozen() || OwnsLock());
return m_Data.end(); return m_Data.end();
} }
@ -327,7 +327,12 @@ Array::Ptr Array::Unique() const
void Array::Freeze() void Array::Freeze()
{ {
ObjectLock olock(this); 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 Value Array::GetFieldByName(const String& field, bool sandboxed, const DebugInfo& debugInfo) const

View File

@ -4,6 +4,7 @@
#define ARRAY_H #define ARRAY_H
#include "base/i2-base.hpp" #include "base/i2-base.hpp"
#include "base/atomic.hpp"
#include "base/objectlock.hpp" #include "base/objectlock.hpp"
#include "base/value.hpp" #include "base/value.hpp"
#include <boost/range/iterator.hpp> #include <boost/range/iterator.hpp>
@ -98,13 +99,14 @@ public:
Array::Ptr Unique() const; Array::Ptr Unique() const;
void Freeze(); void Freeze();
bool Frozen() const;
Value GetFieldByName(const String& field, bool sandboxed, const DebugInfo& debugInfo) const override; Value GetFieldByName(const String& field, bool sandboxed, const DebugInfo& debugInfo) const override;
void SetFieldByName(const String& field, const Value& value, const DebugInfo& debugInfo) override; void SetFieldByName(const String& field, const Value& value, const DebugInfo& debugInfo) override;
private: private:
std::vector<Value> m_Data; /**< The data for the array. */ std::vector<Value> m_Data; /**< The data for the array. */
bool m_Frozen{false}; Atomic<bool> m_Frozen{false};
}; };
Array::Iterator begin(const Array::Ptr& x); Array::Iterator begin(const Array::Ptr& x);

View File

@ -132,7 +132,7 @@ bool Dictionary::Contains(const String& key) const
*/ */
Dictionary::Iterator Dictionary::Begin() Dictionary::Iterator Dictionary::Begin()
{ {
ASSERT(OwnsLock()); ASSERT(Frozen() || OwnsLock());
return m_Data.begin(); return m_Data.begin();
} }
@ -146,7 +146,7 @@ Dictionary::Iterator Dictionary::Begin()
*/ */
Dictionary::Iterator Dictionary::End() Dictionary::Iterator Dictionary::End()
{ {
ASSERT(OwnsLock()); ASSERT(Frozen() || OwnsLock());
return m_Data.end(); return m_Data.end();
} }
@ -276,7 +276,12 @@ String Dictionary::ToString() const
void Dictionary::Freeze() void Dictionary::Freeze()
{ {
ObjectLock olock(this); 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 Value Dictionary::GetFieldByName(const String& field, bool, const DebugInfo& debugInfo) const

View File

@ -4,6 +4,7 @@
#define DICTIONARY_H #define DICTIONARY_H
#include "base/i2-base.hpp" #include "base/i2-base.hpp"
#include "base/atomic.hpp"
#include "base/object.hpp" #include "base/object.hpp"
#include "base/value.hpp" #include "base/value.hpp"
#include <boost/range/iterator.hpp> #include <boost/range/iterator.hpp>
@ -69,6 +70,7 @@ public:
String ToString() const override; String ToString() const override;
void Freeze(); void Freeze();
bool Frozen() const;
Value GetFieldByName(const String& field, bool sandboxed, const DebugInfo& debugInfo) const override; Value GetFieldByName(const String& field, bool sandboxed, const DebugInfo& debugInfo) const override;
void SetFieldByName(const String& field, const Value& value, const DebugInfo& debugInfo) override; void SetFieldByName(const String& field, const Value& value, const DebugInfo& debugInfo) override;
@ -78,7 +80,7 @@ public:
private: private:
std::map<String, Value> m_Data; /**< The data for the dictionary. */ std::map<String, Value> m_Data; /**< The data for the dictionary. */
mutable std::shared_timed_mutex m_DataMutex; mutable std::shared_timed_mutex m_DataMutex;
bool m_Frozen{false}; Atomic<bool> m_Frozen{false};
}; };
Dictionary::Iterator begin(const Dictionary::Ptr& x); Dictionary::Iterator begin(const Dictionary::Ptr& x);

View File

@ -119,7 +119,12 @@ void Namespace::Remove(const String& field)
void Namespace::Freeze() { void Namespace::Freeze() {
ObjectLock olock(this); 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<std::shared_timed_mutex> Namespace::ReadLockUnlessFrozen() const std::shared_lock<std::shared_timed_mutex> Namespace::ReadLockUnlessFrozen() const
@ -160,14 +165,14 @@ bool Namespace::GetOwnField(const String& field, Value *result) const
Namespace::Iterator Namespace::Begin() Namespace::Iterator Namespace::Begin()
{ {
ASSERT(OwnsLock()); ASSERT(Frozen() || OwnsLock());
return m_Data.begin(); return m_Data.begin();
} }
Namespace::Iterator Namespace::End() Namespace::Iterator Namespace::End()
{ {
ASSERT(OwnsLock()); ASSERT(Frozen() || OwnsLock());
return m_Data.end(); return m_Data.end();
} }

View File

@ -73,6 +73,7 @@ public:
bool Contains(const String& field) const; bool Contains(const String& field) const;
void Remove(const String& field); void Remove(const String& field);
void Freeze(); void Freeze();
bool Frozen() const;
Iterator Begin(); Iterator Begin();
Iterator End(); Iterator End();