1a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo// Copyright 2015 The Chromium OS Authors. All rights reserved. 2a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo// Use of this source code is governed by a BSD-style license that can be 3a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo// found in the LICENSE file. 4a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo 59ed0cab99f18acb3570a35e9408f24355f6b8324Alex Vakulenko#include <brillo/message_loops/base_message_loop.h> 6a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo 7a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo#include <fcntl.h> 8d671746a66d87edf9598cfbe077b3430e50a09d3Alex Deymo#include <sys/stat.h> 9d671746a66d87edf9598cfbe077b3430e50a09d3Alex Deymo#include <sys/types.h> 10a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo#include <unistd.h> 11a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo 129471399027d4a8e0ef5e1a68429b2e9e93a31e96Elliott Hughes#ifndef __APPLE__ 139471399027d4a8e0ef5e1a68429b2e9e93a31e96Elliott Hughes#include <sys/sysmacros.h> 149471399027d4a8e0ef5e1a68429b2e9e93a31e96Elliott Hughes#endif 159471399027d4a8e0ef5e1a68429b2e9e93a31e96Elliott Hughes 1677edc5357e1ff2c507a07d4c97f943910609ee44Alex Deymo#ifndef __ANDROID_HOST__ 1777edc5357e1ff2c507a07d4c97f943910609ee44Alex Deymo// Used for MISC_MAJOR. Only required for the target and not always available 1877edc5357e1ff2c507a07d4c97f943910609ee44Alex Deymo// for the host. 1977edc5357e1ff2c507a07d4c97f943910609ee44Alex Deymo#include <linux/major.h> 2077edc5357e1ff2c507a07d4c97f943910609ee44Alex Deymo#endif 2177edc5357e1ff2c507a07d4c97f943910609ee44Alex Deymo 22d671746a66d87edf9598cfbe077b3430e50a09d3Alex Deymo#include <vector> 23d671746a66d87edf9598cfbe077b3430e50a09d3Alex Deymo 24a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo#include <base/bind.h> 25d671746a66d87edf9598cfbe077b3430e50a09d3Alex Deymo#include <base/files/file_path.h> 26d671746a66d87edf9598cfbe077b3430e50a09d3Alex Deymo#include <base/files/file_util.h> 2730ef318cd1d94e896a277324c68b89798e3dbbddAlex Deymo#include <base/run_loop.h> 28d671746a66d87edf9598cfbe077b3430e50a09d3Alex Deymo#include <base/strings/string_number_conversions.h> 29d671746a66d87edf9598cfbe077b3430e50a09d3Alex Deymo#include <base/strings/string_split.h> 30a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo 319ed0cab99f18acb3570a35e9408f24355f6b8324Alex Vakulenko#include <brillo/location_logging.h> 32d671746a66d87edf9598cfbe077b3430e50a09d3Alex Deymo#include <brillo/strings/string_utils.h> 33a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo 34a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymousing base::Closure; 35a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo 36d671746a66d87edf9598cfbe077b3430e50a09d3Alex Deymonamespace { 37d671746a66d87edf9598cfbe077b3430e50a09d3Alex Deymo 38d671746a66d87edf9598cfbe077b3430e50a09d3Alex Deymoconst char kMiscMinorPath[] = "/proc/misc"; 39d671746a66d87edf9598cfbe077b3430e50a09d3Alex Deymoconst char kBinderDriverName[] = "binder"; 40d671746a66d87edf9598cfbe077b3430e50a09d3Alex Deymo 41d671746a66d87edf9598cfbe077b3430e50a09d3Alex Deymo} // namespace 42d671746a66d87edf9598cfbe077b3430e50a09d3Alex Deymo 439ed0cab99f18acb3570a35e9408f24355f6b8324Alex Vakulenkonamespace brillo { 44a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo 45d671746a66d87edf9598cfbe077b3430e50a09d3Alex Deymoconst int BaseMessageLoop::kInvalidMinor = -1; 46d671746a66d87edf9598cfbe077b3430e50a09d3Alex Deymoconst int BaseMessageLoop::kUninitializedMinor = -2; 47d671746a66d87edf9598cfbe077b3430e50a09d3Alex Deymo 48922d235dca34496fd30e1b15b2bf24b4a6949288Alex DeymoBaseMessageLoop::BaseMessageLoop() { 49ef47c404abf9c2e482c2381d991f45ca23d62beeAlex Deymo CHECK(!base::MessageLoop::current()) 50ef47c404abf9c2e482c2381d991f45ca23d62beeAlex Deymo << "You can't create a base::MessageLoopForIO when another " 51ef47c404abf9c2e482c2381d991f45ca23d62beeAlex Deymo "base::MessageLoop is already created for this thread."; 52922d235dca34496fd30e1b15b2bf24b4a6949288Alex Deymo owned_base_loop_.reset(new base::MessageLoopForIO); 53922d235dca34496fd30e1b15b2bf24b4a6949288Alex Deymo base_loop_ = owned_base_loop_.get(); 54922d235dca34496fd30e1b15b2bf24b4a6949288Alex Deymo} 55922d235dca34496fd30e1b15b2bf24b4a6949288Alex Deymo 56a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex DeymoBaseMessageLoop::BaseMessageLoop(base::MessageLoopForIO* base_loop) 57922d235dca34496fd30e1b15b2bf24b4a6949288Alex Deymo : base_loop_(base_loop) {} 58a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo 59a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex DeymoBaseMessageLoop::~BaseMessageLoop() { 60a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo for (auto& io_task : io_tasks_) { 61a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo DVLOG_LOC(io_task.second.location(), 1) 62a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo << "Removing file descriptor watcher task_id " << io_task.first 63a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo << " leaked on BaseMessageLoop, scheduled from this location."; 6407c1779e51680364060f3ec289249869ac7bc5caAlex Deymo io_task.second.StopWatching(); 65a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo } 66a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo 67a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo // Note all pending canceled delayed tasks when destroying the message loop. 68a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo size_t lazily_deleted_tasks = 0; 69a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo for (const auto& delayed_task : delayed_tasks_) { 70a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo if (delayed_task.second.closure.is_null()) { 71a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo lazily_deleted_tasks++; 72a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo } else { 73a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo DVLOG_LOC(delayed_task.second.location, 1) 74a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo << "Removing delayed task_id " << delayed_task.first 75a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo << " leaked on BaseMessageLoop, scheduled from this location."; 76a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo } 77a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo } 78a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo if (lazily_deleted_tasks) { 79a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo LOG(INFO) << "Leaking " << lazily_deleted_tasks << " canceled tasks."; 80a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo } 81a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo} 82a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo 83a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex DeymoMessageLoop::TaskId BaseMessageLoop::PostDelayedTask( 84a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo const tracked_objects::Location& from_here, 85a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo const Closure &task, 86a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo base::TimeDelta delay) { 87a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo TaskId task_id = NextTaskId(); 88a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo bool base_scheduled = base_loop_->task_runner()->PostDelayedTask( 89a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo from_here, 90a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo base::Bind(&BaseMessageLoop::OnRanPostedTask, 91a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo weak_ptr_factory_.GetWeakPtr(), 92a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo task_id), 93a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo delay); 94a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo DVLOG_LOC(from_here, 1) << "Scheduling delayed task_id " << task_id 95a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo << " to run in " << delay << "."; 96a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo if (!base_scheduled) 97a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo return MessageLoop::kTaskIdNull; 98a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo 99a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo delayed_tasks_.emplace(task_id, 100a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo DelayedTask{from_here, task_id, std::move(task)}); 101a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo return task_id; 102a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo} 103a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo 104a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex DeymoMessageLoop::TaskId BaseMessageLoop::WatchFileDescriptor( 105a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo const tracked_objects::Location& from_here, 106a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo int fd, 107a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo WatchMode mode, 108a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo bool persistent, 109a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo const Closure &task) { 110a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo // base::MessageLoopForIO CHECKS that "fd >= 0", so we handle that case here. 111a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo if (fd < 0) 112a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo return MessageLoop::kTaskIdNull; 113a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo 114a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo base::MessageLoopForIO::Mode base_mode = base::MessageLoopForIO::WATCH_READ; 115a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo switch (mode) { 116a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo case MessageLoop::kWatchRead: 117a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo base_mode = base::MessageLoopForIO::WATCH_READ; 118a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo break; 119a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo case MessageLoop::kWatchWrite: 120a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo base_mode = base::MessageLoopForIO::WATCH_WRITE; 121a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo break; 122a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo default: 123a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo return MessageLoop::kTaskIdNull; 124a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo } 125a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo 126a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo TaskId task_id = NextTaskId(); 127a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo auto it_bool = io_tasks_.emplace( 128a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo std::piecewise_construct, 129a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo std::forward_as_tuple(task_id), 13007c1779e51680364060f3ec289249869ac7bc5caAlex Deymo std::forward_as_tuple( 13107c1779e51680364060f3ec289249869ac7bc5caAlex Deymo from_here, this, task_id, fd, base_mode, persistent, task)); 132a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo // This should always insert a new element. 133a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo DCHECK(it_bool.second); 13407c1779e51680364060f3ec289249869ac7bc5caAlex Deymo bool scheduled = it_bool.first->second.StartWatching(); 135a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo DVLOG_LOC(from_here, 1) 136a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo << "Watching fd " << fd << " for " 137a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo << (mode == MessageLoop::kWatchRead ? "reading" : "writing") 138a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo << (persistent ? " persistently" : " just once") 139a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo << " as task_id " << task_id 140a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo << (scheduled ? " successfully" : " failed."); 141a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo 142a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo if (!scheduled) { 143a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo io_tasks_.erase(task_id); 144a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo return MessageLoop::kTaskIdNull; 145a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo } 146d671746a66d87edf9598cfbe077b3430e50a09d3Alex Deymo 14777edc5357e1ff2c507a07d4c97f943910609ee44Alex Deymo#ifndef __ANDROID_HOST__ 148d671746a66d87edf9598cfbe077b3430e50a09d3Alex Deymo // Determine if the passed fd is the binder file descriptor. For that, we need 149d671746a66d87edf9598cfbe077b3430e50a09d3Alex Deymo // to check that is a special char device and that the major and minor device 150d671746a66d87edf9598cfbe077b3430e50a09d3Alex Deymo // numbers match. The binder file descriptor can't be removed and added back 151d671746a66d87edf9598cfbe077b3430e50a09d3Alex Deymo // to an epoll group when there's work available to be done by the file 152d671746a66d87edf9598cfbe077b3430e50a09d3Alex Deymo // descriptor due to bugs in the binder driver (b/26524111) when used with 153d671746a66d87edf9598cfbe077b3430e50a09d3Alex Deymo // epoll. Therefore, we flag the binder fd and never attempt to remove it. 154d671746a66d87edf9598cfbe077b3430e50a09d3Alex Deymo // This may cause the binder file descriptor to be attended with higher 155d671746a66d87edf9598cfbe077b3430e50a09d3Alex Deymo // priority and cause starvation of other events. 156d671746a66d87edf9598cfbe077b3430e50a09d3Alex Deymo struct stat buf; 157d671746a66d87edf9598cfbe077b3430e50a09d3Alex Deymo if (fstat(fd, &buf) == 0 && 158d671746a66d87edf9598cfbe077b3430e50a09d3Alex Deymo S_ISCHR(buf.st_mode) && 159d671746a66d87edf9598cfbe077b3430e50a09d3Alex Deymo major(buf.st_rdev) == MISC_MAJOR && 160d671746a66d87edf9598cfbe077b3430e50a09d3Alex Deymo minor(buf.st_rdev) == GetBinderMinor()) { 161d671746a66d87edf9598cfbe077b3430e50a09d3Alex Deymo it_bool.first->second.RunImmediately(); 162d671746a66d87edf9598cfbe077b3430e50a09d3Alex Deymo } 16377edc5357e1ff2c507a07d4c97f943910609ee44Alex Deymo#endif 164d671746a66d87edf9598cfbe077b3430e50a09d3Alex Deymo 165a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo return task_id; 166a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo} 167a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo 168a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymobool BaseMessageLoop::CancelTask(TaskId task_id) { 169a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo if (task_id == kTaskIdNull) 170a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo return false; 171a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo auto delayed_task_it = delayed_tasks_.find(task_id); 172a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo if (delayed_task_it == delayed_tasks_.end()) { 173a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo // This might be an IOTask then. 174a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo auto io_task_it = io_tasks_.find(task_id); 175a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo if (io_task_it == io_tasks_.end()) 176a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo return false; 17707c1779e51680364060f3ec289249869ac7bc5caAlex Deymo return io_task_it->second.CancelTask(); 178a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo } 179a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo // A DelayedTask was found for this task_id at this point. 180a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo 181a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo // Check if the callback was already canceled but we have the entry in 182a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo // delayed_tasks_ since it didn't fire yet in the message loop. 183a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo if (delayed_task_it->second.closure.is_null()) 184a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo return false; 185a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo 186a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo DVLOG_LOC(delayed_task_it->second.location, 1) 187a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo << "Removing task_id " << task_id << " scheduled from this location."; 188a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo // We reset to closure to a null Closure to release all the resources 189a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo // used by this closure at this point, but we don't remove the task_id from 190a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo // delayed_tasks_ since we can't tell base::MessageLoopForIO to not run it. 191a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo delayed_task_it->second.closure = Closure(); 192a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo 193a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo return true; 194a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo} 195a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo 196a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymobool BaseMessageLoop::RunOnce(bool may_block) { 197a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo run_once_ = true; 19830ef318cd1d94e896a277324c68b89798e3dbbddAlex Deymo base::RunLoop run_loop; // Uses the base::MessageLoopForIO implicitly. 19930ef318cd1d94e896a277324c68b89798e3dbbddAlex Deymo base_run_loop_ = &run_loop; 200a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo if (!may_block) 20130ef318cd1d94e896a277324c68b89798e3dbbddAlex Deymo run_loop.RunUntilIdle(); 202a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo else 20330ef318cd1d94e896a277324c68b89798e3dbbddAlex Deymo run_loop.Run(); 20430ef318cd1d94e896a277324c68b89798e3dbbddAlex Deymo base_run_loop_ = nullptr; 205a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo // If the flag was reset to false, it means a closure was run. 206a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo if (!run_once_) 207a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo return true; 208a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo 209a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo run_once_ = false; 210a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo return false; 211a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo} 212a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo 213a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymovoid BaseMessageLoop::Run() { 21430ef318cd1d94e896a277324c68b89798e3dbbddAlex Deymo base::RunLoop run_loop; // Uses the base::MessageLoopForIO implicitly. 21530ef318cd1d94e896a277324c68b89798e3dbbddAlex Deymo base_run_loop_ = &run_loop; 21630ef318cd1d94e896a277324c68b89798e3dbbddAlex Deymo run_loop.Run(); 21730ef318cd1d94e896a277324c68b89798e3dbbddAlex Deymo base_run_loop_ = nullptr; 218a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo} 219a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo 220a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymovoid BaseMessageLoop::BreakLoop() { 22130ef318cd1d94e896a277324c68b89798e3dbbddAlex Deymo if (base_run_loop_ == nullptr) { 22230ef318cd1d94e896a277324c68b89798e3dbbddAlex Deymo DVLOG(1) << "Message loop not running, ignoring BreakLoop()."; 22330ef318cd1d94e896a277324c68b89798e3dbbddAlex Deymo return; // Message loop not running, nothing to do. 22430ef318cd1d94e896a277324c68b89798e3dbbddAlex Deymo } 22530ef318cd1d94e896a277324c68b89798e3dbbddAlex Deymo base_run_loop_->Quit(); 22630ef318cd1d94e896a277324c68b89798e3dbbddAlex Deymo} 22730ef318cd1d94e896a277324c68b89798e3dbbddAlex Deymo 22830ef318cd1d94e896a277324c68b89798e3dbbddAlex DeymoClosure BaseMessageLoop::QuitClosure() const { 22930ef318cd1d94e896a277324c68b89798e3dbbddAlex Deymo if (base_run_loop_ == nullptr) 23030ef318cd1d94e896a277324c68b89798e3dbbddAlex Deymo return base::Bind(&base::DoNothing); 23130ef318cd1d94e896a277324c68b89798e3dbbddAlex Deymo return base_run_loop_->QuitClosure(); 232a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo} 233a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo 234a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex DeymoMessageLoop::TaskId BaseMessageLoop::NextTaskId() { 235a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo TaskId res; 236a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo do { 237a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo res = ++last_id_; 238a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo // We would run out of memory before we run out of task ids. 239a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo } while (!res || 240a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo delayed_tasks_.find(res) != delayed_tasks_.end() || 241a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo io_tasks_.find(res) != io_tasks_.end()); 242a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo return res; 243a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo} 244a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo 245a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymovoid BaseMessageLoop::OnRanPostedTask(MessageLoop::TaskId task_id) { 246a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo auto task_it = delayed_tasks_.find(task_id); 247a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo DCHECK(task_it != delayed_tasks_.end()); 248a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo if (!task_it->second.closure.is_null()) { 249a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo DVLOG_LOC(task_it->second.location, 1) 250a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo << "Running delayed task_id " << task_id 251a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo << " scheduled from this location."; 252a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo // Mark the task as canceled while we are running it so CancelTask returns 253a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo // false. 254a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo Closure closure = std::move(task_it->second.closure); 255a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo task_it->second.closure = Closure(); 256a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo closure.Run(); 257a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo 258a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo // If the |run_once_| flag is set, it is because we are instructed to run 259a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo // only once callback. 260a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo if (run_once_) { 261a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo run_once_ = false; 26230ef318cd1d94e896a277324c68b89798e3dbbddAlex Deymo BreakLoop(); 263a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo } 264a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo } 265a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo delayed_tasks_.erase(task_it); 266a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo} 267a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo 26807c1779e51680364060f3ec289249869ac7bc5caAlex Deymovoid BaseMessageLoop::OnFileReadyPostedTask(MessageLoop::TaskId task_id) { 26907c1779e51680364060f3ec289249869ac7bc5caAlex Deymo auto task_it = io_tasks_.find(task_id); 27007c1779e51680364060f3ec289249869ac7bc5caAlex Deymo // Even if this task was canceled while we were waiting in the message loop 27107c1779e51680364060f3ec289249869ac7bc5caAlex Deymo // for this method to run, the entry in io_tasks_ should still be present, but 27207c1779e51680364060f3ec289249869ac7bc5caAlex Deymo // won't do anything. 27307c1779e51680364060f3ec289249869ac7bc5caAlex Deymo DCHECK(task_it != io_tasks_.end()); 27407c1779e51680364060f3ec289249869ac7bc5caAlex Deymo task_it->second.OnFileReadyPostedTask(); 27507c1779e51680364060f3ec289249869ac7bc5caAlex Deymo} 27607c1779e51680364060f3ec289249869ac7bc5caAlex Deymo 277d671746a66d87edf9598cfbe077b3430e50a09d3Alex Deymoint BaseMessageLoop::ParseBinderMinor( 278d671746a66d87edf9598cfbe077b3430e50a09d3Alex Deymo const std::string& file_contents) { 279d671746a66d87edf9598cfbe077b3430e50a09d3Alex Deymo int result = kInvalidMinor; 280d671746a66d87edf9598cfbe077b3430e50a09d3Alex Deymo // Split along '\n', then along the ' '. Note that base::SplitString trims all 281d671746a66d87edf9598cfbe077b3430e50a09d3Alex Deymo // white spaces at the beginning and end after splitting. 282922d235dca34496fd30e1b15b2bf24b4a6949288Alex Deymo std::vector<std::string> lines = 28380b7ee94e36e2d25a97a262d3b558bbf130c2a01Alex Vakulenko base::SplitString(file_contents, "\n", base::TRIM_WHITESPACE, 28480b7ee94e36e2d25a97a262d3b558bbf130c2a01Alex Vakulenko base::SPLIT_WANT_ALL); 285d671746a66d87edf9598cfbe077b3430e50a09d3Alex Deymo for (const std::string& line : lines) { 286d671746a66d87edf9598cfbe077b3430e50a09d3Alex Deymo if (line.empty()) 287d671746a66d87edf9598cfbe077b3430e50a09d3Alex Deymo continue; 288d671746a66d87edf9598cfbe077b3430e50a09d3Alex Deymo std::string number; 289d671746a66d87edf9598cfbe077b3430e50a09d3Alex Deymo std::string name; 290d671746a66d87edf9598cfbe077b3430e50a09d3Alex Deymo if (!string_utils::SplitAtFirst(line, " ", &number, &name, false)) 291d671746a66d87edf9598cfbe077b3430e50a09d3Alex Deymo continue; 292d671746a66d87edf9598cfbe077b3430e50a09d3Alex Deymo 293d671746a66d87edf9598cfbe077b3430e50a09d3Alex Deymo if (name == kBinderDriverName && base::StringToInt(number, &result)) 294d671746a66d87edf9598cfbe077b3430e50a09d3Alex Deymo break; 295d671746a66d87edf9598cfbe077b3430e50a09d3Alex Deymo } 296d671746a66d87edf9598cfbe077b3430e50a09d3Alex Deymo return result; 297d671746a66d87edf9598cfbe077b3430e50a09d3Alex Deymo} 298d671746a66d87edf9598cfbe077b3430e50a09d3Alex Deymo 299d671746a66d87edf9598cfbe077b3430e50a09d3Alex Deymounsigned int BaseMessageLoop::GetBinderMinor() { 300d671746a66d87edf9598cfbe077b3430e50a09d3Alex Deymo if (binder_minor_ != kUninitializedMinor) 301d671746a66d87edf9598cfbe077b3430e50a09d3Alex Deymo return binder_minor_; 302d671746a66d87edf9598cfbe077b3430e50a09d3Alex Deymo 303d671746a66d87edf9598cfbe077b3430e50a09d3Alex Deymo std::string proc_misc; 304d671746a66d87edf9598cfbe077b3430e50a09d3Alex Deymo if (!base::ReadFileToString(base::FilePath(kMiscMinorPath), &proc_misc)) 305d671746a66d87edf9598cfbe077b3430e50a09d3Alex Deymo return binder_minor_; 306d671746a66d87edf9598cfbe077b3430e50a09d3Alex Deymo binder_minor_ = ParseBinderMinor(proc_misc); 307d671746a66d87edf9598cfbe077b3430e50a09d3Alex Deymo return binder_minor_; 308d671746a66d87edf9598cfbe077b3430e50a09d3Alex Deymo} 309d671746a66d87edf9598cfbe077b3430e50a09d3Alex Deymo 310a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex DeymoBaseMessageLoop::IOTask::IOTask(const tracked_objects::Location& location, 311a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo BaseMessageLoop* loop, 312a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo MessageLoop::TaskId task_id, 31307c1779e51680364060f3ec289249869ac7bc5caAlex Deymo int fd, 31407c1779e51680364060f3ec289249869ac7bc5caAlex Deymo base::MessageLoopForIO::Mode base_mode, 315a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo bool persistent, 316a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo const Closure& task) 317a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo : location_(location), loop_(loop), task_id_(task_id), 318324b9515118eca1ac9b579af6dd4d9ffc33a023cJay Civelli fd_(fd), base_mode_(base_mode), persistent_(persistent), closure_(task), 319324b9515118eca1ac9b579af6dd4d9ffc33a023cJay Civelli fd_watcher_(FROM_HERE) {} 320a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo 32107c1779e51680364060f3ec289249869ac7bc5caAlex Deymobool BaseMessageLoop::IOTask::StartWatching() { 32207c1779e51680364060f3ec289249869ac7bc5caAlex Deymo return loop_->base_loop_->WatchFileDescriptor( 32307c1779e51680364060f3ec289249869ac7bc5caAlex Deymo fd_, persistent_, base_mode_, &fd_watcher_, this); 324a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo} 325a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo 32607c1779e51680364060f3ec289249869ac7bc5caAlex Deymovoid BaseMessageLoop::IOTask::StopWatching() { 32707c1779e51680364060f3ec289249869ac7bc5caAlex Deymo // This is safe to call even if we are not watching for it. 32807c1779e51680364060f3ec289249869ac7bc5caAlex Deymo fd_watcher_.StopWatchingFileDescriptor(); 32907c1779e51680364060f3ec289249869ac7bc5caAlex Deymo} 33007c1779e51680364060f3ec289249869ac7bc5caAlex Deymo 33107c1779e51680364060f3ec289249869ac7bc5caAlex Deymovoid BaseMessageLoop::IOTask::OnFileCanReadWithoutBlocking(int /* fd */) { 33207c1779e51680364060f3ec289249869ac7bc5caAlex Deymo OnFileReady(); 33307c1779e51680364060f3ec289249869ac7bc5caAlex Deymo} 33407c1779e51680364060f3ec289249869ac7bc5caAlex Deymo 33507c1779e51680364060f3ec289249869ac7bc5caAlex Deymovoid BaseMessageLoop::IOTask::OnFileCanWriteWithoutBlocking(int /* fd */) { 33607c1779e51680364060f3ec289249869ac7bc5caAlex Deymo OnFileReady(); 33707c1779e51680364060f3ec289249869ac7bc5caAlex Deymo} 33807c1779e51680364060f3ec289249869ac7bc5caAlex Deymo 33907c1779e51680364060f3ec289249869ac7bc5caAlex Deymovoid BaseMessageLoop::IOTask::OnFileReady() { 340d671746a66d87edf9598cfbe077b3430e50a09d3Alex Deymo // For file descriptors marked with the immediate_run flag, we don't call 341d671746a66d87edf9598cfbe077b3430e50a09d3Alex Deymo // StopWatching() and wait, instead we dispatch the callback immediately. 342d671746a66d87edf9598cfbe077b3430e50a09d3Alex Deymo if (immediate_run_) { 343d671746a66d87edf9598cfbe077b3430e50a09d3Alex Deymo posted_task_pending_ = true; 344d671746a66d87edf9598cfbe077b3430e50a09d3Alex Deymo OnFileReadyPostedTask(); 345d671746a66d87edf9598cfbe077b3430e50a09d3Alex Deymo return; 346d671746a66d87edf9598cfbe077b3430e50a09d3Alex Deymo } 347d671746a66d87edf9598cfbe077b3430e50a09d3Alex Deymo 34807c1779e51680364060f3ec289249869ac7bc5caAlex Deymo // When the file descriptor becomes available we stop watching for it and 34907c1779e51680364060f3ec289249869ac7bc5caAlex Deymo // schedule a task to run the callback from the main loop. The callback will 350d671746a66d87edf9598cfbe077b3430e50a09d3Alex Deymo // run using the same scheduler used to run other delayed tasks, avoiding 35107c1779e51680364060f3ec289249869ac7bc5caAlex Deymo // starvation of the available posted tasks if there are file descriptors 35207c1779e51680364060f3ec289249869ac7bc5caAlex Deymo // always available. The new posted task will use the same TaskId as the 35307c1779e51680364060f3ec289249869ac7bc5caAlex Deymo // current file descriptor watching task an could be canceled in either state, 35407c1779e51680364060f3ec289249869ac7bc5caAlex Deymo // when waiting for the file descriptor or waiting in the main loop. 35507c1779e51680364060f3ec289249869ac7bc5caAlex Deymo StopWatching(); 35607c1779e51680364060f3ec289249869ac7bc5caAlex Deymo bool base_scheduled = loop_->base_loop_->task_runner()->PostTask( 35707c1779e51680364060f3ec289249869ac7bc5caAlex Deymo location_, 35807c1779e51680364060f3ec289249869ac7bc5caAlex Deymo base::Bind(&BaseMessageLoop::OnFileReadyPostedTask, 35907c1779e51680364060f3ec289249869ac7bc5caAlex Deymo loop_->weak_ptr_factory_.GetWeakPtr(), 36007c1779e51680364060f3ec289249869ac7bc5caAlex Deymo task_id_)); 36107c1779e51680364060f3ec289249869ac7bc5caAlex Deymo posted_task_pending_ = true; 36207c1779e51680364060f3ec289249869ac7bc5caAlex Deymo if (base_scheduled) { 36307c1779e51680364060f3ec289249869ac7bc5caAlex Deymo DVLOG_LOC(location_, 1) 36407c1779e51680364060f3ec289249869ac7bc5caAlex Deymo << "Dispatching task_id " << task_id_ << " for " 36507c1779e51680364060f3ec289249869ac7bc5caAlex Deymo << (base_mode_ == base::MessageLoopForIO::WATCH_READ ? 36607c1779e51680364060f3ec289249869ac7bc5caAlex Deymo "reading" : "writing") 36707c1779e51680364060f3ec289249869ac7bc5caAlex Deymo << " file descriptor " << fd_ << ", scheduled from this location."; 36807c1779e51680364060f3ec289249869ac7bc5caAlex Deymo } else { 36907c1779e51680364060f3ec289249869ac7bc5caAlex Deymo // In the rare case that PostTask() fails, we fall back to run it directly. 37007c1779e51680364060f3ec289249869ac7bc5caAlex Deymo // This would indicate a bigger problem with the message loop setup. 37107c1779e51680364060f3ec289249869ac7bc5caAlex Deymo LOG(ERROR) << "Error on base::MessageLoopForIO::PostTask()."; 37207c1779e51680364060f3ec289249869ac7bc5caAlex Deymo OnFileReadyPostedTask(); 37307c1779e51680364060f3ec289249869ac7bc5caAlex Deymo } 374a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo} 375a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo 37607c1779e51680364060f3ec289249869ac7bc5caAlex Deymovoid BaseMessageLoop::IOTask::OnFileReadyPostedTask() { 377a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo // We can't access |this| after running the |closure_| since it could call 378a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo // CancelTask on its own task_id, so we copy the members we need now. 379a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo BaseMessageLoop* loop_ptr = loop_; 38007c1779e51680364060f3ec289249869ac7bc5caAlex Deymo DCHECK(posted_task_pending_ = true); 38107c1779e51680364060f3ec289249869ac7bc5caAlex Deymo posted_task_pending_ = false; 38207c1779e51680364060f3ec289249869ac7bc5caAlex Deymo 38307c1779e51680364060f3ec289249869ac7bc5caAlex Deymo // If this task was already canceled, the closure will be null and there is 38407c1779e51680364060f3ec289249869ac7bc5caAlex Deymo // nothing else to do here. This execution doesn't count a step for RunOnce() 38507c1779e51680364060f3ec289249869ac7bc5caAlex Deymo // unless we have a callback to run. 38607c1779e51680364060f3ec289249869ac7bc5caAlex Deymo if (closure_.is_null()) { 38707c1779e51680364060f3ec289249869ac7bc5caAlex Deymo loop_->io_tasks_.erase(task_id_); 38807c1779e51680364060f3ec289249869ac7bc5caAlex Deymo return; 38907c1779e51680364060f3ec289249869ac7bc5caAlex Deymo } 390a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo 391a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo DVLOG_LOC(location_, 1) 39207c1779e51680364060f3ec289249869ac7bc5caAlex Deymo << "Running task_id " << task_id_ << " for " 39307c1779e51680364060f3ec289249869ac7bc5caAlex Deymo << (base_mode_ == base::MessageLoopForIO::WATCH_READ ? 39407c1779e51680364060f3ec289249869ac7bc5caAlex Deymo "reading" : "writing") 39507c1779e51680364060f3ec289249869ac7bc5caAlex Deymo << " file descriptor " << fd_ << ", scheduled from this location."; 396a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo 397a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo if (persistent_) { 398a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo // In the persistent case we just run the callback. If this callback cancels 39907c1779e51680364060f3ec289249869ac7bc5caAlex Deymo // the task id, we can't access |this| anymore, so we re-start watching the 400d671746a66d87edf9598cfbe077b3430e50a09d3Alex Deymo // file descriptor before running the callback, unless this is a fd where 401d671746a66d87edf9598cfbe077b3430e50a09d3Alex Deymo // we didn't stop watching the file descriptor when it became available. 402d671746a66d87edf9598cfbe077b3430e50a09d3Alex Deymo if (!immediate_run_) 403d671746a66d87edf9598cfbe077b3430e50a09d3Alex Deymo StartWatching(); 404a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo closure_.Run(); 405a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo } else { 406a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo // This will destroy |this|, the fd_watcher and therefore stop watching this 407a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo // file descriptor. 408a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo Closure closure_copy = std::move(closure_); 409a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo loop_->io_tasks_.erase(task_id_); 410a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo // Run the closure from the local copy we just made. 411a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo closure_copy.Run(); 412a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo } 413a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo 414a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo if (loop_ptr->run_once_) { 415a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo loop_ptr->run_once_ = false; 41630ef318cd1d94e896a277324c68b89798e3dbbddAlex Deymo loop_ptr->BreakLoop(); 417a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo } 418a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo} 419a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo 42007c1779e51680364060f3ec289249869ac7bc5caAlex Deymobool BaseMessageLoop::IOTask::CancelTask() { 42107c1779e51680364060f3ec289249869ac7bc5caAlex Deymo if (closure_.is_null()) 42207c1779e51680364060f3ec289249869ac7bc5caAlex Deymo return false; 42307c1779e51680364060f3ec289249869ac7bc5caAlex Deymo 42407c1779e51680364060f3ec289249869ac7bc5caAlex Deymo DVLOG_LOC(location_, 1) 42507c1779e51680364060f3ec289249869ac7bc5caAlex Deymo << "Removing task_id " << task_id_ << " scheduled from this location."; 42607c1779e51680364060f3ec289249869ac7bc5caAlex Deymo 42707c1779e51680364060f3ec289249869ac7bc5caAlex Deymo if (!posted_task_pending_) { 42807c1779e51680364060f3ec289249869ac7bc5caAlex Deymo // Destroying the FileDescriptorWatcher implicitly stops watching the file 42907c1779e51680364060f3ec289249869ac7bc5caAlex Deymo // descriptor. This will delete our instance. 43007c1779e51680364060f3ec289249869ac7bc5caAlex Deymo loop_->io_tasks_.erase(task_id_); 43107c1779e51680364060f3ec289249869ac7bc5caAlex Deymo return true; 43207c1779e51680364060f3ec289249869ac7bc5caAlex Deymo } 43307c1779e51680364060f3ec289249869ac7bc5caAlex Deymo // The IOTask is waiting for the message loop to run its delayed task, so 43407c1779e51680364060f3ec289249869ac7bc5caAlex Deymo // it is not watching for the file descriptor. We release the closure 43507c1779e51680364060f3ec289249869ac7bc5caAlex Deymo // resources now but keep the IOTask instance alive while we wait for the 43607c1779e51680364060f3ec289249869ac7bc5caAlex Deymo // callback to run and delete the IOTask. 43707c1779e51680364060f3ec289249869ac7bc5caAlex Deymo closure_ = Closure(); 43807c1779e51680364060f3ec289249869ac7bc5caAlex Deymo return true; 43907c1779e51680364060f3ec289249869ac7bc5caAlex Deymo} 44007c1779e51680364060f3ec289249869ac7bc5caAlex Deymo 4419ed0cab99f18acb3570a35e9408f24355f6b8324Alex Vakulenko} // namespace brillo 442