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