@ -140,20 +140,15 @@ private:
// The private mutex. Developers should always use Mutex() instead of
// The private mutex. Developers should always use Mutex() instead of
// using this variable directly.
// using this variable directly.
port : : Mutex mutex_ ;
port : : Mutex mutex_ ;
# ifdef ROCKSDB_SUPPORT_THREAD_LOCAL
// Thread local storage
// Thread local storage
static __thread ThreadData * tls_ ;
static thread_local ThreadData * tls_ ;
# endif
// Used to make thread exit trigger possible if !defined(OS_MACOSX).
// Used to make thread exit trigger possible if !defined(OS_MACOSX).
// Otherwise, used to retrieve thread data.
// Otherwise, used to retrieve thread data.
pthread_key_t pthread_key_ ;
pthread_key_t pthread_key_ ;
} ;
} ;
thread_local ThreadData * ThreadLocalPtr : : StaticMeta : : tls_ = nullptr ;
# ifdef ROCKSDB_SUPPORT_THREAD_LOCAL
__thread ThreadData * ThreadLocalPtr : : StaticMeta : : tls_ = nullptr ;
# endif
// Windows doesn't support a per-thread destructor with its
// Windows doesn't support a per-thread destructor with its
// TLS primitives. So, we build it manually by inserting a
// TLS primitives. So, we build it manually by inserting a
@ -263,13 +258,10 @@ ThreadLocalPtr::StaticMeta* ThreadLocalPtr::Instance() {
// the following variable will go first, then OnThreadExit, therefore causing
// the following variable will go first, then OnThreadExit, therefore causing
// invalid access.
// invalid access.
//
//
// The above problem can be solved by using thread_local to store tls_ instead
// The above problem can be solved by using thread_local to store tls_.
// of using __thread. The major difference between thread_local and __thread
// thread_local supports dynamic construction and destruction of
// is that thread_local supports dynamic construction and destruction of
// non-primitive typed variables. As a result, we can guarantee the
// non-primitive typed variables. As a result, we can guarantee the
// destruction order even when the main thread dies before any child threads.
// destruction order even when the main thread dies before any child threads.
// However, thread_local is not supported in all compilers that accept -std=c++11
// (e.g., eg Mac with XCode < 8. XCode 8+ supports thread_local).
static ThreadLocalPtr : : StaticMeta * inst = new ThreadLocalPtr : : StaticMeta ( ) ;
static ThreadLocalPtr : : StaticMeta * inst = new ThreadLocalPtr : : StaticMeta ( ) ;
return inst ;
return inst ;
}
}
@ -328,10 +320,6 @@ ThreadLocalPtr::StaticMeta::StaticMeta()
# if !defined(OS_WIN)
# if !defined(OS_WIN)
static struct A {
static struct A {
~ A ( ) {
~ A ( ) {
# ifndef ROCKSDB_SUPPORT_THREAD_LOCAL
ThreadData * tls_ =
static_cast < ThreadData * > ( pthread_getspecific ( Instance ( ) - > pthread_key_ ) ) ;
# endif
if ( tls_ ) {
if ( tls_ ) {
OnThreadExit ( tls_ ) ;
OnThreadExit ( tls_ ) ;
}
}
@ -366,13 +354,6 @@ void ThreadLocalPtr::StaticMeta::RemoveThreadData(
}
}
ThreadData * ThreadLocalPtr : : StaticMeta : : GetThreadLocal ( ) {
ThreadData * ThreadLocalPtr : : StaticMeta : : GetThreadLocal ( ) {
# ifndef ROCKSDB_SUPPORT_THREAD_LOCAL
// Make this local variable name look like a member variable so that we
// can share all the code below
ThreadData * tls_ =
static_cast < ThreadData * > ( pthread_getspecific ( Instance ( ) - > pthread_key_ ) ) ;
# endif
if ( UNLIKELY ( tls_ = = nullptr ) ) {
if ( UNLIKELY ( tls_ = = nullptr ) ) {
auto * inst = Instance ( ) ;
auto * inst = Instance ( ) ;
tls_ = new ThreadData ( inst ) ;
tls_ = new ThreadData ( inst ) ;