1// Copyright 2013 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#ifndef MOJO_SYSTEM_WAITER_TEST_UTILS_H_ 6#define MOJO_SYSTEM_WAITER_TEST_UTILS_H_ 7 8#include "base/basictypes.h" 9#include "base/compiler_specific.h" 10#include "base/memory/ref_counted.h" 11#include "base/threading/simple_thread.h" 12#include "mojo/public/system/core.h" 13#include "mojo/system/dispatcher.h" 14#include "mojo/system/waiter.h" 15 16namespace mojo { 17namespace system { 18namespace test { 19 20// This is a very simple thread that has a |Waiter|, on which it waits 21// indefinitely (and records the result). It will create and initialize the 22// |Waiter| on creation, but the caller must start the thread with |Start()|. It 23// will join the thread on destruction. 24// 25// One usually uses it like: 26// 27// MojoResult result; 28// { 29// WaiterList waiter_list; 30// test::SimpleWaiterThread thread(&result); 31// waiter_list.AddWaiter(thread.waiter(), ...); 32// thread.Start(); 33// ... some stuff to wake the waiter ... 34// waiter_list.RemoveWaiter(thread.waiter()); 35// } // Join |thread|. 36// EXPECT_EQ(..., result); 37// 38// There's a bit of unrealism in its use: In this sort of usage, calls such as 39// |Waiter::Init()|, |AddWaiter()|, and |RemoveWaiter()| are done in the main 40// (test) thread, not the waiter thread (as would actually happen in real code). 41// (We accept this unrealism for simplicity, since |WaiterList| is 42// thread-unsafe so making it more realistic would require adding nontrivial 43// synchronization machinery.) 44class SimpleWaiterThread : public base::SimpleThread { 45 public: 46 // For the duration of the lifetime of this object, |*result| belongs to it 47 // (in the sense that it will write to it whenever it wants). 48 explicit SimpleWaiterThread(MojoResult* result); 49 virtual ~SimpleWaiterThread(); // Joins the thread. 50 51 Waiter* waiter() { return &waiter_; } 52 53 private: 54 virtual void Run() OVERRIDE; 55 56 MojoResult* const result_; 57 Waiter waiter_; 58 59 DISALLOW_COPY_AND_ASSIGN(SimpleWaiterThread); 60}; 61 62// This is a more complex and realistic thread that has a |Waiter|, on which it 63// waits for the given deadline (with the given flags). Unlike 64// |SimpleWaiterThread|, it requires the machinery of |Dispatcher|. 65class WaiterThread : public base::SimpleThread { 66 public: 67 // Note: |*did_wait_out| and |*result| belong to this object while it's alive. 68 WaiterThread(scoped_refptr<Dispatcher> dispatcher, 69 MojoWaitFlags wait_flags, 70 MojoDeadline deadline, 71 MojoResult success_result, 72 bool* did_wait_out, 73 MojoResult* result_out); 74 virtual ~WaiterThread(); 75 76 private: 77 virtual void Run() OVERRIDE; 78 79 const scoped_refptr<Dispatcher> dispatcher_; 80 const MojoWaitFlags wait_flags_; 81 const MojoDeadline deadline_; 82 const MojoResult success_result_; 83 bool* const did_wait_out_; 84 MojoResult* const result_out_; 85 86 Waiter waiter_; 87 88 DISALLOW_COPY_AND_ASSIGN(WaiterThread); 89}; 90 91} // namespace test 92} // namespace system 93} // namespace mojo 94 95#endif // MOJO_SYSTEM_WAITER_TEST_UTILS_H_ 96