dsinclair@chromium.org | 38608f8 | 2013-01-26 05:41:19 +0900 | [diff] [blame] | 1 | // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 | // Use of this source code is governed by a BSD-style license that can be |
| 3 | // found in the LICENSE file. |
| 4 | |
| 5 | #include "base/threading/thread_id_name_manager.h" |
| 6 | |
| 7 | #include <stdlib.h> |
| 8 | #include <string.h> |
| 9 | |
| 10 | #include "base/logging.h" |
| 11 | #include "base/memory/singleton.h" |
avi@chromium.org | 68a745c | 2013-06-11 05:11:14 +0900 | [diff] [blame] | 12 | #include "base/strings/string_util.h" |
dsinclair@chromium.org | 38608f8 | 2013-01-26 05:41:19 +0900 | [diff] [blame] | 13 | |
| 14 | namespace base { |
| 15 | namespace { |
| 16 | |
| 17 | static const char kDefaultName[] = ""; |
| 18 | static std::string* g_default_name; |
| 19 | |
dsinclair@chromium.org | 38608f8 | 2013-01-26 05:41:19 +0900 | [diff] [blame] | 20 | } |
| 21 | |
dsinclair@chromium.org | 5df777e | 2013-05-28 01:37:39 +0900 | [diff] [blame] | 22 | ThreadIdNameManager::ThreadIdNameManager() |
finnur@chromium.org | 14a6063 | 2013-08-29 18:39:16 +0900 | [diff] [blame] | 23 | : main_process_name_(NULL), |
| 24 | main_process_id_(kInvalidThreadId) { |
dsinclair@chromium.org | 38608f8 | 2013-01-26 05:41:19 +0900 | [diff] [blame] | 25 | g_default_name = new std::string(kDefaultName); |
| 26 | |
| 27 | AutoLock locked(lock_); |
| 28 | name_to_interned_name_[kDefaultName] = g_default_name; |
| 29 | } |
| 30 | |
| 31 | ThreadIdNameManager::~ThreadIdNameManager() { |
| 32 | } |
| 33 | |
| 34 | ThreadIdNameManager* ThreadIdNameManager::GetInstance() { |
| 35 | return Singleton<ThreadIdNameManager, |
| 36 | LeakySingletonTraits<ThreadIdNameManager> >::get(); |
| 37 | } |
| 38 | |
| 39 | const char* ThreadIdNameManager::GetDefaultInternedString() { |
| 40 | return g_default_name->c_str(); |
| 41 | } |
| 42 | |
dsinclair@chromium.org | 5df777e | 2013-05-28 01:37:39 +0900 | [diff] [blame] | 43 | void ThreadIdNameManager::RegisterThread(PlatformThreadHandle::Handle handle, |
| 44 | PlatformThreadId id) { |
| 45 | AutoLock locked(lock_); |
| 46 | thread_id_to_handle_[id] = handle; |
| 47 | thread_handle_to_interned_name_[handle] = |
| 48 | name_to_interned_name_[kDefaultName]; |
| 49 | } |
| 50 | |
dsinclair@chromium.org | 38608f8 | 2013-01-26 05:41:19 +0900 | [diff] [blame] | 51 | void ThreadIdNameManager::SetName(PlatformThreadId id, const char* name) { |
| 52 | std::string str_name(name); |
| 53 | |
| 54 | AutoLock locked(lock_); |
dsinclair@chromium.org | 5df777e | 2013-05-28 01:37:39 +0900 | [diff] [blame] | 55 | NameToInternedNameMap::iterator iter = name_to_interned_name_.find(str_name); |
dsinclair@chromium.org | 38608f8 | 2013-01-26 05:41:19 +0900 | [diff] [blame] | 56 | std::string* leaked_str = NULL; |
| 57 | if (iter != name_to_interned_name_.end()) { |
| 58 | leaked_str = iter->second; |
| 59 | } else { |
| 60 | leaked_str = new std::string(str_name); |
| 61 | name_to_interned_name_[str_name] = leaked_str; |
| 62 | } |
dsinclair@chromium.org | 5df777e | 2013-05-28 01:37:39 +0900 | [diff] [blame] | 63 | |
| 64 | ThreadIdToHandleMap::iterator id_to_handle_iter = |
| 65 | thread_id_to_handle_.find(id); |
| 66 | |
| 67 | // The main thread of a process will not be created as a Thread object which |
| 68 | // means there is no PlatformThreadHandler registered. |
| 69 | if (id_to_handle_iter == thread_id_to_handle_.end()) { |
| 70 | main_process_name_ = leaked_str; |
| 71 | main_process_id_ = id; |
| 72 | return; |
| 73 | } |
| 74 | thread_handle_to_interned_name_[id_to_handle_iter->second] = leaked_str; |
dsinclair@chromium.org | 38608f8 | 2013-01-26 05:41:19 +0900 | [diff] [blame] | 75 | } |
| 76 | |
| 77 | const char* ThreadIdNameManager::GetName(PlatformThreadId id) { |
| 78 | AutoLock locked(lock_); |
dsinclair@chromium.org | 5df777e | 2013-05-28 01:37:39 +0900 | [diff] [blame] | 79 | |
| 80 | if (id == main_process_id_) |
| 81 | return main_process_name_->c_str(); |
| 82 | |
| 83 | ThreadIdToHandleMap::iterator id_to_handle_iter = |
| 84 | thread_id_to_handle_.find(id); |
| 85 | if (id_to_handle_iter == thread_id_to_handle_.end()) |
dsinclair@chromium.org | 38608f8 | 2013-01-26 05:41:19 +0900 | [diff] [blame] | 86 | return name_to_interned_name_[kDefaultName]->c_str(); |
dsinclair@chromium.org | 5df777e | 2013-05-28 01:37:39 +0900 | [diff] [blame] | 87 | |
| 88 | ThreadHandleToInternedNameMap::iterator handle_to_name_iter = |
| 89 | thread_handle_to_interned_name_.find(id_to_handle_iter->second); |
| 90 | return handle_to_name_iter->second->c_str(); |
dsinclair@chromium.org | 38608f8 | 2013-01-26 05:41:19 +0900 | [diff] [blame] | 91 | } |
| 92 | |
dsinclair@chromium.org | 5df777e | 2013-05-28 01:37:39 +0900 | [diff] [blame] | 93 | void ThreadIdNameManager::RemoveName(PlatformThreadHandle::Handle handle, |
| 94 | PlatformThreadId id) { |
| 95 | AutoLock locked(lock_); |
| 96 | ThreadHandleToInternedNameMap::iterator handle_to_name_iter = |
| 97 | thread_handle_to_interned_name_.find(handle); |
| 98 | |
| 99 | DCHECK(handle_to_name_iter != thread_handle_to_interned_name_.end()); |
| 100 | thread_handle_to_interned_name_.erase(handle_to_name_iter); |
| 101 | |
| 102 | ThreadIdToHandleMap::iterator id_to_handle_iter = |
| 103 | thread_id_to_handle_.find(id); |
| 104 | DCHECK((id_to_handle_iter!= thread_id_to_handle_.end())); |
| 105 | // The given |id| may have been re-used by the system. Make sure the |
| 106 | // mapping points to the provided |handle| before removal. |
| 107 | if (id_to_handle_iter->second != handle) |
dsinclair@chromium.org | 38608f8 | 2013-01-26 05:41:19 +0900 | [diff] [blame] | 108 | return; |
| 109 | |
dsinclair@chromium.org | 5df777e | 2013-05-28 01:37:39 +0900 | [diff] [blame] | 110 | thread_id_to_handle_.erase(id_to_handle_iter); |
dsinclair@chromium.org | 38608f8 | 2013-01-26 05:41:19 +0900 | [diff] [blame] | 111 | } |
| 112 | |
| 113 | } // namespace base |