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:
parent
16f637fbf4
commit
f503588aee
@ -274,12 +274,14 @@
|
|||||||
# include <TargetConditionals.h>
|
# include <TargetConditionals.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <iostream> // NOLINT
|
#include <condition_variable> // NOLINT
|
||||||
|
#include <iostream>
|
||||||
#include <locale>
|
#include <locale>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <string> // NOLINT
|
#include <mutex> // NOLINT
|
||||||
|
#include <string>
|
||||||
#include <tuple>
|
#include <tuple>
|
||||||
#include <vector> // NOLINT
|
#include <vector>
|
||||||
|
|
||||||
#include "gtest/internal/custom/gtest-port.h"
|
#include "gtest/internal/custom/gtest-port.h"
|
||||||
#include "gtest/internal/gtest-port-arch.h"
|
#include "gtest/internal/gtest-port-arch.h"
|
||||||
@ -1172,58 +1174,8 @@ inline void SleepMilliseconds(int n) {
|
|||||||
};
|
};
|
||||||
nanosleep(&time, nullptr);
|
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);
|
GTEST_API_ void SleepMilliseconds(int n);
|
||||||
|
|
||||||
// Provides leak-safe Windows kernel handle ownership.
|
// Provides leak-safe Windows kernel handle ownership.
|
||||||
@ -1255,22 +1207,45 @@ class GTEST_API_ AutoHandle {
|
|||||||
GTEST_DISALLOW_COPY_AND_ASSIGN_(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
|
// Allows a controller thread to pause execution of newly created
|
||||||
// threads until notified. Instances of this class must be created
|
// threads until notified. Instances of this class must be created
|
||||||
// and destroyed in the controller thread.
|
// and destroyed in the controller thread.
|
||||||
//
|
//
|
||||||
// This class is only for testing Google Test's own constructs. Do not
|
// This class is only for testing Google Test's own constructs. Do not
|
||||||
// use it in user tests, either directly or indirectly.
|
// use it in user tests, either directly or indirectly.
|
||||||
|
// TODO(b/203539622): Replace unconditionally with absl::Notification.
|
||||||
class GTEST_API_ Notification {
|
class GTEST_API_ Notification {
|
||||||
public:
|
public:
|
||||||
Notification();
|
Notification() : notified_(false) {}
|
||||||
void Notify();
|
Notification(const Notification&) = delete;
|
||||||
void WaitForNotification();
|
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:
|
private:
|
||||||
AutoHandle event_;
|
std::mutex mu_;
|
||||||
|
std::condition_variable cv_;
|
||||||
GTEST_DISALLOW_COPY_AND_ASSIGN_(Notification);
|
bool notified_;
|
||||||
};
|
};
|
||||||
# endif // GTEST_HAS_NOTIFICATION_
|
# endif // GTEST_HAS_NOTIFICATION_
|
||||||
|
|
||||||
|
@ -322,23 +322,6 @@ bool AutoHandle::IsCloseable() const {
|
|||||||
return handle_ != nullptr && handle_ != INVALID_HANDLE_VALUE;
|
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()
|
Mutex::Mutex()
|
||||||
: owner_thread_id_(0),
|
: owner_thread_id_(0),
|
||||||
type_(kDynamic),
|
type_(kDynamic),
|
||||||
|
Loading…
Reference in New Issue
Block a user