mirror of
https://github.com/google/googletest.git
synced 2026-07-21 14:43:35 +00:00
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:
committed by
Copybara-Service
parent
f38004c441
commit
015950a936
@@ -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
|
||||
|
||||
@@ -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),
|
||||
|
||||
Reference in New Issue
Block a user