1 // Copyright 2012 The Chromium Authors 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef BASE_THREADING_THREAD_ID_NAME_MANAGER_H_ 6 #define BASE_THREADING_THREAD_ID_NAME_MANAGER_H_ 7 8 #include <map> 9 #include <string> 10 #include <vector> 11 12 #include "base/base_export.h" 13 #include "base/functional/callback.h" 14 #include "base/memory/raw_ptr.h" 15 #include "base/synchronization/lock.h" 16 #include "base/threading/platform_thread.h" 17 18 namespace base { 19 20 template <typename T> 21 struct DefaultSingletonTraits; 22 23 class BASE_EXPORT ThreadIdNameManager { 24 public: 25 static ThreadIdNameManager* GetInstance(); 26 27 ThreadIdNameManager(const ThreadIdNameManager&) = delete; 28 ThreadIdNameManager& operator=(const ThreadIdNameManager&) = delete; 29 30 static const char* GetDefaultInternedString(); 31 32 class BASE_EXPORT Observer { 33 public: 34 virtual ~Observer(); 35 36 // Called on the thread whose name is changing, immediately after the name 37 // is set. |name| is a pointer to a C string that is guaranteed to remain 38 // valid for the duration of the process. 39 // 40 // NOTE: Will be called while ThreadIdNameManager's lock is held, so don't 41 // call back into it. 42 virtual void OnThreadNameChanged(const char* name) = 0; 43 }; 44 45 // Register the mapping between a thread |id| and |handle|. 46 void RegisterThread(PlatformThreadHandle::Handle handle, PlatformThreadId id); 47 48 void AddObserver(Observer*); 49 void RemoveObserver(Observer*); 50 51 // Set the name for the current thread. 52 void SetName(const std::string& name); 53 54 // Get the name for the given id. 55 const char* GetName(PlatformThreadId id); 56 57 // Unlike |GetName|, this method using TLS and avoids touching |lock_|. 58 const char* GetNameForCurrentThread(); 59 60 // Remove the name for the given id. 61 void RemoveName(PlatformThreadHandle::Handle handle, PlatformThreadId id); 62 63 // Return all registered thread ids (note that this doesn't include the main 64 // thread id). 65 std::vector<PlatformThreadId> GetIds(); 66 67 private: 68 friend struct DefaultSingletonTraits<ThreadIdNameManager>; 69 70 typedef std::map<PlatformThreadId, PlatformThreadHandle::Handle> 71 ThreadIdToHandleMap; 72 typedef std::map<PlatformThreadHandle::Handle, std::string*> 73 ThreadHandleToInternedNameMap; 74 typedef std::map<std::string, raw_ptr<std::string, CtnExperimental>> 75 NameToInternedNameMap; 76 77 ThreadIdNameManager(); 78 ~ThreadIdNameManager(); 79 80 // lock_ protects the name_to_interned_name_, thread_id_to_handle_ and 81 // thread_handle_to_interned_name_ maps. 82 Lock lock_; 83 84 NameToInternedNameMap name_to_interned_name_; 85 ThreadIdToHandleMap thread_id_to_handle_; 86 ThreadHandleToInternedNameMap thread_handle_to_interned_name_; 87 88 // Treat the main process specially as there is no PlatformThreadHandle. 89 raw_ptr<std::string> main_process_name_; 90 PlatformThreadId main_process_id_; 91 92 // There's no point using a base::ObserverList behind a lock, so we just use 93 // an std::vector instead. 94 std::vector<raw_ptr<Observer, VectorExperimental>> observers_; 95 }; 96 97 } // namespace base 98 99 #endif // BASE_THREADING_THREAD_ID_NAME_MANAGER_H_ 100