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