@@ -78,21 +78,16 @@ typedef std::map<std::pair<void*, void*>, LockStack> LockOrders;
78
78
typedef std::set<std::pair<void *, void *> > InvLockOrders;
79
79
80
80
struct LockData {
81
- // Very ugly hack: as the global constructs and destructors run single
82
- // threaded, we use this boolean to know whether LockData still exists,
83
- // as DeleteLock can get called by global RecursiveMutex destructors
84
- // after LockData disappears.
85
- bool available;
86
- LockData () : available(true ) {}
87
- ~LockData () { available = false ; }
88
-
89
81
LockOrders lockorders;
90
82
InvLockOrders invlockorders;
91
83
std::mutex dd_mutex;
92
84
};
85
+
93
86
LockData& GetLockData () {
94
- static LockData lockdata;
95
- return lockdata;
87
+ // This approach guarantees that the object is not destroyed until after its last use.
88
+ // The operating system automatically reclaims all the memory in a program's heap when that program exits.
89
+ static LockData& lock_data = *new LockData ();
90
+ return lock_data;
96
91
}
97
92
98
93
static thread_local LockStack g_lockstack;
@@ -207,10 +202,6 @@ void AssertLockNotHeldInternal(const char* pszName, const char* pszFile, int nLi
207
202
void DeleteLock (void * cs)
208
203
{
209
204
LockData& lockdata = GetLockData ();
210
- if (!lockdata.available ) {
211
- // We're already shutting down.
212
- return ;
213
- }
214
205
std::lock_guard<std::mutex> lock (lockdata.dd_mutex );
215
206
std::pair<void *, void *> item = std::make_pair (cs, nullptr );
216
207
LockOrders::iterator it = lockdata.lockorders .lower_bound (item);
0 commit comments