// Copyright (c) 2011-present, Facebook, Inc. All rights reserved. // This source code is licensed under both the GPLv2 (found in the // COPYING file in the root directory) and Apache 2.0 License // (found in the LICENSE.Apache file in the root directory). // // Copyright (c) 2011 The LevelDB Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. See the AUTHORS file for names of contributors. #pragma once #include #include #include #include #include #include "util/autovector.h" #include "port/port.h" namespace rocksdb { // Cleanup function that will be called for a stored thread local // pointer (if not NULL) when one of the following happens: // (1) a thread terminates // (2) a ThreadLocalPtr is destroyed typedef void (*UnrefHandler)(void* ptr); // ThreadLocalPtr stores only values of pointer type. Different from // the usual thread-local-storage, ThreadLocalPtr has the ability to // distinguish data coming from different threads and different // ThreadLocalPtr instances. For example, if a regular thread_local // variable A is declared in DBImpl, two DBImpl objects would share // the same A. However, a ThreadLocalPtr that is defined under the // scope of DBImpl can avoid such confliction. As a result, its memory // usage would be O(# of threads * # of ThreadLocalPtr instances). class ThreadLocalPtr { public: explicit ThreadLocalPtr(UnrefHandler handler = nullptr); ~ThreadLocalPtr(); // Return the current pointer stored in thread local void* Get() const; // Set a new pointer value to the thread local storage. void Reset(void* ptr); // Atomically swap the supplied ptr and return the previous value void* Swap(void* ptr); // Atomically compare the stored value with expected. Set the new // pointer value to thread local only if the comparison is true. // Otherwise, expected returns the stored value. // Return true on success, false on failure bool CompareAndSwap(void* ptr, void*& expected); // Reset all thread local data to replacement, and return non-nullptr // data for all existing threads void Scrape(autovector* ptrs, void* const replacement); typedef std::function FoldFunc; // Update res by applying func on each thread-local value. Holds a lock that // prevents unref handler from running during this call, but clients must // still provide external synchronization since the owning thread can // access the values without internal locking, e.g., via Get() and Reset(). void Fold(FoldFunc func, void* res); // Add here for testing // Return the next available Id without claiming it static uint32_t TEST_PeekId(); // Initialize the static singletons of the ThreadLocalPtr. // // If this function is not called, then the singletons will be // automatically initialized when they are used. // // Calling this function twice or after the singletons have been // initialized will be no-op. static void InitSingletons(); class StaticMeta; private: static StaticMeta* Instance(); const uint32_t id_; }; } // namespace rocksdb