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_
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"
20 namespace tracked_objects
{
24 namespace extensions
{
26 // This class represents an event that's expected to happen once. It
27 // allows clients to guarantee that code is run after the OneShotEvent
28 // is signaled. If the OneShotEvent is destroyed before it's
29 // signaled, the delayed closures are destroyed without being run.
31 // This class is similar to a WaitableEvent combined with several
32 // WaitableEventWatchers, but using it is simpler.
34 // This class is not thread-safe, and must be used from a single thread.
40 // True if Signal has been called. This function is mostly for
41 // migrating old code; usually calling Post() unconditionally will
42 // result in more readable code.
43 bool is_signaled() const {
44 DCHECK(thread_checker_
.CalledOnValidThread());
48 // Causes is_signaled() to return true and all queued tasks to be
49 // run in an arbitrary order. This method must only be called once.
52 // Scheduled |task| to be called on |runner| after is_signaled()
53 // becomes true. Inside |task|, if this OneShotEvent is still
54 // alive, CHECK(is_signaled()) will never fail (which implies that
55 // OneShotEvent::Reset() doesn't exist).
57 // If |*this| is destroyed before being released, none of these
58 // tasks will be executed.
60 // Omitting the |runner| argument indicates that |task| should run
61 // on MessageLoopProxy::current().
63 // Tasks may be run in an arbitrary order, not just FIFO. Tasks
64 // will never be called on the current thread before this function
65 // returns. Beware that there's no simple way to wait for all tasks
66 // on a OneShotEvent to complete, so it's almost never safe to use
67 // base::Unretained() when creating one.
69 // Const because Post() doesn't modify the logical state of this
70 // object (which is just the is_signaled() bit).
71 void Post(const tracked_objects::Location
& from_here
,
72 const base::Closure
& task
) const;
73 void Post(const tracked_objects::Location
& from_here
,
74 const base::Closure
& task
,
75 const scoped_refptr
<base::TaskRunner
>& runner
) const;
80 base::ThreadChecker thread_checker_
;
84 // The task list is mutable because it's not part of the logical
85 // state of the object. This lets us return const references to the
86 // OneShotEvent to clients that just want to run tasks through it
87 // without worrying that they'll signal the event.
89 // Optimization note: We could reduce the size of this class to a
90 // single pointer by storing |signaled_| in the low bit of a
91 // pointer, and storing the size and capacity of the array (if any)
92 // on the far end of the pointer.
93 mutable std::vector
<TaskInfo
> tasks_
;
96 } // namespace extensions
98 #endif // EXTENSIONS_COMMON_ONE_SHOT_EVENT_H_