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..17ab5c88f73133954f3d1b29335bcb11435d0f8a |
--- /dev/null |
+++ b/extensions/common/one_shot_event.h |
@@ -0,0 +1,98 @@ |
+// Copyright 2013 The Chromium Authors. All rights reserved. |
+// 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; usually calling Post() unconditionally will |
+ // result in more readable code. |
+ 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 Post() doesn't modify the logical state of this |
+ // object (which is just the is_signaled() bit). |
+ void Post(const tracked_objects::Location& from_here, |
+ const base::Closure& task) const; |
+ void Post(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_ |