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

View File

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

View File

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