190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved. 290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// found in the LICENSE file. 490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#ifndef EXTENSIONS_COMMON_ONE_SHOT_EVENT_H_ 690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#define EXTENSIONS_COMMON_ONE_SHOT_EVENT_H_ 790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include <vector> 990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 1090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "base/callback_forward.h" 1190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "base/logging.h" 1290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "base/memory/ref_counted.h" 1390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "base/memory/weak_ptr.h" 1490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "base/threading/thread_checker.h" 1590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 1690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)namespace base { 1790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)class TaskRunner; 18e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdochclass TimeDelta; 1990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 2090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 2190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)namespace tracked_objects { 2290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)class Location; 2390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 2490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 2590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)namespace extensions { 2690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 2790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// This class represents an event that's expected to happen once. It 2890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// allows clients to guarantee that code is run after the OneShotEvent 2990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// is signaled. If the OneShotEvent is destroyed before it's 3090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// signaled, the delayed closures are destroyed without being run. 3190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// 3290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// This class is similar to a WaitableEvent combined with several 3390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// WaitableEventWatchers, but using it is simpler. 3490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// 3590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// This class is not thread-safe, and must be used from a single thread. 3690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)class OneShotEvent { 3790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) public: 3890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) OneShotEvent(); 395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Use the following constructor to create an already signaled event. This is 405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // useful if you construct the event on a different thread from where it is 415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // used, in which case it is not possible to call Signal() just after 425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // construction. 435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) explicit OneShotEvent(bool signaled); 4490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) ~OneShotEvent(); 4590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 4690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // True if Signal has been called. This function is mostly for 4790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // migrating old code; usually calling Post() unconditionally will 4890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // result in more readable code. 4990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) bool is_signaled() const { 5090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) DCHECK(thread_checker_.CalledOnValidThread()); 5190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return signaled_; 5290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 5390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 5490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Causes is_signaled() to return true and all queued tasks to be 5590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // run in an arbitrary order. This method must only be called once. 5690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) void Signal(); 5790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 5890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Scheduled |task| to be called on |runner| after is_signaled() 59e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch // becomes true. If called with |delay|, then the task will happen 60e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch // (roughly) |delay| after is_signaled(), *not* |delay| after the 61e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch // post. Inside |task|, if this OneShotEvent is still alive, 62e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch // CHECK(is_signaled()) will never fail (which implies that 6390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // OneShotEvent::Reset() doesn't exist). 6490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // 6590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // If |*this| is destroyed before being released, none of these 6690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // tasks will be executed. 6790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // 6890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Omitting the |runner| argument indicates that |task| should run 6990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // on MessageLoopProxy::current(). 7090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // 7190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Tasks may be run in an arbitrary order, not just FIFO. Tasks 7290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // will never be called on the current thread before this function 7390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // returns. Beware that there's no simple way to wait for all tasks 7490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // on a OneShotEvent to complete, so it's almost never safe to use 7590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // base::Unretained() when creating one. 7690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // 7790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Const because Post() doesn't modify the logical state of this 7890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // object (which is just the is_signaled() bit). 7990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) void Post(const tracked_objects::Location& from_here, 8090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const base::Closure& task) const; 8190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) void Post(const tracked_objects::Location& from_here, 8290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const base::Closure& task, 8390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const scoped_refptr<base::TaskRunner>& runner) const; 84e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch void PostDelayed(const tracked_objects::Location& from_here, 85e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch const base::Closure& task, 86e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch const base::TimeDelta& delay) const; 8790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 8890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) private: 8990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) struct TaskInfo; 9090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 91e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch void PostImpl(const tracked_objects::Location& from_here, 92e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch const base::Closure& task, 93e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch const scoped_refptr<base::TaskRunner>& runner, 94e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch const base::TimeDelta& delay) const; 95e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 9690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::ThreadChecker thread_checker_; 9790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 9890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) bool signaled_; 9990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 10090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // The task list is mutable because it's not part of the logical 10190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // state of the object. This lets us return const references to the 10290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // OneShotEvent to clients that just want to run tasks through it 10390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // without worrying that they'll signal the event. 10490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // 10590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Optimization note: We could reduce the size of this class to a 10690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // single pointer by storing |signaled_| in the low bit of a 10790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // pointer, and storing the size and capacity of the array (if any) 10890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // on the far end of the pointer. 10990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) mutable std::vector<TaskInfo> tasks_; 11090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}; 11190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 11290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} // namespace extensions 11390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 11490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#endif // EXTENSIONS_COMMON_ONE_SHOT_EVENT_H_ 115