diff options
-rw-r--r-- | .github/workflows/gtest-ci.yml | 43 | ||||
-rw-r--r-- | googletest/include/gtest/internal/gtest-filepath.h | 4 | ||||
-rw-r--r-- | googletest/include/gtest/internal/gtest-port.h | 17 | ||||
-rw-r--r-- | googletest/src/gtest-port.cc | 49 | ||||
-rw-r--r-- | googletest/src/gtest.cc | 18 |
5 files changed, 50 insertions, 81 deletions
diff --git a/.github/workflows/gtest-ci.yml b/.github/workflows/gtest-ci.yml deleted file mode 100644 index 03a8cc5..0000000 --- a/.github/workflows/gtest-ci.yml +++ /dev/null @@ -1,43 +0,0 @@ -name: ci - -on: - push: - pull_request: - -env: - BAZEL_CXXOPTS: -std=c++14 - -jobs: - Linux: - runs-on: ubuntu-latest - steps: - - - uses: actions/checkout@v3 - with: - fetch-depth: 0 - - - name: Tests - run: bazel test --cxxopt=-std=c++14 --features=external_include_paths --test_output=errors ... - - macOS: - runs-on: macos-latest - steps: - - - uses: actions/checkout@v3 - with: - fetch-depth: 0 - - - name: Tests - run: bazel test --cxxopt=-std=c++14 --features=external_include_paths --test_output=errors ... - - - Windows: - runs-on: windows-latest - steps: - - - uses: actions/checkout@v3 - with: - fetch-depth: 0 - - - name: Tests - run: bazel test --cxxopt=/std:c++14 --features=external_include_paths --test_output=errors ... diff --git a/googletest/include/gtest/internal/gtest-filepath.h b/googletest/include/gtest/internal/gtest-filepath.h index 7ffb492..6dc47be 100644 --- a/googletest/include/gtest/internal/gtest-filepath.h +++ b/googletest/include/gtest/internal/gtest-filepath.h @@ -71,7 +71,7 @@ class GTEST_API_ FilePath { public: FilePath() : pathname_("") {} FilePath(const FilePath& rhs) : pathname_(rhs.pathname_) {} - FilePath(FilePath&& rhs) : pathname_(std::move(rhs.pathname_)) {} + FilePath(FilePath&& rhs) noexcept : pathname_(std::move(rhs.pathname_)) {} explicit FilePath(std::string pathname) : pathname_(std::move(pathname)) { Normalize(); @@ -81,7 +81,7 @@ class GTEST_API_ FilePath { Set(rhs); return *this; } - FilePath& operator=(FilePath&& rhs) { + FilePath& operator=(FilePath&& rhs) noexcept { pathname_ = std::move(rhs.pathname_); return *this; } diff --git a/googletest/include/gtest/internal/gtest-port.h b/googletest/include/gtest/internal/gtest-port.h index 35bcf9b..6c469e9 100644 --- a/googletest/include/gtest/internal/gtest-port.h +++ b/googletest/include/gtest/internal/gtest-port.h @@ -340,8 +340,8 @@ #if defined(GTEST_HAS_ABSL) && !defined(GTEST_NO_ABSL_FLAGS) #define GTEST_INTERNAL_HAS_ABSL_FLAGS // Used only in this file. -#include "absl/flags/flag.h" #include "absl/flags/declare.h" +#include "absl/flags/flag.h" #include "absl/flags/reflection.h" #endif @@ -658,11 +658,10 @@ typedef struct _RTL_CRITICAL_SECTION GTEST_CRITICAL_SECTION; // By default, we assume that stream redirection is supported on all // platforms except known mobile / embedded ones. Also, if the port doesn't have // a file system, stream redirection is not supported. -#if defined(GTEST_OS_WINDOWS_MOBILE) || defined(GTEST_OS_WINDOWS_PHONE) || \ - defined(GTEST_OS_WINDOWS_RT) || defined(GTEST_OS_WINDOWS_GAMES) || \ - defined(GTEST_OS_ESP8266) || \ - defined(GTEST_OS_XTENSA) || defined(GTEST_OS_QURT) || \ - !GTEST_HAS_FILE_SYSTEM +#if defined(GTEST_OS_WINDOWS_MOBILE) || defined(GTEST_OS_WINDOWS_PHONE) || \ + defined(GTEST_OS_WINDOWS_RT) || defined(GTEST_OS_WINDOWS_GAMES) || \ + defined(GTEST_OS_ESP8266) || defined(GTEST_OS_XTENSA) || \ + defined(GTEST_OS_QURT) || !GTEST_HAS_FILE_SYSTEM #define GTEST_HAS_STREAM_REDIRECTION 0 #else #define GTEST_HAS_STREAM_REDIRECTION 1 @@ -2109,9 +2108,9 @@ GTEST_DISABLE_MSC_DEPRECATED_PUSH_() // defined there. #if GTEST_HAS_FILE_SYSTEM #if !defined(GTEST_OS_WINDOWS_MOBILE) && !defined(GTEST_OS_WINDOWS_PHONE) && \ - !defined(GTEST_OS_WINDOWS_RT) && !defined(GTEST_OS_WINDOWS_GAMES) && \ - !defined(GTEST_OS_ESP8266) && \ - !defined(GTEST_OS_XTENSA) && !defined(GTEST_OS_QURT) + !defined(GTEST_OS_WINDOWS_RT) && !defined(GTEST_OS_WINDOWS_GAMES) && \ + !defined(GTEST_OS_ESP8266) && !defined(GTEST_OS_XTENSA) && \ + !defined(GTEST_OS_QURT) inline int ChDir(const char* dir) { return chdir(dir); } #endif inline FILE* FOpen(const char* path, const char* mode) { diff --git a/googletest/src/gtest-port.cc b/googletest/src/gtest-port.cc index d423814..1038ad7 100644 --- a/googletest/src/gtest-port.cc +++ b/googletest/src/gtest-port.cc @@ -587,9 +587,11 @@ class ThreadLocalRegistryImpl { // thread's ID. typedef std::map<DWORD, ThreadLocalValues> ThreadIdToThreadLocals; - // Holds the thread id and thread handle that we pass from - // StartWatcherThreadFor to WatcherThreadFunc. - typedef std::pair<DWORD, HANDLE> ThreadIdAndHandle; + struct WatcherThreadParams { + DWORD thread_id; + HANDLE handle; + Notification has_initialized; + }; static void StartWatcherThreadFor(DWORD thread_id) { // The returned handle will be kept in thread_map and closed by @@ -597,15 +599,20 @@ class ThreadLocalRegistryImpl { HANDLE thread = ::OpenThread(SYNCHRONIZE | THREAD_QUERY_INFORMATION, FALSE, thread_id); GTEST_CHECK_(thread != nullptr); + + WatcherThreadParams* watcher_thread_params = new WatcherThreadParams; + watcher_thread_params->thread_id = thread_id; + watcher_thread_params->handle = thread; + // We need to pass a valid thread ID pointer into CreateThread for it // to work correctly under Win98. DWORD watcher_thread_id; - HANDLE watcher_thread = ::CreateThread( - nullptr, // Default security. - 0, // Default stack size - &ThreadLocalRegistryImpl::WatcherThreadFunc, - reinterpret_cast<LPVOID>(new ThreadIdAndHandle(thread_id, thread)), - CREATE_SUSPENDED, &watcher_thread_id); + HANDLE watcher_thread = + ::CreateThread(nullptr, // Default security. + 0, // Default stack size + &ThreadLocalRegistryImpl::WatcherThreadFunc, + reinterpret_cast<LPVOID>(watcher_thread_params), + CREATE_SUSPENDED, &watcher_thread_id); GTEST_CHECK_(watcher_thread != nullptr) << "CreateThread failed with error " << ::GetLastError() << "."; // Give the watcher thread the same priority as ours to avoid being @@ -614,17 +621,25 @@ class ThreadLocalRegistryImpl { ::GetThreadPriority(::GetCurrentThread())); ::ResumeThread(watcher_thread); ::CloseHandle(watcher_thread); + + // Wait for the watcher thread to start to avoid race conditions. + // One specific race condition that can happen is that we have returned + // from main and have started to tear down, the newly spawned watcher + // thread may access already-freed variables, like global shared_ptrs. + watcher_thread_params->has_initialized.WaitForNotification(); } // Monitors exit from a given thread and notifies those // ThreadIdToThreadLocals about thread termination. static DWORD WINAPI WatcherThreadFunc(LPVOID param) { - const ThreadIdAndHandle* tah = - reinterpret_cast<const ThreadIdAndHandle*>(param); - GTEST_CHECK_(::WaitForSingleObject(tah->second, INFINITE) == WAIT_OBJECT_0); - OnThreadExit(tah->first); - ::CloseHandle(tah->second); - delete tah; + WatcherThreadParams* watcher_thread_params = + reinterpret_cast<WatcherThreadParams*>(param); + watcher_thread_params->has_initialized.Notify(); + GTEST_CHECK_(::WaitForSingleObject(watcher_thread_params->handle, + INFINITE) == WAIT_OBJECT_0); + OnThreadExit(watcher_thread_params->thread_id); + ::CloseHandle(watcher_thread_params->handle); + delete watcher_thread_params; return 0; } @@ -1333,8 +1348,8 @@ bool ParseInt32(const Message& src_text, const char* str, int32_t* value) { ) { Message msg; msg << "WARNING: " << src_text - << " is expected to be a 32-bit integer, but actually" - << " has value " << str << ", which overflows.\n"; + << " is expected to be a 32-bit integer, but actually" << " has value " + << str << ", which overflows.\n"; printf("%s", msg.GetString().c_str()); fflush(stdout); return false; diff --git a/googletest/src/gtest.cc b/googletest/src/gtest.cc index 898904f..a997707 100644 --- a/googletest/src/gtest.cc +++ b/googletest/src/gtest.cc @@ -379,7 +379,7 @@ GTEST_DEFINE_string_( testing::internal::StringFromGTestEnv("stream_result_to", ""), "This flag specifies the host name and the port number on which to stream " "test results. Example: \"localhost:555\". The flag is effective only on " - "Linux."); + "Linux and macOS."); GTEST_DEFINE_bool_( throw_on_failure, @@ -2340,7 +2340,7 @@ static const char* const kReservedTestCaseAttributes[] = { "type_param", "value_param", "file", "line"}; // Use a slightly different set for allowed output to ensure existing tests can -// still RecordProperty("result") or "RecordProperty(timestamp") +// still RecordProperty("result") or RecordProperty("timestamp") static const char* const kReservedOutputTestCaseAttributes[] = { "classname", "name", "status", "time", "type_param", "value_param", "file", "line", "result", "timestamp"}; @@ -3184,10 +3184,9 @@ static void PrintTestPartResult(const TestPartResult& test_part_result) { } // class PrettyUnitTestResultPrinter -#if defined(GTEST_OS_WINDOWS) && \ - !defined(GTEST_OS_WINDOWS_MOBILE) && !defined(GTEST_OS_WINDOWS_GAMES) && \ - !defined(GTEST_OS_WINDOWS_PHONE) && !defined(GTEST_OS_WINDOWS_RT) && \ - !defined(GTEST_OS_WINDOWS_MINGW) +#if defined(GTEST_OS_WINDOWS) && !defined(GTEST_OS_WINDOWS_MOBILE) && \ + !defined(GTEST_OS_WINDOWS_GAMES) && !defined(GTEST_OS_WINDOWS_PHONE) && \ + !defined(GTEST_OS_WINDOWS_RT) && !defined(GTEST_OS_WINDOWS_MINGW) // Returns the character attribute for the given color. static WORD GetColorAttribute(GTestColor color) { @@ -3314,10 +3313,9 @@ static void ColoredPrintf(GTestColor color, const char* fmt, ...) { return; } -#if defined(GTEST_OS_WINDOWS) && \ - !defined(GTEST_OS_WINDOWS_MOBILE) && !defined(GTEST_OS_WINDOWS_GAMES) && \ - !defined(GTEST_OS_WINDOWS_PHONE) && !defined(GTEST_OS_WINDOWS_RT) && \ - !defined(GTEST_OS_WINDOWS_MINGW) +#if defined(GTEST_OS_WINDOWS) && !defined(GTEST_OS_WINDOWS_MOBILE) && \ + !defined(GTEST_OS_WINDOWS_GAMES) && !defined(GTEST_OS_WINDOWS_PHONE) && \ + !defined(GTEST_OS_WINDOWS_RT) && !defined(GTEST_OS_WINDOWS_MINGW) const HANDLE stdout_handle = GetStdHandle(STD_OUTPUT_HANDLE); // Gets the current text color. |