Chromium Code Reviews| Index: extensions/common/one_shot_event.h |
| diff --git a/extensions/common/one_shot_event.h b/extensions/common/one_shot_event.h |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..cd993020613071857cd235ac8c439dc9704773ba |
| --- /dev/null |
| +++ b/extensions/common/one_shot_event.h |
| @@ -0,0 +1,98 @@ |
| +// Copyright (c) 2013 The Chromium Authors. All rights reserved. |
|
not at google - send to devlin
2013/05/16 15:51:08
I believe we leave out the (c) these days.
Jeffrey Yasskin
2013/05/16 19:05:36
If only I'd obeyed the style guide's rule to avoid
|
| +// Use of this source code is governed by a BSD-style license that can be |
| +// found in the LICENSE file. |
| + |
| +#ifndef EXTENSIONS_COMMON_ONE_SHOT_EVENT_H_ |
| +#define EXTENSIONS_COMMON_ONE_SHOT_EVENT_H_ |
| + |
| +#include <vector> |
| + |
| +#include "base/callback_forward.h" |
| +#include "base/logging.h" |
| +#include "base/memory/ref_counted.h" |
| +#include "base/memory/weak_ptr.h" |
| +#include "base/threading/thread_checker.h" |
| + |
| +namespace base { |
| +class TaskRunner; |
| +} |
| + |
| +namespace tracked_objects { |
| +class Location; |
| +} |
| + |
| +namespace extensions { |
| + |
| +// This class represents an event that's expected to happen once. It |
| +// allows clients to guarantee that code is run after the OneShotEvent |
| +// is signaled. If the OneShotEvent is destroyed before it's |
| +// signaled, the delayed closures are destroyed without being run. |
| +// |
| +// This class is similar to a WaitableEvent combined with several |
| +// WaitableEventWatchers, but using it is simpler. |
| +// |
| +// This class is not thread-safe, and must be used from a single thread. |
| +class OneShotEvent { |
| + public: |
| + OneShotEvent(); |
| + ~OneShotEvent(); |
| + |
| + // True if Signal has been called. This function is mostly for |
| + // migrating old code; using it in code designed for ThenRun() is |
| + // not recommended. |
| + bool is_signaled() const { |
| + DCHECK(thread_checker_.CalledOnValidThread()); |
| + return signaled_; |
| + } |
| + |
| + // Causes is_signaled() to return true and all queued tasks to be |
| + // run in an arbitrary order. This method must only be called once. |
| + void Signal(); |
| + |
| + // Scheduled |task| to be called on |runner| after is_signaled() |
| + // becomes true. Inside |task|, if this OneShotEvent is still |
| + // alive, CHECK(is_signaled()) will never fail (which implies that |
| + // OneShotEvent::Reset() doesn't exist). |
| + // |
| + // If |*this| is destroyed before being released, none of these |
| + // tasks will be executed. |
| + // |
| + // Omitting the |runner| argument indicates that |task| should run |
| + // on MessageLoopProxy::current(). |
| + // |
| + // Tasks may be run in an arbitrary order, not just FIFO. Tasks |
| + // will never be called on the current thread before this function |
| + // returns. Beware that there's no simple way to wait for all tasks |
| + // on a OneShotEvent to complete, so it's almost never safe to use |
| + // base::Unretained() when creating one. |
| + // |
| + // Const because ThenRun doesn't modify the logical state of this |
| + // object (which is just the is_signaled() bit). |
| + void ThenRun(const tracked_objects::Location& from_here, |
| + const base::Closure& task) const; |
| + void ThenRun(const tracked_objects::Location& from_here, |
| + const base::Closure& task, |
| + const scoped_refptr<base::TaskRunner>& runner) const; |
| + |
| + private: |
| + struct TaskInfo; |
| + |
| + base::ThreadChecker thread_checker_; |
| + |
| + bool signaled_; |
| + |
| + // The task list is mutable because it's not part of the logical |
| + // state of the object. This lets us return const references to the |
| + // OneShotEvent to clients that just want to run tasks through it |
| + // without worrying that they'll signal the event. |
| + // |
| + // Optimization note: We could reduce the size of this class to a |
| + // single pointer by storing |signaled_| in the low bit of a |
| + // pointer, and storing the size and capacity of the array (if any) |
| + // on the far end of the pointer. |
| + mutable std::vector<TaskInfo> tasks_; |
| +}; |
| + |
| +} // namespace extensions |
| + |
| +#endif // EXTENSIONS_COMMON_ONE_SHOT_EVENT_H_ |