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, std::string*> NameToInternedNameMap; 75 76 ThreadIdNameManager(); 77 ~ThreadIdNameManager(); 78 79 // lock_ protects the name_to_interned_name_, thread_id_to_handle_ and 80 // thread_handle_to_interned_name_ maps. 81 Lock lock_; 82 83 NameToInternedNameMap name_to_interned_name_; 84 ThreadIdToHandleMap thread_id_to_handle_; 85 ThreadHandleToInternedNameMap thread_handle_to_interned_name_; 86 87 // Treat the main process specially as there is no PlatformThreadHandle. 88 raw_ptr<std::string> main_process_name_; 89 PlatformThreadId main_process_id_; 90 91 // There's no point using a base::ObserverList behind a lock, so we just use 92 // an std::vector instead. 93 std::vector<raw_ptr<Observer, VectorExperimental>> observers_; 94 }; 95 96 } // namespace base 97 98 #endif // BASE_THREADING_THREAD_ID_NAME_MANAGER_H_ 99