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 BASE_ONE_SHOT_EVENT_H_
6 #define BASE_ONE_SHOT_EVENT_H_
7 
8 #include <vector>
9 
10 #include "base/callback_forward.h"
11 #include "base/check.h"
12 #include "base/memory/ref_counted.h"
13 #include "base/memory/weak_ptr.h"
14 #include "base/threading/thread_checker.h"
15 #include "base/threading/thread_task_runner_handle.h"
16 
17 namespace base {
18 
19 class Location;
20 class SingleThreadTaskRunner;
21 class TimeDelta;
22 
23 // This class represents an event that's expected to happen once.  It
24 // allows clients to guarantee that code is run after the OneShotEvent
25 // is signaled.  If the OneShotEvent is destroyed before it's
26 // signaled, the closures are destroyed without being run.
27 //
28 // This class is similar to a WaitableEvent combined with several
29 // WaitableEventWatchers, but using it is simpler.
30 //
31 // This class is not thread-safe, and must be used from a single thread.
32 class BASE_EXPORT OneShotEvent {
33  public:
34   OneShotEvent();
35   // Use the following constructor to create an already signaled event. This is
36   // useful if you construct the event on a different thread from where it is
37   // used, in which case it is not possible to call Signal() just after
38   // construction.
39   explicit OneShotEvent(bool signaled);
40   ~OneShotEvent();
41 
42   // True if Signal has been called.  This function is mostly for
43   // migrating old code; usually calling Post() unconditionally will
44   // result in more readable code.
is_signaled()45   bool is_signaled() const {
46     DCHECK(thread_checker_.CalledOnValidThread());
47     return signaled_;
48   }
49 
50   // Causes is_signaled() to return true and all tasks to be posted to their
51   // corresponding task runners in the FIFO order. Note that tasks posted to
52   // different SingleThreadTaskRunners may still execute in arbitrary order.
53   // This method must only be called once.
54   void Signal();
55 
56   // Scheduled |task| to be called on |runner| after is_signaled()
57   // becomes true. If called with |delay|, then the task will happen
58   // (roughly) |delay| after is_signaled(), *not* |delay| after the
59   // post. Inside |task|, if this OneShotEvent is still alive,
60   // CHECK(is_signaled()) will never fail (which implies that
61   // OneShotEvent::Reset() doesn't exist).
62   //
63   // If |*this| is destroyed before being released, none of these
64   // tasks will be executed.
65   //
66   // Tasks are posted in FIFO order, however, tasks posted to different
67   // SingleThreadTaskRunners may still execute in an arbitrary order. Tasks will
68   // never be called on the current thread before this function returns.  Beware
69   // that there's no simple way to wait for all tasks on a OneShotEvent to
70   // complete, so it's almost never safe to use base::Unretained() when creating
71   // one.
72   void Post(const Location& from_here,
73             OnceClosure task,
74             scoped_refptr<SingleThreadTaskRunner> runner =
75                 ThreadTaskRunnerHandle::Get()) const;
76   void PostDelayed(const Location& from_here,
77                    OnceClosure task,
78                    const TimeDelta& delay) const;
79 
80  private:
81   struct TaskInfo;
82 
83   void PostImpl(const Location& from_here,
84                 OnceClosure task,
85                 scoped_refptr<SingleThreadTaskRunner> runner,
86                 const TimeDelta& delay) const;
87 
88   ThreadChecker thread_checker_;
89 
90   bool signaled_;
91 
92   // The task list is mutable because it's not part of the logical
93   // state of the object.  This lets us return const references to the
94   // OneShotEvent to clients that just want to run tasks through it
95   // without worrying that they'll signal the event.
96   //
97   // Optimization note: We could reduce the size of this class to a
98   // single pointer by storing |signaled_| in the low bit of a
99   // pointer, and storing the size and capacity of the array (if any)
100   // on the far end of the pointer.
101   mutable std::vector<TaskInfo> tasks_;
102 };
103 
104 }  // namespace base
105 
106 #endif  // BASE_ONE_SHOT_EVENT_H_
107