diff options
| author | Matt Peters <[email protected]> | 2021-12-02 21:16:55 -0700 |
|---|---|---|
| committer | Matt Peters <[email protected]> | 2021-12-02 21:16:55 -0700 |
| commit | c9d52890cd98aaf2ec46a726d323169ca724a1dd (patch) | |
| tree | ad9c6c45540336c7298b857273a30b58cc6b645a /zencore/include | |
| parent | Merge pull request #31 from EpicGames/non-elevated-asio (diff) | |
| download | zen-c9d52890cd98aaf2ec46a726d323169ca724a1dd.tar.xz zen-c9d52890cd98aaf2ec46a726d323169ca724a1dd.zip | |
Make IoBufferCore::Materialize threadsafe
Diffstat (limited to 'zencore/include')
| -rw-r--r-- | zencore/include/zencore/iobuffer.h | 48 |
1 files changed, 29 insertions, 19 deletions
diff --git a/zencore/include/zencore/iobuffer.h b/zencore/include/zencore/iobuffer.h index 04b3b33dd..a39f442e3 100644 --- a/zencore/include/zencore/iobuffer.h +++ b/zencore/include/zencore/iobuffer.h @@ -2,6 +2,7 @@ #pragma once +#include <atomic> #include <memory.h> #include <zencore/memory.h> #include "refcount.h" @@ -111,39 +112,39 @@ public: inline void EnsureDataValid() const { - if ((m_Flags & kIsExtended) && !(m_Flags & kIsMaterialized)) + uint32_t LocalFlags = m_Flags.load(std::memory_order_acquire); + if ((LocalFlags & kIsExtended) && !(LocalFlags & kIsMaterialized)) { Materialize(); } } - inline bool IsOwnedByThis() const { return !!(m_Flags & kIsOwnedByThis); } + inline bool IsOwnedByThis() const { return !!(m_Flags.load(std::memory_order_relaxed) & kIsOwnedByThis); } inline void SetIsOwnedByThis(bool NewState) { if (NewState) { - m_Flags |= kIsOwnedByThis; + m_Flags.fetch_or(kIsOwnedByThis, std::memory_order_relaxed); } else { - m_Flags &= ~kIsOwnedByThis; + m_Flags.fetch_and(~kIsOwnedByThis, std::memory_order_relaxed); } } inline bool IsOwned() const { - bool ThisIsOwned = !!(m_Flags & kIsOwnedByThis); - if (ThisIsOwned) + if (IsOwnedByThis()) { return true; } return m_OuterCore && m_OuterCore->IsOwned(); } - inline bool IsImmutable() const { return (m_Flags & kIsMutable) == 0; } - inline bool IsWholeFile() const { return (m_Flags & kIsWholeFile) != 0; } - inline bool IsNull() const { return (m_Flags & kIsNull) != 0; } + inline bool IsImmutable() const { return (m_Flags.load(std::memory_order_relaxed) & kIsMutable) == 0; } + inline bool IsWholeFile() const { return (m_Flags.load(std::memory_order_relaxed) & kIsWholeFile) != 0; } + inline bool IsNull() const { return (m_Flags.load(std::memory_order_relaxed) & kIsNull) != 0; } inline IoBufferExtendedCore* ExtendedCore(); inline const IoBufferExtendedCore* ExtendedCore() const; @@ -168,11 +169,11 @@ public: { if (!NewState) { - m_Flags |= kIsMutable; + m_Flags.fetch_or(kIsMutable, std::memory_order_relaxed); } else { - m_Flags &= ~kIsMutable; + m_Flags.fetch_and(~kIsMutable, std::memory_order_relaxed); } } @@ -180,27 +181,36 @@ public: { if (NewState) { - m_Flags |= kIsWholeFile; + m_Flags.fetch_or(kIsWholeFile, std::memory_order_relaxed); } else { - m_Flags |= ~kIsWholeFile; + m_Flags.fetch_and(~kIsWholeFile, std::memory_order_relaxed); } } inline void SetContentType(ZenContentType ContentType) { ZEN_ASSERT_SLOW((uint32_t(ContentType) & kContentTypeMask) == uint32_t(ContentType)); - m_Flags = (m_Flags & ~(kContentTypeMask << kContentTypeShift)) | (uint32_t(ContentType) << kContentTypeShift); + uint32_t OldValue = m_Flags.load(std::memory_order_relaxed); + bool bSucceeded; + do + { + uint32_t NewValue = (OldValue & ~(kContentTypeMask << kContentTypeShift)) | (uint32_t(ContentType) << kContentTypeShift); + bSucceeded = m_Flags.compare_exchange_weak(OldValue, NewValue, std::memory_order_relaxed, std::memory_order_relaxed); + } while (!bSucceeded); } - inline ZenContentType GetContentType() const { return ZenContentType((m_Flags >> kContentTypeShift) & kContentTypeMask); } + inline ZenContentType GetContentType() const + { + return ZenContentType((m_Flags.load(std::memory_order_relaxed) >> kContentTypeShift) & kContentTypeMask); + } inline uint32_t GetRefCount() const { return m_RefCount; } protected: uint32_t m_RefCount = 0; - mutable uint32_t m_Flags = 0; + mutable std::atomic<uint32_t> m_Flags{0}; mutable const void* m_DataPtr = nullptr; size_t m_DataBytes = 0; RefPtr<const IoBufferCore> m_OuterCore; @@ -213,7 +223,7 @@ protected: static_assert((uint32_t(ZenContentType::kUnknownContentType) & ~kContentTypeMask) == 0); - enum Flags + enum Flags : uint32_t { kIsNull = 1 << 0, // This is a null IoBuffer kIsMutable = 1 << 1, @@ -266,7 +276,7 @@ private: inline IoBufferExtendedCore* IoBufferCore::ExtendedCore() { - if (m_Flags & kIsExtended) + if (m_Flags.load(std::memory_order_relaxed) & kIsExtended) { return static_cast<IoBufferExtendedCore*>(this); } @@ -277,7 +287,7 @@ IoBufferCore::ExtendedCore() inline const IoBufferExtendedCore* IoBufferCore::ExtendedCore() const { - if (m_Flags & kIsExtended) + if (m_Flags.load(std::memory_order_relaxed) & kIsExtended) { return static_cast<const IoBufferExtendedCore*>(this); } |