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 <stdint.h> 9 10#include "base/compiler_specific.h" 11#include "base/macros.h" 12#include "base/memory/ref_counted.h" 13#include "base/threading/simple_thread.h" 14#include "mojo/public/c/system/types.h" 15#include "mojo/system/dispatcher.h" 16#include "mojo/system/handle_signals_state.h" 17#include "mojo/system/waiter.h" 18 19namespace mojo { 20namespace system { 21namespace test { 22 23// This is a very simple thread that has a |Waiter|, on which it waits 24// indefinitely (and records the result). It will create and initialize the 25// |Waiter| on creation, but the caller must start the thread with |Start()|. It 26// will join the thread on destruction. 27// 28// One usually uses it like: 29// 30// MojoResult result; 31// { 32// WaiterList waiter_list; 33// test::SimpleWaiterThread thread(&result); 34// waiter_list.AddWaiter(thread.waiter(), ...); 35// thread.Start(); 36// ... some stuff to wake the waiter ... 37// waiter_list.RemoveWaiter(thread.waiter()); 38// } // Join |thread|. 39// EXPECT_EQ(..., result); 40// 41// There's a bit of unrealism in its use: In this sort of usage, calls such as 42// |Waiter::Init()|, |AddWaiter()|, and |RemoveWaiter()| are done in the main 43// (test) thread, not the waiter thread (as would actually happen in real code). 44// (We accept this unrealism for simplicity, since |WaiterList| is 45// thread-unsafe so making it more realistic would require adding nontrivial 46// synchronization machinery.) 47class SimpleWaiterThread : public base::SimpleThread { 48 public: 49 // For the duration of the lifetime of this object, |*result| belongs to it 50 // (in the sense that it will write to it whenever it wants). 51 SimpleWaiterThread(MojoResult* result, uint32_t* context); 52 virtual ~SimpleWaiterThread(); // Joins the thread. 53 54 Waiter* waiter() { return &waiter_; } 55 56 private: 57 virtual void Run() OVERRIDE; 58 59 MojoResult* const result_; 60 uint32_t* const context_; 61 Waiter waiter_; 62 63 DISALLOW_COPY_AND_ASSIGN(SimpleWaiterThread); 64}; 65 66// This is a more complex and realistic thread that has a |Waiter|, on which it 67// waits for the given deadline (with the given flags). Unlike 68// |SimpleWaiterThread|, it requires the machinery of |Dispatcher|. 69class WaiterThread : public base::SimpleThread { 70 public: 71 // Note: |*did_wait_out|, |*result_out|, |*context_out| and 72 // |*signals_state_out| "belong" to this object (i.e., may be modified by, on 73 // some other thread) while it's alive. 74 WaiterThread(scoped_refptr<Dispatcher> dispatcher, 75 MojoHandleSignals handle_signals, 76 MojoDeadline deadline, 77 uint32_t context, 78 bool* did_wait_out, 79 MojoResult* result_out, 80 uint32_t* context_out, 81 HandleSignalsState* signals_state_out); 82 virtual ~WaiterThread(); 83 84 private: 85 virtual void Run() OVERRIDE; 86 87 const scoped_refptr<Dispatcher> dispatcher_; 88 const MojoHandleSignals handle_signals_; 89 const MojoDeadline deadline_; 90 const uint32_t context_; 91 bool* const did_wait_out_; 92 MojoResult* const result_out_; 93 uint32_t* const context_out_; 94 HandleSignalsState* const signals_state_out_; 95 96 Waiter waiter_; 97 98 DISALLOW_COPY_AND_ASSIGN(WaiterThread); 99}; 100 101} // namespace test 102} // namespace system 103} // namespace mojo 104 105#endif // MOJO_SYSTEM_WAITER_TEST_UTILS_H_ 106