Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(578)

Unified Diff: extensions/common/one_shot_event.h

Issue 14757022: Add a non-blocking "OneShotEvent" class (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Add a test for the behavior within a Post()ed callback Created 7 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « chrome/chrome_tests_unit.gypi ('k') | extensions/common/one_shot_event.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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_
« no previous file with comments | « chrome/chrome_tests_unit.gypi ('k') | extensions/common/one_shot_event.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698