This source file includes following definitions.
- TEST
- TEST
- TEST
- TEST
#include "mojo/system/waiter_list.h"
#include "base/threading/platform_thread.h"
#include "base/time/time.h"
#include "mojo/system/waiter.h"
#include "mojo/system/waiter_test_utils.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace mojo {
namespace system {
namespace {
const int64_t kMicrosPerMs = 1000;
const int64_t kEpsilonMicros = 30 * kMicrosPerMs;
TEST(WaiterListTest, BasicCancel) {
MojoResult result;
{
WaiterList waiter_list;
test::SimpleWaiterThread thread(&result);
waiter_list.AddWaiter(thread.waiter(), MOJO_WAIT_FLAG_READABLE, 0);
thread.Start();
waiter_list.CancelAllWaiters();
waiter_list.RemoveWaiter(thread.waiter());
}
EXPECT_EQ(MOJO_RESULT_CANCELLED, result);
{
WaiterList waiter_list;
test::SimpleWaiterThread thread(&result);
waiter_list.AddWaiter(thread.waiter(), MOJO_WAIT_FLAG_WRITABLE, 1);
waiter_list.CancelAllWaiters();
thread.Start();
}
EXPECT_EQ(MOJO_RESULT_CANCELLED, result);
{
WaiterList waiter_list;
test::SimpleWaiterThread thread(&result);
waiter_list.AddWaiter(thread.waiter(), MOJO_WAIT_FLAG_READABLE, 2);
thread.Start();
base::PlatformThread::Sleep(
base::TimeDelta::FromMicroseconds(2 * kEpsilonMicros));
waiter_list.CancelAllWaiters();
}
EXPECT_EQ(MOJO_RESULT_CANCELLED, result);
}
TEST(WaiterListTest, BasicAwakeSatisfied) {
MojoResult result;
{
WaiterList waiter_list;
test::SimpleWaiterThread thread(&result);
waiter_list.AddWaiter(thread.waiter(), MOJO_WAIT_FLAG_READABLE, 0);
thread.Start();
waiter_list.AwakeWaitersForStateChange(MOJO_WAIT_FLAG_READABLE,
MOJO_WAIT_FLAG_READABLE |
MOJO_WAIT_FLAG_WRITABLE);
waiter_list.RemoveWaiter(thread.waiter());
}
EXPECT_EQ(0, result);
{
WaiterList waiter_list;
test::SimpleWaiterThread thread(&result);
waiter_list.AddWaiter(thread.waiter(), MOJO_WAIT_FLAG_WRITABLE, 1);
waiter_list.AwakeWaitersForStateChange(MOJO_WAIT_FLAG_WRITABLE,
MOJO_WAIT_FLAG_READABLE |
MOJO_WAIT_FLAG_WRITABLE);
waiter_list.RemoveWaiter(thread.waiter());
waiter_list.RemoveWaiter(thread.waiter());
thread.Start();
}
EXPECT_EQ(1, result);
{
WaiterList waiter_list;
test::SimpleWaiterThread thread(&result);
waiter_list.AddWaiter(thread.waiter(), MOJO_WAIT_FLAG_READABLE, 2);
thread.Start();
base::PlatformThread::Sleep(
base::TimeDelta::FromMicroseconds(2 * kEpsilonMicros));
waiter_list.AwakeWaitersForStateChange(MOJO_WAIT_FLAG_READABLE,
MOJO_WAIT_FLAG_READABLE |
MOJO_WAIT_FLAG_WRITABLE);
waiter_list.RemoveWaiter(thread.waiter());
}
EXPECT_EQ(2, result);
}
TEST(WaiterListTest, BasicAwakeUnsatisfiable) {
MojoResult result;
{
WaiterList waiter_list;
test::SimpleWaiterThread thread(&result);
waiter_list.AddWaiter(thread.waiter(), MOJO_WAIT_FLAG_READABLE, 0);
thread.Start();
waiter_list.AwakeWaitersForStateChange(0, MOJO_WAIT_FLAG_WRITABLE);
waiter_list.RemoveWaiter(thread.waiter());
}
EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, result);
{
WaiterList waiter_list;
test::SimpleWaiterThread thread(&result);
waiter_list.AddWaiter(thread.waiter(), MOJO_WAIT_FLAG_WRITABLE, 1);
waiter_list.AwakeWaitersForStateChange(MOJO_WAIT_FLAG_READABLE,
MOJO_WAIT_FLAG_READABLE);
waiter_list.RemoveWaiter(thread.waiter());
thread.Start();
}
EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, result);
{
WaiterList waiter_list;
test::SimpleWaiterThread thread(&result);
waiter_list.AddWaiter(thread.waiter(), MOJO_WAIT_FLAG_READABLE, 2);
thread.Start();
base::PlatformThread::Sleep(
base::TimeDelta::FromMicroseconds(2 * kEpsilonMicros));
waiter_list.AwakeWaitersForStateChange(0, MOJO_WAIT_FLAG_WRITABLE);
waiter_list.RemoveWaiter(thread.waiter());
waiter_list.RemoveWaiter(thread.waiter());
}
EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, result);
}
TEST(WaiterListTest, MultipleWaiters) {
MojoResult result1;
MojoResult result2;
MojoResult result3;
MojoResult result4;
{
WaiterList waiter_list;
test::SimpleWaiterThread thread1(&result1);
waiter_list.AddWaiter(thread1.waiter(), MOJO_WAIT_FLAG_READABLE, 0);
thread1.Start();
test::SimpleWaiterThread thread2(&result2);
waiter_list.AddWaiter(thread2.waiter(), MOJO_WAIT_FLAG_WRITABLE, 1);
thread2.Start();
base::PlatformThread::Sleep(
base::TimeDelta::FromMicroseconds(2 * kEpsilonMicros));
waiter_list.CancelAllWaiters();
}
EXPECT_EQ(MOJO_RESULT_CANCELLED, result1);
EXPECT_EQ(MOJO_RESULT_CANCELLED, result2);
{
WaiterList waiter_list;
test::SimpleWaiterThread thread1(&result1);
waiter_list.AddWaiter(thread1.waiter(), MOJO_WAIT_FLAG_READABLE, 2);
thread1.Start();
test::SimpleWaiterThread thread2(&result2);
waiter_list.AddWaiter(thread2.waiter(), MOJO_WAIT_FLAG_WRITABLE, 3);
thread2.Start();
base::PlatformThread::Sleep(
base::TimeDelta::FromMicroseconds(2 * kEpsilonMicros));
waiter_list.AwakeWaitersForStateChange(MOJO_WAIT_FLAG_READABLE,
MOJO_WAIT_FLAG_READABLE |
MOJO_WAIT_FLAG_WRITABLE);
waiter_list.RemoveWaiter(thread1.waiter());
waiter_list.CancelAllWaiters();
}
EXPECT_EQ(2, result1);
EXPECT_EQ(MOJO_RESULT_CANCELLED, result2);
{
WaiterList waiter_list;
test::SimpleWaiterThread thread1(&result1);
waiter_list.AddWaiter(thread1.waiter(), MOJO_WAIT_FLAG_READABLE, 4);
thread1.Start();
test::SimpleWaiterThread thread2(&result2);
waiter_list.AddWaiter(thread2.waiter(), MOJO_WAIT_FLAG_WRITABLE, 5);
thread2.Start();
base::PlatformThread::Sleep(
base::TimeDelta::FromMicroseconds(2 * kEpsilonMicros));
waiter_list.AwakeWaitersForStateChange(0, MOJO_WAIT_FLAG_READABLE);
waiter_list.RemoveWaiter(thread2.waiter());
waiter_list.CancelAllWaiters();
}
EXPECT_EQ(MOJO_RESULT_CANCELLED, result1);
EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, result2);
{
WaiterList waiter_list;
test::SimpleWaiterThread thread1(&result1);
waiter_list.AddWaiter(thread1.waiter(), MOJO_WAIT_FLAG_READABLE, 6);
thread1.Start();
base::PlatformThread::Sleep(
base::TimeDelta::FromMicroseconds(1 * kEpsilonMicros));
waiter_list.AwakeWaitersForStateChange(0,
MOJO_WAIT_FLAG_READABLE |
MOJO_WAIT_FLAG_WRITABLE);
test::SimpleWaiterThread thread2(&result2);
waiter_list.AddWaiter(thread2.waiter(), MOJO_WAIT_FLAG_WRITABLE, 7);
thread2.Start();
base::PlatformThread::Sleep(
base::TimeDelta::FromMicroseconds(1 * kEpsilonMicros));
waiter_list.AwakeWaitersForStateChange(MOJO_WAIT_FLAG_READABLE,
MOJO_WAIT_FLAG_READABLE |
MOJO_WAIT_FLAG_WRITABLE);
waiter_list.RemoveWaiter(thread1.waiter());
base::PlatformThread::Sleep(
base::TimeDelta::FromMicroseconds(1 * kEpsilonMicros));
test::SimpleWaiterThread thread3(&result3);
waiter_list.AddWaiter(thread3.waiter(), MOJO_WAIT_FLAG_WRITABLE, 8);
thread3.Start();
test::SimpleWaiterThread thread4(&result4);
waiter_list.AddWaiter(thread4.waiter(), MOJO_WAIT_FLAG_READABLE, 9);
thread4.Start();
base::PlatformThread::Sleep(
base::TimeDelta::FromMicroseconds(1 * kEpsilonMicros));
waiter_list.AwakeWaitersForStateChange(0, MOJO_WAIT_FLAG_READABLE);
waiter_list.RemoveWaiter(thread2.waiter());
waiter_list.RemoveWaiter(thread3.waiter());
waiter_list.CancelAllWaiters();
}
EXPECT_EQ(6, result1);
EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, result2);
EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, result3);
EXPECT_EQ(MOJO_RESULT_CANCELLED, result4);
}
}
}
}