waiter_test_utils.h revision 645501c2ab19a559ce82a1d5a29ced159a4c30fb
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
18namespace mojo {
19namespace edk {
20namespace 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.)
46class 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
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|.
68class 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