Commit f503588a authored by dmauro's avatar dmauro Committed by CJ Johnson
Browse files

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
parent 16f637fb
......@@ -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;
private:
AutoHandle event_;
// 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();
}
GTEST_DISALLOW_COPY_AND_ASSIGN_(Notification);
// 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:
std::mutex mu_;
std::condition_variable cv_;
bool notified_;
};
# endif // GTEST_HAS_NOTIFICATION_
......
......@@ -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),
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment