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 19 namespace mojo { 20 namespace system { 21 namespace 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.) 47 class 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 waiter()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|. 69 class 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