ThreadEntry* prev;
};
-
+constexpr uint32_t kEntryIDInvalid = std::numeric_limits<uint32_t>::max();
// Held in a singleton to track our global instances.
// We have one of these per "Tag", by default one for the whole system
// fail). It allows us to keep a constexpr constructor and avoid SIOF.
class EntryID {
public:
- static constexpr uint32_t kInvalid = std::numeric_limits<uint32_t>::max();
std::atomic<uint32_t> value;
- constexpr EntryID() : value(kInvalid) {
+ constexpr EntryID() : value(kEntryIDInvalid) {
}
EntryID(EntryID&& other) noexcept : value(other.value.load()) {
- other.value = kInvalid;
+ other.value = kEntryIDInvalid;
}
EntryID& operator=(EntryID&& other) {
assert(this != &other);
value = other.value.load();
- other.value = kInvalid;
+ other.value = kEntryIDInvalid;
return *this;
}
uint32_t getOrAllocate() {
uint32_t id = getOrInvalid();
- if (id != kInvalid) {
+ if (id != kEntryIDInvalid) {
return id;
}
// The lock inside allocate ensures that a single value is allocated
std::lock_guard<std::mutex> g(meta.lock_);
id = ent->value.load();
- if (id != EntryID::kInvalid) {
+ if (id != kEntryIDInvalid) {
return id;
}
}
uint32_t old_id = ent->value.exchange(id);
- DCHECK_EQ(old_id, EntryID::kInvalid);
+ DCHECK_EQ(old_id, kEntryIDInvalid);
return id;
}
std::vector<ElementWrapper> elements;
{
std::lock_guard<std::mutex> g(meta.lock_);
- uint32_t id = ent->value.exchange(EntryID::kInvalid);
- if (id == EntryID::kInvalid) {
+ uint32_t id = ent->value.exchange(kEntryIDInvalid);
+ if (id == kEntryIDInvalid) {
return;
}
}
};
-template <class Tag>
-constexpr uint32_t StaticMeta<Tag>::EntryID::kInvalid;
-
#ifdef FOLLY_TLD_USE_FOLLY_TLS
template <class Tag>
FOLLY_TLS ThreadEntry StaticMeta<Tag>::threadEntry_ = {nullptr, 0,
EXPECT_EQ(wVersionMax * 10, Widget::totalVal_);
}
-TEST(ThreadLocalPtr, ODRUseEntryIDkInvalid) {
- // EntryID::kInvalid is odr-used
- // see http://en.cppreference.com/w/cpp/language/static
- const uint32_t* pInvalid =
- &(threadlocal_detail::StaticMeta<void>::EntryID::kInvalid);
- EXPECT_EQ(std::numeric_limits<uint32_t>::max(), *pInvalid);
-}
-
class SimpleThreadCachedInt {
class NewTag;