@@ -587,25 +587,32 @@ class ThreadLocalRegistryImpl {
587
587
// thread's ID.
588
588
typedef std::map<DWORD, ThreadLocalValues> ThreadIdToThreadLocals;
589
589
590
- // Holds the thread id and thread handle that we pass from
591
- // StartWatcherThreadFor to WatcherThreadFunc.
592
- typedef std::pair<DWORD, HANDLE> ThreadIdAndHandle;
590
+ struct WatcherThreadParams {
591
+ DWORD thread_id;
592
+ HANDLE handle;
593
+ Notification has_initialized;
594
+ };
593
595
594
596
static void StartWatcherThreadFor (DWORD thread_id) {
595
597
// The returned handle will be kept in thread_map and closed by
596
598
// watcher_thread in WatcherThreadFunc.
597
599
HANDLE thread =
598
600
::OpenThread (SYNCHRONIZE | THREAD_QUERY_INFORMATION, FALSE , thread_id);
599
601
GTEST_CHECK_ (thread != nullptr );
602
+
603
+ WatcherThreadParams* watcher_thread_params = new WatcherThreadParams;
604
+ watcher_thread_params->thread_id = thread_id;
605
+ watcher_thread_params->handle = thread;
606
+
600
607
// We need to pass a valid thread ID pointer into CreateThread for it
601
608
// to work correctly under Win98.
602
609
DWORD watcher_thread_id;
603
- HANDLE watcher_thread = :: CreateThread (
604
- nullptr , // Default security.
605
- 0 , // Default stack size
606
- &ThreadLocalRegistryImpl::WatcherThreadFunc,
607
- reinterpret_cast <LPVOID>(new ThreadIdAndHandle (thread_id, thread) ),
608
- CREATE_SUSPENDED, &watcher_thread_id);
610
+ HANDLE watcher_thread =
611
+ ::CreateThread ( nullptr , // Default security.
612
+ 0 , // Default stack size
613
+ &ThreadLocalRegistryImpl::WatcherThreadFunc,
614
+ reinterpret_cast <LPVOID>(watcher_thread_params ),
615
+ CREATE_SUSPENDED, &watcher_thread_id);
609
616
GTEST_CHECK_ (watcher_thread != nullptr )
610
617
<< " CreateThread failed with error " << ::GetLastError () << " ." ;
611
618
// Give the watcher thread the same priority as ours to avoid being
@@ -614,17 +621,25 @@ class ThreadLocalRegistryImpl {
614
621
::GetThreadPriority (::GetCurrentThread()));
615
622
::ResumeThread (watcher_thread);
616
623
::CloseHandle (watcher_thread);
624
+
625
+ // Wait for the watcher thread to start to avoid race conditions.
626
+ // One specific race condition that can happen is that we have returned
627
+ // from main and have started to tear down, the newly spawned watcher
628
+ // thread may access already-freed variables, like global shared_ptrs.
629
+ watcher_thread_params->has_initialized.WaitForNotification();
617
630
}
618
631
619
632
// Monitors exit from a given thread and notifies those
620
633
// ThreadIdToThreadLocals about thread termination.
621
634
static DWORD WINAPI WatcherThreadFunc (LPVOID param) {
622
- const ThreadIdAndHandle* tah =
623
- reinterpret_cast <const ThreadIdAndHandle*>(param);
624
- GTEST_CHECK_ (::WaitForSingleObject (tah->second , INFINITE) == WAIT_OBJECT_0);
625
- OnThreadExit (tah->first );
626
- ::CloseHandle (tah->second);
627
- delete tah;
635
+ WatcherThreadParams* watcher_thread_params =
636
+ reinterpret_cast <WatcherThreadParams*>(param);
637
+ watcher_thread_params->has_initialized .Notify ();
638
+ GTEST_CHECK_ (::WaitForSingleObject (watcher_thread_params->handle ,
639
+ INFINITE) == WAIT_OBJECT_0);
640
+ OnThreadExit (watcher_thread_params->thread_id );
641
+ ::CloseHandle (watcher_thread_params->handle);
642
+ delete watcher_thread_params;
628
643
return 0 ;
629
644
}
630
645
@@ -1033,12 +1048,12 @@ GTestLog::~GTestLog() {
1033
1048
}
1034
1049
}
1035
1050
1051
+ #if GTEST_HAS_STREAM_REDIRECTION
1052
+
1036
1053
// Disable Microsoft deprecation warnings for POSIX functions called from
1037
1054
// this class (creat, dup, dup2, and close)
1038
1055
GTEST_DISABLE_MSC_DEPRECATED_PUSH_ ()
1039
1056
1040
- #if GTEST_HAS_STREAM_REDIRECTION
1041
-
1042
1057
namespace {
1043
1058
1044
1059
#if defined(GTEST_OS_LINUX_ANDROID) || defined(GTEST_OS_IOS)
@@ -1333,8 +1348,8 @@ bool ParseInt32(const Message& src_text, const char* str, int32_t* value) {
1333
1348
) {
1334
1349
Message msg;
1335
1350
msg << " WARNING: " << src_text
1336
- << " is expected to be a 32-bit integer, but actually"
1337
- << " has value " << str << " , which overflows.\n " ;
1351
+ << " is expected to be a 32-bit integer, but actually" << " has value "
1352
+ << str << " , which overflows.\n " ;
1338
1353
printf (" %s" , msg.GetString ().c_str ());
1339
1354
fflush (stdout);
1340
1355
return false ;
0 commit comments