one_shot_event.cc revision 868fa2fe829687343ffae624259930155e16dbd8
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)#include "extensions/common/one_shot_event.h" 690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "base/callback.h" 890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "base/location.h" 990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "base/message_loop/message_loop_proxy.h" 1090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "base/task_runner.h" 1190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 1290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)using base::TaskRunner; 1390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 1490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)namespace extensions { 1590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 1690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)struct OneShotEvent::TaskInfo { 1790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) TaskInfo() {} 1890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) TaskInfo(const tracked_objects::Location& from_here, 1990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const scoped_refptr<TaskRunner>& runner, 2090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const base::Closure& task) 2190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) : from_here(from_here), runner(runner), task(task) { 22868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) CHECK(runner.get()); // Detect mistakes with a decent stack frame. 2390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 2490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) tracked_objects::Location from_here; 2590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) scoped_refptr<TaskRunner> runner; 2690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::Closure task; 2790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}; 2890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 2990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)OneShotEvent::OneShotEvent() : signaled_(false) { 3090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // It's acceptable to construct the OneShotEvent on one thread, but 3190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // immediately move it to another thread. 3290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) thread_checker_.DetachFromThread(); 3390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 3490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)OneShotEvent::~OneShotEvent() {} 3590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 3690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void OneShotEvent::Post(const tracked_objects::Location& from_here, 3790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const base::Closure& task) const { 3890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) Post(from_here, task, base::MessageLoopProxy::current()); 3990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 4090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 4190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void OneShotEvent::Post(const tracked_objects::Location& from_here, 4290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const base::Closure& task, 4390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const scoped_refptr<TaskRunner>& runner) const { 4490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) DCHECK(thread_checker_.CalledOnValidThread()); 4590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 4690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (is_signaled()) { 4790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) runner->PostTask(from_here, task); 4890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } else { 4990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) tasks_.push_back(TaskInfo(from_here, runner, task)); 5090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 5190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 5290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 5390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void OneShotEvent::Signal() { 5490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) DCHECK(thread_checker_.CalledOnValidThread()); 5590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 5690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) CHECK(!signaled_) << "Only call Signal once."; 5790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 5890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) signaled_ = true; 5990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // After this point, a call to Post() from one of the queued tasks 6090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // could proceed immediately, but the fact that this object is 6190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // single-threaded prevents that from being relevant. 6290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 6390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // We could randomize tasks_ in debug mode in order to check that 6490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // the order doesn't matter... 6590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) for (size_t i = 0; i < tasks_.size(); ++i) { 6690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) tasks_[i].runner->PostTask(tasks_[i].from_here, tasks_[i].task); 6790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 6890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 6990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 7090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} // namespace extensions 71