Modified: trunk/Source/WTF/ChangeLog (225037 => 225038)
--- trunk/Source/WTF/ChangeLog 2017-11-20 00:56:27 UTC (rev 225037)
+++ trunk/Source/WTF/ChangeLog 2017-11-20 01:08:20 UTC (rev 225038)
@@ -1,3 +1,20 @@
+2017-11-19 Chris Dumez <[email protected]>
+
+ Fix potential thread safety issue in ThreadSafeIdentified
+ https://bugs.webkit.org/show_bug.cgi?id=179879
+
+ Reviewed by Darin Adler.
+
+ Fix potential thread safety issue in ThreadSafeIdentified. Protect static std::atomic
+ initialization with an std::call_once() given that we build with
+ --fno-threadsafe-statics.
+
+ * wtf/Identified.h:
+ (WTF::Identified::Identified):
+ (WTF::Identified::generateIdentifier):
+ (WTF::ThreadSafeIdentified::ThreadSafeIdentified):
+ (WTF::ThreadSafeIdentified::generateIdentifier):
+
2017-11-18 Darin Adler <[email protected]>
Eliminate some cases of double hashing, other related refactoring
Modified: trunk/Source/WTF/wtf/Identified.h (225037 => 225038)
--- trunk/Source/WTF/wtf/Identified.h 2017-11-20 00:56:27 UTC (rev 225037)
+++ trunk/Source/WTF/wtf/Identified.h 2017-11-20 01:08:20 UTC (rev 225038)
@@ -26,10 +26,11 @@
#pragma once
#include <atomic>
+#include <wtf/NeverDestroyed.h>
namespace WTF {
-template <typename IdentifierType, typename StaticType, typename ClassType>
+template <typename IdentifierType, typename ClassType>
class IdentifiedBase {
public:
IdentifierType identifier() const
@@ -38,11 +39,6 @@
}
protected:
- IdentifiedBase()
- : m_identifier(++s_currentIdentifier)
- {
- }
-
IdentifiedBase(const IdentifiedBase& other)
: m_identifier(other.m_identifier)
{
@@ -55,33 +51,56 @@
private:
IdentifierType m_identifier;
- static StaticType s_currentIdentifier;
};
-template<typename IdentifierType, typename StaticType, typename ClassType> StaticType IdentifiedBase<IdentifierType, StaticType, ClassType>::s_currentIdentifier;
-
template <typename T>
-class Identified : public IdentifiedBase<uint64_t, uint64_t, T> {
+class Identified : public IdentifiedBase<uint64_t, T> {
protected:
- Identified() = default;
+ Identified()
+ : IdentifiedBase<uint64_t, T>(generateIdentifier())
+ {
+ }
+
Identified(const Identified&) = default;
explicit Identified(uint64_t identifier)
- : IdentifiedBase<uint64_t, uint64_t, T>(identifier)
+ : IdentifiedBase<uint64_t, T>(identifier)
{
}
+
+private:
+ static uint64_t generateIdentifier()
+ {
+ static uint64_t currentIdentifier;
+ return ++currentIdentifier;
+ }
};
template <typename T>
-class ThreadSafeIdentified : public IdentifiedBase<uint64_t, std::atomic<uint64_t>, T> {
+class ThreadSafeIdentified : public IdentifiedBase<uint64_t, T> {
protected:
- ThreadSafeIdentified() = default;
+ ThreadSafeIdentified()
+ : IdentifiedBase<uint64_t, T>(generateIdentifier())
+ {
+ }
+
ThreadSafeIdentified(const ThreadSafeIdentified&) = default;
explicit ThreadSafeIdentified(uint64_t identifier)
- : IdentifiedBase<uint64_t, std::atomic<uint64_t>, T>(identifier)
+ : IdentifiedBase<uint64_t, T>(identifier)
{
}
+
+private:
+ static uint64_t generateIdentifier()
+ {
+ static LazyNeverDestroyed<std::atomic<uint64_t>> currentIdentifier;
+ static std::once_flag initializeCurrentIdentifier;
+ std::call_once(initializeCurrentIdentifier, [] {
+ currentIdentifier.construct(0);
+ });
+ return ++currentIdentifier.get();
+ }
};
} // namespace WTF