14e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved. 24e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 34e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// found in the LICENSE file. 44e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 54e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// NOTE(vtl): These tests are inherently flaky (e.g., if run on a heavily-loaded 64e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// system). Sorry. |kEpsilonMicros| may be increased to increase tolerance and 74e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// reduce observed flakiness. 84e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 94e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "mojo/system/waiter.h" 104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 114e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "base/basictypes.h" 124e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "base/compiler_specific.h" 134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "base/synchronization/lock.h" 144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "base/threading/platform_thread.h" // For |Sleep()|. 154e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "base/threading/simple_thread.h" 164e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "base/time/time.h" 174e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "mojo/system/test_utils.h" 184e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h" 194e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 204e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)namespace mojo { 214e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)namespace system { 224e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)namespace { 234e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)const int64_t kMicrosPerMs = 1000; 254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)const int64_t kEpsilonMicros = 15 * kMicrosPerMs; // 15 ms. 264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)const int64_t kPollTimeMicros = 10 * kMicrosPerMs; // 10 ms. 274e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 284e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)class WaitingThread : public base::SimpleThread { 294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) public: 304e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) explicit WaitingThread(MojoDeadline deadline) 314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) : base::SimpleThread("waiting_thread"), 324e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) deadline_(deadline), 334e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) done_(false), 344e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) result_(MOJO_RESULT_UNKNOWN), 354e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) elapsed_micros_(-1) { 364e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) waiter_.Init(); 374e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 384e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 394e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) virtual ~WaitingThread() { 404e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) Join(); 414e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 424e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 434e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) void WaitUntilDone(MojoResult* result, int64_t* elapsed_micros) { 444e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) for (;;) { 454e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) { 464e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) base::AutoLock locker(lock_); 474e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (done_) { 484e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) *result = result_; 494e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) *elapsed_micros = elapsed_micros_; 504e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) break; 514e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 524e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 534e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 544e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) base::PlatformThread::Sleep( 554e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) base::TimeDelta::FromMicroseconds(kPollTimeMicros)); 564e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 574e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 584e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 594e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) Waiter* waiter() { return &waiter_; } 604e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 614e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) private: 624e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) virtual void Run() OVERRIDE { 634e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) test::Stopwatch stopwatch; 644e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) MojoResult result; 654e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) int64_t elapsed_micros; 664e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 674e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) stopwatch.Start(); 684e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) result = waiter_.Wait(deadline_); 694e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) elapsed_micros = stopwatch.Elapsed(); 704e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 714e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) { 724e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) base::AutoLock locker(lock_); 734e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) done_ = true; 744e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) result_ = result; 754e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) elapsed_micros_ = elapsed_micros; 764e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 774e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 784e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 794e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const MojoDeadline deadline_; 804e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) Waiter waiter_; // Thread-safe. 814e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 824e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) base::Lock lock_; // Protects the following members. 834e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) bool done_; 844e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) MojoResult result_; 854e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) int64_t elapsed_micros_; 864e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 874e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(WaitingThread); 884e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}; 894e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 904e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)TEST(WaiterTest, Basic) { 914e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) MojoResult result; 924e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) int64_t elapsed_micros; 934e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 944e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // Finite deadline. 954e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 964e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // Awake immediately after thread start. 974e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) { 984e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) WaitingThread thread(static_cast<MojoDeadline>(10 * kEpsilonMicros)); 994e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) thread.Start(); 1004e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) thread.waiter()->Awake(0); 1014e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) thread.WaitUntilDone(&result, &elapsed_micros); 1024e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) EXPECT_EQ(0, result); 1034e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) EXPECT_LT(elapsed_micros, kEpsilonMicros); 1044e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 1054e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1064e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // Awake before after thread start. 1074e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) { 1084e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) WaitingThread thread(static_cast<MojoDeadline>(10 * kEpsilonMicros)); 1094e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) thread.waiter()->Awake(MOJO_RESULT_CANCELLED); 1104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) thread.Start(); 1114e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) thread.WaitUntilDone(&result, &elapsed_micros); 1124e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) EXPECT_EQ(MOJO_RESULT_CANCELLED, result); 1134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) EXPECT_LT(elapsed_micros, kEpsilonMicros); 1144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 1154e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1164e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // Awake some time after thread start. 1174e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) { 1184e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) WaitingThread thread(static_cast<MojoDeadline>(10 * kEpsilonMicros)); 1194e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) thread.Start(); 1204e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) base::PlatformThread::Sleep( 1214e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) base::TimeDelta::FromMicroseconds(2 * kEpsilonMicros)); 1224e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) thread.waiter()->Awake(1); 1234e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) thread.WaitUntilDone(&result, &elapsed_micros); 1244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) EXPECT_EQ(1, result); 1254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) EXPECT_GT(elapsed_micros, (2-1) * kEpsilonMicros); 1264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) EXPECT_LT(elapsed_micros, (2+1) * kEpsilonMicros); 1274e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 1284e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // Awake some longer time after thread start. 1304e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) { 1314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) WaitingThread thread(static_cast<MojoDeadline>(10 * kEpsilonMicros)); 1324e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) thread.Start(); 1334e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) base::PlatformThread::Sleep( 1344e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) base::TimeDelta::FromMicroseconds(5 * kEpsilonMicros)); 1354e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) thread.waiter()->Awake(1); 1364e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) thread.WaitUntilDone(&result, &elapsed_micros); 1374e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) EXPECT_EQ(1, result); 1384e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) EXPECT_GT(elapsed_micros, (5-1) * kEpsilonMicros); 1394e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) EXPECT_LT(elapsed_micros, (5+1) * kEpsilonMicros); 1404e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 1414e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1424e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // Don't awake -- time out (on another thread). 1434e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) { 1444e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) WaitingThread thread(static_cast<MojoDeadline>(2 * kEpsilonMicros)); 1454e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) thread.Start(); 1464e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) thread.WaitUntilDone(&result, &elapsed_micros); 1474e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) EXPECT_EQ(MOJO_RESULT_DEADLINE_EXCEEDED, result); 1484e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) EXPECT_GT(elapsed_micros, (2-1) * kEpsilonMicros); 1494e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) EXPECT_LT(elapsed_micros, (2+1) * kEpsilonMicros); 1504e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 1514e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1524e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // No (indefinite) deadline. 1534e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1544e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // Awake immediately after thread start. 1554e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) { 1564e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) WaitingThread thread(MOJO_DEADLINE_INDEFINITE); 1574e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) thread.Start(); 1584e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) thread.waiter()->Awake(0); 1594e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) thread.WaitUntilDone(&result, &elapsed_micros); 1604e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) EXPECT_EQ(0, result); 1614e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) EXPECT_LT(elapsed_micros, kEpsilonMicros); 1624e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 1634e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1644e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // Awake before after thread start. 1654e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) { 1664e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) WaitingThread thread(MOJO_DEADLINE_INDEFINITE); 1674e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) thread.waiter()->Awake(MOJO_RESULT_CANCELLED); 1684e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) thread.Start(); 1694e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) thread.WaitUntilDone(&result, &elapsed_micros); 1704e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) EXPECT_EQ(MOJO_RESULT_CANCELLED, result); 1714e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) EXPECT_LT(elapsed_micros, kEpsilonMicros); 1724e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 1734e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1744e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // Awake some time after thread start. 1754e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) { 1764e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) WaitingThread thread(MOJO_DEADLINE_INDEFINITE); 1774e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) thread.Start(); 1784e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) base::PlatformThread::Sleep( 1794e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) base::TimeDelta::FromMicroseconds(2 * kEpsilonMicros)); 1804e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) thread.waiter()->Awake(1); 1814e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) thread.WaitUntilDone(&result, &elapsed_micros); 1824e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) EXPECT_EQ(1, result); 1834e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) EXPECT_GT(elapsed_micros, (2-1) * kEpsilonMicros); 1844e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) EXPECT_LT(elapsed_micros, (2+1) * kEpsilonMicros); 1854e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 1864e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1874e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // Awake some longer time after thread start. 1884e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) { 1894e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) WaitingThread thread(MOJO_DEADLINE_INDEFINITE); 1904e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) thread.Start(); 1914e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) base::PlatformThread::Sleep( 1924e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) base::TimeDelta::FromMicroseconds(5 * kEpsilonMicros)); 1934e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) thread.waiter()->Awake(1); 1944e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) thread.WaitUntilDone(&result, &elapsed_micros); 1954e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) EXPECT_EQ(1, result); 1964e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) EXPECT_GT(elapsed_micros, (5-1) * kEpsilonMicros); 1974e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) EXPECT_LT(elapsed_micros, (5+1) * kEpsilonMicros); 1984e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 1994e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 2004e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 2014e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)TEST(WaiterTest, TimeOut) { 2024e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) test::Stopwatch stopwatch; 2034e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) int64_t elapsed_micros; 2044e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 2054e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) Waiter waiter; 2064e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 2074e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) waiter.Init(); 2084e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) stopwatch.Start(); 2094e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) EXPECT_EQ(MOJO_RESULT_DEADLINE_EXCEEDED, waiter.Wait(0)); 2104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) elapsed_micros = stopwatch.Elapsed(); 2114e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) EXPECT_LT(elapsed_micros, kEpsilonMicros); 2124e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 2134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) waiter.Init(); 2144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) stopwatch.Start(); 2154e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) EXPECT_EQ(MOJO_RESULT_DEADLINE_EXCEEDED, 2164e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) waiter.Wait(static_cast<MojoDeadline>(2 * kEpsilonMicros))); 2174e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) elapsed_micros = stopwatch.Elapsed(); 2184e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) EXPECT_GT(elapsed_micros, (2-1) * kEpsilonMicros); 2194e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) EXPECT_LT(elapsed_micros, (2+1) * kEpsilonMicros); 2204e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 2214e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) waiter.Init(); 2224e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) stopwatch.Start(); 2234e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) EXPECT_EQ(MOJO_RESULT_DEADLINE_EXCEEDED, 2244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) waiter.Wait(static_cast<MojoDeadline>(5 * kEpsilonMicros))); 2254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) elapsed_micros = stopwatch.Elapsed(); 2264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) EXPECT_GT(elapsed_micros, (5-1) * kEpsilonMicros); 2274e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) EXPECT_LT(elapsed_micros, (5+1) * kEpsilonMicros); 2284e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 2294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 2304e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// The first |Awake()| should always win. 2314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)TEST(WaiterTest, MultipleAwakes) { 2324e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) MojoResult result; 2334e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) int64_t elapsed_micros; 2344e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 2354e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) { 2364e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) WaitingThread thread(MOJO_DEADLINE_INDEFINITE); 2374e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) thread.Start(); 2384e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) thread.waiter()->Awake(0); 2394e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) thread.waiter()->Awake(1); 2404e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) thread.WaitUntilDone(&result, &elapsed_micros); 2414e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) EXPECT_EQ(0, result); 2424e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) EXPECT_LT(elapsed_micros, kEpsilonMicros); 2434e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 2444e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 2454e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) { 2464e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) WaitingThread thread(MOJO_DEADLINE_INDEFINITE); 2474e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) thread.waiter()->Awake(1); 2484e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) thread.Start(); 2494e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) thread.waiter()->Awake(0); 2504e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) thread.WaitUntilDone(&result, &elapsed_micros); 2514e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) EXPECT_EQ(1, result); 2524e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) EXPECT_LT(elapsed_micros, kEpsilonMicros); 2534e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 2544e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 2554e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) { 2564e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) WaitingThread thread(MOJO_DEADLINE_INDEFINITE); 2574e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) thread.Start(); 2584e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) thread.waiter()->Awake(10); 2594e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) base::PlatformThread::Sleep( 2604e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) base::TimeDelta::FromMicroseconds(2 * kEpsilonMicros)); 2614e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) thread.waiter()->Awake(20); 2624e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) thread.WaitUntilDone(&result, &elapsed_micros); 2634e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) EXPECT_EQ(10, result); 2644e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) EXPECT_LT(elapsed_micros, kEpsilonMicros); 2654e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 2664e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 2674e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) { 2684e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) WaitingThread thread(static_cast<MojoDeadline>(10 * kEpsilonMicros)); 2694e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) thread.Start(); 2704e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) base::PlatformThread::Sleep( 2714e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) base::TimeDelta::FromMicroseconds(1 * kEpsilonMicros)); 2724e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) thread.waiter()->Awake(MOJO_RESULT_FAILED_PRECONDITION); 2734e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) base::PlatformThread::Sleep( 2744e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) base::TimeDelta::FromMicroseconds(2 * kEpsilonMicros)); 2754e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) thread.waiter()->Awake(0); 2764e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) thread.WaitUntilDone(&result, &elapsed_micros); 2774e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, result); 2784e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) EXPECT_GT(elapsed_micros, (1-1) * kEpsilonMicros); 2794e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) EXPECT_LT(elapsed_micros, (1+1) * kEpsilonMicros); 2804e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 2814e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 2824e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 2834e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} // namespace 2844e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} // namespace system 2854e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} // namespace mojo 286