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
This commit is contained in:
dmauro 2021-10-25 10:54:43 -04:00 committed by CJ Johnson
parent 16f637fbf4
commit f503588aee
2 changed files with 35 additions and 77 deletions

View File

@ -274,12 +274,14 @@
# include <TargetConditionals.h>
#endif
#include <iostream> // NOLINT
#include <condition_variable> // NOLINT
#include <iostream>
#include <locale>
#include <memory>
#include <string> // NOLINT
#include <mutex> // NOLINT
#include <string>
#include <tuple>
#include <vector> // NOLINT
#include <vector>
#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<std::mutex> 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<std::mutex> 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_

View File

@ -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),