• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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/waiter.h"
17 
18 namespace mojo {
19 namespace system {
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 //      WaiterList waiter_list;
32 //      test::SimpleWaiterThread thread(&result);
33 //      waiter_list.AddWaiter(thread.waiter(), ...);
34 //      thread.Start();
35 //      ... some stuff to wake the waiter ...
36 //      waiter_list.RemoveWaiter(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()|, |AddWaiter()|, and |RemoveWaiter()| are done in the main
42 // (test) thread, not the waiter thread (as would actually happen in real code).
43 // (We accept this unrealism for simplicity, since |WaiterList| 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, uint32_t* context);
51   virtual ~SimpleWaiterThread();  // Joins the thread.
52 
waiter()53   Waiter* waiter() { return &waiter_; }
54 
55  private:
56   virtual void Run() OVERRIDE;
57 
58   MojoResult* const result_;
59   uint32_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|, and |*context_out| "belong" to this
71   // object (i.e., may be modified by, on some other thread) while it's alive.
72   WaiterThread(scoped_refptr<Dispatcher> dispatcher,
73                MojoHandleSignals handle_signals,
74                MojoDeadline deadline,
75                uint32_t context,
76                bool* did_wait_out,
77                MojoResult* result_out,
78                uint32_t* context_out);
79   virtual ~WaiterThread();
80 
81  private:
82   virtual void Run() OVERRIDE;
83 
84   const scoped_refptr<Dispatcher> dispatcher_;
85   const MojoHandleSignals handle_signals_;
86   const MojoDeadline deadline_;
87   const uint32_t context_;
88   bool* const did_wait_out_;
89   MojoResult* const result_out_;
90   uint32_t* const context_out_;
91 
92   Waiter waiter_;
93 
94   DISALLOW_COPY_AND_ASSIGN(WaiterThread);
95 };
96 
97 }  // namespace test
98 }  // namespace system
99 }  // namespace mojo
100 
101 #endif  // MOJO_SYSTEM_WAITER_TEST_UTILS_H_
102