| 10295 | } |
| 10296 | |
| 10297 | static void OnThreadExit(DWORD thread_id) { |
| 10298 | GTEST_CHECK_(thread_id != 0) << ::GetLastError(); |
| 10299 | std::vector<std::shared_ptr<ThreadLocalValueHolderBase> > value_holders; |
| 10300 | // Clean up the ThreadIdToThreadLocals data structure while holding the |
| 10301 | // lock, but defer the destruction of the ThreadLocalValueHolderBases. |
| 10302 | { |
| 10303 | MutexLock lock(&mutex_); |
| 10304 | ThreadIdToThreadLocals* const thread_to_thread_locals = |
| 10305 | GetThreadLocalsMapLocked(); |
| 10306 | ThreadIdToThreadLocals::iterator thread_local_pos = |
| 10307 | thread_to_thread_locals->find(thread_id); |
| 10308 | if (thread_local_pos != thread_to_thread_locals->end()) { |
| 10309 | ThreadLocalValues& thread_local_values = thread_local_pos->second; |
| 10310 | for (ThreadLocalValues::iterator value_pos = |
| 10311 | thread_local_values.begin(); |
| 10312 | value_pos != thread_local_values.end(); |
| 10313 | ++value_pos) { |
| 10314 | value_holders.push_back(value_pos->second); |
| 10315 | } |
| 10316 | thread_to_thread_locals->erase(thread_local_pos); |
| 10317 | } |
| 10318 | } |
| 10319 | // Outside the lock, let the destructor for 'value_holders' deallocate the |
| 10320 | // ThreadLocalValueHolderBases. |
| 10321 | } |
| 10322 | |
| 10323 | private: |
| 10324 | // In a particular thread, maps a ThreadLocal object to its value. |