aboutsummaryrefslogtreecommitdiff
path: root/zencore/include
diff options
context:
space:
mode:
authorMatt Peters <[email protected]>2021-12-02 21:16:55 -0700
committerMatt Peters <[email protected]>2021-12-02 21:16:55 -0700
commitc9d52890cd98aaf2ec46a726d323169ca724a1dd (patch)
treead9c6c45540336c7298b857273a30b58cc6b645a /zencore/include
parentMerge pull request #31 from EpicGames/non-elevated-asio (diff)
downloadzen-c9d52890cd98aaf2ec46a726d323169ca724a1dd.tar.xz
zen-c9d52890cd98aaf2ec46a726d323169ca724a1dd.zip
Make IoBufferCore::Materialize threadsafe
Diffstat (limited to 'zencore/include')
-rw-r--r--zencore/include/zencore/iobuffer.h48
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);
}