22 #include "MAContainerLocker.hpp" 24 #include "MAContainerLockerPrivate.hpp" 27 #include <MCThreadLocalData.hpp> 35 void CheckStaticContainerLockerVariables()
37 if (!ContainerLockManager.get())
39 ContainerLockManager.reset(
new MAContainerLockManager);
44 MAContainerLockManager::MAContainerLockManager() : ContainerDangerSignal(new ContainerDangerSignalType)
49 MAContainerLockManager& MAContainerLockManager::GetInstance()
51 CheckStaticContainerLockerVariables();
52 return *ContainerLockManager;
56 void MAContainerLockManager::RegisterFileName(
const std::string& class_name,
const std::string& file_name)
58 ClassFiles[class_name] = FormatFileString(file_name);
62 int MAContainerLockManager::RegisterContainer(
const std::string& class_name,
const std::string& container_name)
64 Containers.push_back(class_name+
"::"+container_name);
65 return Containers.size()-1;
69 void MAContainerLockManager::Lock(
int container_id,
int line,
const char* file_name)
71 const auto Iter = ContainerLocks.find(container_id);
74 if (Iter != ContainerLocks.end())
76 std::string ContainerName = Containers[container_id];
77 std::string
ClassName = ContainerName.substr(0, ContainerName.find_first_of(
':'));
78 std::string OriginalFileName = Iter->second.second.empty() ? ClassFiles[
ClassName] : Iter->second.second;
79 std::string CurrentFileName = file_name ==
nullptr ? ClassFiles[
ClassName] : FormatFileString(std::string(file_name));
81 MC_WARNING(
"Crash danger: The container %s has been locked at %s (line %d), cannot be locked at %s (line %d)",
82 Containers[container_id].c_str(), OriginalFileName.c_str(),
83 Iter->second.first, CurrentFileName.c_str(), line);
84 (*ContainerDangerSignal).Emit();
87 MA::ContainerLockDescriptor Descriptor;
89 Descriptor.first = line;
90 Descriptor.second = file_name ==
nullptr ?
"" : FormatFileString(std::string(file_name));
91 ContainerLocks[container_id] = Descriptor;
95 void MAContainerLockManager::Unlock(
int container_id,
int line,
const char* file_name)
97 std::string FileName = file_name ==
nullptr ?
"" : FormatFileString(file_name);
100 for (
auto iter = ContainerLocks.begin(); iter != ContainerLocks.end(); ++iter)
102 if (iter->first == container_id && iter->second.first == line &&
103 iter->second.second == FileName)
105 ContainerLocks.erase(iter);
113 std::string MAContainerLockManager::FormatFileString(
const std::string& full_file_name)
const 115 size_t Index = full_file_name.find_last_of(
'/');
117 if (Index == std::string::npos)
119 return full_file_name;
121 return full_file_name.substr(Index+1, full_file_name.length()-Index);
125 int MAContainerLockManager::GetActiveLockNumber()
const 127 return ContainerLocks.size();
133 ClassName(class_name)
135 CheckStaticContainerLockerVariables();
136 ContainerLockManager->RegisterFileName(ClassName, file_name);
142 CheckStaticContainerLockerVariables();
143 return ContainerLockManager->RegisterContainer(ClassName, container_name);
149 CheckStaticContainerLockerVariables();
150 ContainerLockManager->Lock(container_id, line, file_name);
157 CheckStaticContainerLockerVariables();
158 ContainerLockManager->Unlock(container_id, line, file_name);
std::string ClassName
Class name.
#define MC_WARNING(...)
Warning macro.
MAContainerLocker(const std::string &class_name, const std::string &file_name)
Class constructor.
int Lock(int container_id, int line, const char *file_name=nullptr)
Lock a container.
int Unlock(int container_id, int line, const char *file_name=nullptr)
Unlock a container.
int RegisterContainer(const std::string &container_name)
Register a container for locking.
A wrapper class to cover boost::thread_specific_ptr/folly::ThreadLocal API on certain targets...