Add an implmenetation of Notification for MinGW

Add an alternative implementation of the Notification class for MinGW
using a Windows manual-reset event object.

GCC version < 13 in MinGW, if configured with the win32 thread model
(with the --enable-threads=win32 configure option), does not implement
std::mutex and std::condition_variable in the <mutex> and
<condition_variable> headers. So the current implementation of the
Notification class, which uses std::mutex and std::condition_variable,
has compilation errors. Windows has a synchronization object called a
manual-reset event object that behaves just like the Notification class.
So we can easily implement the Notification class using a Windows
manual-reset event object.

This GCC issue is fixed in GCC 13. See
https://gcc.gnu.org/gcc-13/changes.html#windows. This alternative
implementation of Notification should be removed when GoogleTest
requires GCC version >= 13 in MinGW.

Fixes https://github.com/google/googletest/issues/4031 and
https://github.com/google/googletest/issues/4464.

PiperOrigin-RevId: 888752598
Change-Id: I69e01b2e7953e1fe72d87b6d0804c7a8a8d0e740
This commit is contained in:
Abseil Team
2026-03-24 10:53:03 -07:00
committed by Copybara-Service
parent f38004c441
commit 015950a936
2 changed files with 50 additions and 3 deletions
+34 -3
View File
@@ -1236,9 +1236,6 @@ class GTEST_API_ [[nodiscard]] AutoHandle {
// Nothing to do here.
#else
GTEST_DISABLE_MSC_WARNINGS_PUSH_(4251 \
/* class A needs to have dll-interface to be used by clients of class B */)
// 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.
@@ -1246,6 +1243,39 @@ GTEST_DISABLE_MSC_WARNINGS_PUSH_(4251 \
// 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.
#ifdef GTEST_OS_WINDOWS_MINGW
// GCC version < 13 with the win32 thread model does not provide std::mutex and
// std::condition_variable in the <mutex> and <condition_variable> headers. So
// we implement the Notification class using a Windows manual-reset event. See
// https://gcc.gnu.org/gcc-13/changes.html#windows.
class GTEST_API_ [[nodiscard]] Notification {
public:
Notification();
Notification(const Notification&) = delete;
Notification& operator=(const Notification&) = delete;
~Notification();
// Notifies all threads created with this notification to start. Must
// be called from the controller thread.
void Notify();
// Blocks until the controller thread notifies. Must be called from a test
// thread.
void WaitForNotification();
private:
// Assume that Win32 HANDLE type is equivalent to void*. Doing so allows us to
// avoid including <windows.h> in this header file. Including <windows.h> is
// undesirable because it defines a lot of symbols and macros that tend to
// conflict with client code. This assumption is verified by
// WindowsTypesTest.HANDLEIsVoidStar.
typedef void* Handle;
Handle event_;
};
#else
GTEST_DISABLE_MSC_WARNINGS_PUSH_(4251 \
/* class A needs to have dll-interface to be used by clients of class B */)
class GTEST_API_ [[nodiscard]] Notification {
public:
Notification() : notified_(false) {}
@@ -1273,6 +1303,7 @@ class GTEST_API_ [[nodiscard]] Notification {
bool notified_;
};
GTEST_DISABLE_MSC_WARNINGS_POP_() // 4251
#endif // GTEST_OS_WINDOWS_MINGW
#endif // GTEST_HAS_NOTIFICATION_
// On MinGW, we can have both GTEST_OS_WINDOWS and GTEST_HAS_PTHREAD
+16
View File
@@ -303,6 +303,22 @@ bool AutoHandle::IsCloseable() const {
return handle_ != nullptr && handle_ != INVALID_HANDLE_VALUE;
}
#if !GTEST_HAS_NOTIFICATION_ && defined(GTEST_OS_WINDOWS_MINGW)
Notification::Notification() {
// Create a manual-reset event object.
event_ = ::CreateEvent(nullptr, TRUE, FALSE, nullptr);
GTEST_CHECK_(event_ != nullptr);
}
Notification::~Notification() { ::CloseHandle(event_); }
void Notification::Notify() { GTEST_CHECK_(::SetEvent(event_)); }
void Notification::WaitForNotification() {
GTEST_CHECK_(::WaitForSingleObject(event_, INFINITE) == WAIT_OBJECT_0);
}
#endif // !GTEST_HAS_NOTIFICATION_ && defined(GTEST_OS_WINDOWS_MINGW)
Mutex::Mutex()
: owner_thread_id_(0),
type_(kDynamic),