From f503588aeee4629e5673f2d88ddec01c9ed4bd6b Mon Sep 17 00:00:00 2001 From: dmauro Date: Mon, 25 Oct 2021 10:54:43 -0400 Subject: [PATCH] Googletest export Replace the multiple implementations of Notification with a single portable implementation. The also removes the awkward loop with sleep in Notification and will allow the removal of SleepMilliseconds. PiperOrigin-RevId: 405399733 --- .../include/gtest/internal/gtest-port.h | 95 +++++++------------ googletest/src/gtest-port.cc | 17 ---- 2 files changed, 35 insertions(+), 77 deletions(-) diff --git a/googletest/include/gtest/internal/gtest-port.h b/googletest/include/gtest/internal/gtest-port.h index d3eab57b..de00483d 100644 --- a/googletest/include/gtest/internal/gtest-port.h +++ b/googletest/include/gtest/internal/gtest-port.h @@ -274,12 +274,14 @@ # include #endif -#include // NOLINT +#include // NOLINT +#include #include #include -#include // NOLINT +#include // NOLINT +#include #include -#include // NOLINT +#include #include "gtest/internal/custom/gtest-port.h" #include "gtest/internal/gtest-port-arch.h" @@ -1172,58 +1174,8 @@ inline void SleepMilliseconds(int n) { }; nanosleep(&time, nullptr); } -# endif // GTEST_HAS_PTHREAD - -# if GTEST_HAS_NOTIFICATION_ -// Notification has already been imported into the namespace. -// Nothing to do here. - -# elif GTEST_HAS_PTHREAD -// Allows a controller thread to pause execution of newly created -// threads until notified. Instances of this class must be created -// and destroyed in the controller thread. -// -// This class is only for testing Google Test's own constructs. Do not -// use it in user tests, either directly or indirectly. -class Notification { - public: - Notification() : notified_(false) { - GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_init(&mutex_, nullptr)); - } - ~Notification() { - pthread_mutex_destroy(&mutex_); - } - - // Notifies all threads created with this notification to start. Must - // be called from the controller thread. - void Notify() { - pthread_mutex_lock(&mutex_); - notified_ = true; - pthread_mutex_unlock(&mutex_); - } - - // Blocks until the controller thread notifies. Must be called from a test - // thread. - void WaitForNotification() { - for (;;) { - pthread_mutex_lock(&mutex_); - const bool notified = notified_; - pthread_mutex_unlock(&mutex_); - if (notified) - break; - SleepMilliseconds(10); - } - } - - private: - pthread_mutex_t mutex_; - bool notified_; - - GTEST_DISALLOW_COPY_AND_ASSIGN_(Notification); -}; - -# elif GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_PHONE && !GTEST_OS_WINDOWS_RT +# elif GTEST_OS_WINDOWS GTEST_API_ void SleepMilliseconds(int n); // Provides leak-safe Windows kernel handle ownership. @@ -1255,22 +1207,45 @@ class GTEST_API_ AutoHandle { GTEST_DISALLOW_COPY_AND_ASSIGN_(AutoHandle); }; +# endif + +# if GTEST_HAS_NOTIFICATION_ +// Notification has already been imported into the namespace. +// Nothing to do here. + +# else // Allows a controller thread to pause execution of newly created // threads until notified. Instances of this class must be created // and destroyed in the controller thread. // // This class is only for testing Google Test's own constructs. Do not // use it in user tests, either directly or indirectly. +// TODO(b/203539622): Replace unconditionally with absl::Notification. class GTEST_API_ Notification { public: - Notification(); - void Notify(); - void WaitForNotification(); + Notification() : notified_(false) {} + Notification(const Notification&) = delete; + Notification& operator=(const Notification&) = delete; + + // Notifies all threads created with this notification to start. Must + // be called from the controller thread. + void Notify() { + std::lock_guard lock(mu_); + notified_ = true; + cv_.notify_all(); + } + + // Blocks until the controller thread notifies. Must be called from a test + // thread. + void WaitForNotification() { + std::unique_lock lock(mu_); + cv_.wait(lock, [this]() { return notified_; }); + } private: - AutoHandle event_; - - GTEST_DISALLOW_COPY_AND_ASSIGN_(Notification); + std::mutex mu_; + std::condition_variable cv_; + bool notified_; }; # endif // GTEST_HAS_NOTIFICATION_ diff --git a/googletest/src/gtest-port.cc b/googletest/src/gtest-port.cc index c3c93e61..6faa8b90 100644 --- a/googletest/src/gtest-port.cc +++ b/googletest/src/gtest-port.cc @@ -322,23 +322,6 @@ bool AutoHandle::IsCloseable() const { return handle_ != nullptr && handle_ != INVALID_HANDLE_VALUE; } -Notification::Notification() - : event_(::CreateEvent(nullptr, // Default security attributes. - TRUE, // Do not reset automatically. - FALSE, // Initially unset. - nullptr)) { // Anonymous event. - GTEST_CHECK_(event_.Get() != nullptr); -} - -void Notification::Notify() { - GTEST_CHECK_(::SetEvent(event_.Get()) != FALSE); -} - -void Notification::WaitForNotification() { - GTEST_CHECK_( - ::WaitForSingleObject(event_.Get(), INFINITE) == WAIT_OBJECT_0); -} - Mutex::Mutex() : owner_thread_id_(0), type_(kDynamic),