simplify ThreadLocalPtr a little bit

Summary:
make singleton a static member instead of dynamic object. This should
also avoid the race on unique_ptr

Test Plan: make all check

Reviewers: igor, haobo, sdong

Reviewed By: igor

CC: leveldb

Differential Revision: https://reviews.facebook.net/D18177
This commit is contained in:
Lei Jin 2014-04-22 21:13:34 -07:00
parent 86a0133d05
commit 547bb6a626
3 changed files with 15 additions and 24 deletions

View File

@ -14,20 +14,14 @@
namespace rocksdb { namespace rocksdb {
std::unique_ptr<ThreadLocalPtr::StaticMeta> ThreadLocalPtr::StaticMeta::inst_;
port::Mutex ThreadLocalPtr::StaticMeta::mutex_; port::Mutex ThreadLocalPtr::StaticMeta::mutex_;
#if !defined(OS_MACOSX) #if !defined(OS_MACOSX)
__thread ThreadLocalPtr::ThreadData* ThreadLocalPtr::StaticMeta::tls_ = nullptr; __thread ThreadLocalPtr::ThreadData* ThreadLocalPtr::StaticMeta::tls_ = nullptr;
#endif #endif
ThreadLocalPtr::StaticMeta* ThreadLocalPtr::StaticMeta::Instance() { ThreadLocalPtr::StaticMeta* ThreadLocalPtr::Instance() {
if (UNLIKELY(inst_ == nullptr)) { static ThreadLocalPtr::StaticMeta inst;
MutexLock l(&mutex_); return &inst;
if (inst_ == nullptr) {
inst_.reset(new StaticMeta());
}
}
return inst_.get();
} }
void ThreadLocalPtr::StaticMeta::OnThreadExit(void* ptr) { void ThreadLocalPtr::StaticMeta::OnThreadExit(void* ptr) {
@ -216,34 +210,34 @@ void ThreadLocalPtr::StaticMeta::ReclaimId(uint32_t id) {
} }
ThreadLocalPtr::ThreadLocalPtr(UnrefHandler handler) ThreadLocalPtr::ThreadLocalPtr(UnrefHandler handler)
: id_(StaticMeta::Instance()->GetId()) { : id_(Instance()->GetId()) {
if (handler != nullptr) { if (handler != nullptr) {
StaticMeta::Instance()->SetHandler(id_, handler); Instance()->SetHandler(id_, handler);
} }
} }
ThreadLocalPtr::~ThreadLocalPtr() { ThreadLocalPtr::~ThreadLocalPtr() {
StaticMeta::Instance()->ReclaimId(id_); Instance()->ReclaimId(id_);
} }
void* ThreadLocalPtr::Get() const { void* ThreadLocalPtr::Get() const {
return StaticMeta::Instance()->Get(id_); return Instance()->Get(id_);
} }
void ThreadLocalPtr::Reset(void* ptr) { void ThreadLocalPtr::Reset(void* ptr) {
StaticMeta::Instance()->Reset(id_, ptr); Instance()->Reset(id_, ptr);
} }
void* ThreadLocalPtr::Swap(void* ptr) { void* ThreadLocalPtr::Swap(void* ptr) {
return StaticMeta::Instance()->Swap(id_, ptr); return Instance()->Swap(id_, ptr);
} }
bool ThreadLocalPtr::CompareAndSwap(void* ptr, void*& expected) { bool ThreadLocalPtr::CompareAndSwap(void* ptr, void*& expected) {
return StaticMeta::Instance()->CompareAndSwap(id_, ptr, expected); return Instance()->CompareAndSwap(id_, ptr, expected);
} }
void ThreadLocalPtr::Scrape(autovector<void*>* ptrs, void* const replacement) { void ThreadLocalPtr::Scrape(autovector<void*>* ptrs, void* const replacement) {
StaticMeta::Instance()->Scrape(id_, ptrs, replacement); Instance()->Scrape(id_, ptrs, replacement);
} }
} // namespace rocksdb } // namespace rocksdb

View File

@ -89,7 +89,7 @@ class ThreadLocalPtr {
class StaticMeta { class StaticMeta {
public: public:
static StaticMeta* Instance(); StaticMeta();
// Return the next available Id // Return the next available Id
uint32_t GetId(); uint32_t GetId();
@ -117,8 +117,6 @@ class ThreadLocalPtr {
void SetHandler(uint32_t id, UnrefHandler handler); void SetHandler(uint32_t id, UnrefHandler handler);
private: private:
StaticMeta();
// Get UnrefHandler for id with acquiring mutex // Get UnrefHandler for id with acquiring mutex
// REQUIRES: mutex locked // REQUIRES: mutex locked
UnrefHandler GetHandler(uint32_t id); UnrefHandler GetHandler(uint32_t id);
@ -136,9 +134,6 @@ class ThreadLocalPtr {
static ThreadData* GetThreadLocal(); static ThreadData* GetThreadLocal();
// Singleton instance
static std::unique_ptr<StaticMeta> inst_;
uint32_t next_instance_id_; uint32_t next_instance_id_;
// Used to recycle Ids in case ThreadLocalPtr is instantiated and destroyed // Used to recycle Ids in case ThreadLocalPtr is instantiated and destroyed
// frequently. This also prevents it from blowing up the vector space. // frequently. This also prevents it from blowing up the vector space.
@ -163,6 +158,8 @@ class ThreadLocalPtr {
pthread_key_t pthread_key_; pthread_key_t pthread_key_;
}; };
static StaticMeta* Instance();
const uint32_t id_; const uint32_t id_;
}; };

View File

@ -49,7 +49,7 @@ struct Params {
class IDChecker : public ThreadLocalPtr { class IDChecker : public ThreadLocalPtr {
public: public:
static uint32_t PeekId() { return StaticMeta::Instance()->PeekId(); } static uint32_t PeekId() { return Instance()->PeekId(); }
}; };
} // anonymous namespace } // anonymous namespace