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