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 1277edc5357e1ff2c507a07d4c97f943910609ee44Alex Deymo#ifndef __ANDROID_HOST__ 1377edc5357e1ff2c507a07d4c97f943910609ee44Alex Deymo// Used for MISC_MAJOR. Only required for the target and not always available 1477edc5357e1ff2c507a07d4c97f943910609ee44Alex Deymo// for the host. 1577edc5357e1ff2c507a07d4c97f943910609ee44Alex Deymo#include <linux/major.h> 1677edc5357e1ff2c507a07d4c97f943910609ee44Alex Deymo#endif 1777edc5357e1ff2c507a07d4c97f943910609ee44Alex Deymo 18d671746a66d87edf9598cfbe077b3430e50a09d3Alex Deymo#include <vector> 19d671746a66d87edf9598cfbe077b3430e50a09d3Alex Deymo 20a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo#include <base/bind.h> 21d671746a66d87edf9598cfbe077b3430e50a09d3Alex Deymo#include <base/files/file_path.h> 22d671746a66d87edf9598cfbe077b3430e50a09d3Alex Deymo#include <base/files/file_util.h> 2330ef318cd1d94e896a277324c68b89798e3dbbddAlex Deymo#include <base/run_loop.h> 24d671746a66d87edf9598cfbe077b3430e50a09d3Alex Deymo#include <base/strings/string_number_conversions.h> 25d671746a66d87edf9598cfbe077b3430e50a09d3Alex Deymo#include <base/strings/string_split.h> 26a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo 279ed0cab99f18acb3570a35e9408f24355f6b8324Alex Vakulenko#include <brillo/location_logging.h> 28d671746a66d87edf9598cfbe077b3430e50a09d3Alex Deymo#include <brillo/strings/string_utils.h> 29a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo 30a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymousing base::Closure; 31a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo 32d671746a66d87edf9598cfbe077b3430e50a09d3Alex Deymonamespace { 33d671746a66d87edf9598cfbe077b3430e50a09d3Alex Deymo 34d671746a66d87edf9598cfbe077b3430e50a09d3Alex Deymoconst char kMiscMinorPath[] = "/proc/misc"; 35d671746a66d87edf9598cfbe077b3430e50a09d3Alex Deymoconst char kBinderDriverName[] = "binder"; 36d671746a66d87edf9598cfbe077b3430e50a09d3Alex Deymo 37d671746a66d87edf9598cfbe077b3430e50a09d3Alex Deymo} // namespace 38d671746a66d87edf9598cfbe077b3430e50a09d3Alex Deymo 399ed0cab99f18acb3570a35e9408f24355f6b8324Alex Vakulenkonamespace brillo { 40a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo 41d671746a66d87edf9598cfbe077b3430e50a09d3Alex Deymoconst int BaseMessageLoop::kInvalidMinor = -1; 42d671746a66d87edf9598cfbe077b3430e50a09d3Alex Deymoconst int BaseMessageLoop::kUninitializedMinor = -2; 43d671746a66d87edf9598cfbe077b3430e50a09d3Alex Deymo 44a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex DeymoBaseMessageLoop::BaseMessageLoop(base::MessageLoopForIO* base_loop) 45a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo : base_loop_(base_loop), 46a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo weak_ptr_factory_(this) {} 47a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo 48a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex DeymoBaseMessageLoop::~BaseMessageLoop() { 49a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo for (auto& io_task : io_tasks_) { 50a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo DVLOG_LOC(io_task.second.location(), 1) 51a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo << "Removing file descriptor watcher task_id " << io_task.first 52a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo << " leaked on BaseMessageLoop, scheduled from this location."; 5307c1779e51680364060f3ec289249869ac7bc5caAlex Deymo io_task.second.StopWatching(); 54a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo } 55a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo 56a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo // Note all pending canceled delayed tasks when destroying the message loop. 57a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo size_t lazily_deleted_tasks = 0; 58a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo for (const auto& delayed_task : delayed_tasks_) { 59a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo if (delayed_task.second.closure.is_null()) { 60a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo lazily_deleted_tasks++; 61a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo } else { 62a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo DVLOG_LOC(delayed_task.second.location, 1) 63a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo << "Removing delayed task_id " << delayed_task.first 64a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo << " leaked on BaseMessageLoop, scheduled from this location."; 65a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo } 66a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo } 67a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo if (lazily_deleted_tasks) { 68a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo LOG(INFO) << "Leaking " << lazily_deleted_tasks << " canceled tasks."; 69a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo } 70a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo} 71a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo 72a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex DeymoMessageLoop::TaskId BaseMessageLoop::PostDelayedTask( 73a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo const tracked_objects::Location& from_here, 74a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo const Closure &task, 75a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo base::TimeDelta delay) { 76a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo TaskId task_id = NextTaskId(); 77a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo bool base_scheduled = base_loop_->task_runner()->PostDelayedTask( 78a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo from_here, 79a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo base::Bind(&BaseMessageLoop::OnRanPostedTask, 80a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo weak_ptr_factory_.GetWeakPtr(), 81a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo task_id), 82a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo delay); 83a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo DVLOG_LOC(from_here, 1) << "Scheduling delayed task_id " << task_id 84a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo << " to run in " << delay << "."; 85a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo if (!base_scheduled) 86a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo return MessageLoop::kTaskIdNull; 87a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo 88a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo delayed_tasks_.emplace(task_id, 89a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo DelayedTask{from_here, task_id, std::move(task)}); 90a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo return task_id; 91a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo} 92a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo 93a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex DeymoMessageLoop::TaskId BaseMessageLoop::WatchFileDescriptor( 94a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo const tracked_objects::Location& from_here, 95a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo int fd, 96a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo WatchMode mode, 97a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo bool persistent, 98a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo const Closure &task) { 99a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo // base::MessageLoopForIO CHECKS that "fd >= 0", so we handle that case here. 100a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo if (fd < 0) 101a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo return MessageLoop::kTaskIdNull; 102a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo 103a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo base::MessageLoopForIO::Mode base_mode = base::MessageLoopForIO::WATCH_READ; 104a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo switch (mode) { 105a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo case MessageLoop::kWatchRead: 106a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo base_mode = base::MessageLoopForIO::WATCH_READ; 107a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo break; 108a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo case MessageLoop::kWatchWrite: 109a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo base_mode = base::MessageLoopForIO::WATCH_WRITE; 110a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo break; 111a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo default: 112a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo return MessageLoop::kTaskIdNull; 113a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo } 114a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo 115a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo TaskId task_id = NextTaskId(); 116a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo auto it_bool = io_tasks_.emplace( 117a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo std::piecewise_construct, 118a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo std::forward_as_tuple(task_id), 11907c1779e51680364060f3ec289249869ac7bc5caAlex Deymo std::forward_as_tuple( 12007c1779e51680364060f3ec289249869ac7bc5caAlex Deymo from_here, this, task_id, fd, base_mode, persistent, task)); 121a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo // This should always insert a new element. 122a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo DCHECK(it_bool.second); 12307c1779e51680364060f3ec289249869ac7bc5caAlex Deymo bool scheduled = it_bool.first->second.StartWatching(); 124a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo DVLOG_LOC(from_here, 1) 125a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo << "Watching fd " << fd << " for " 126a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo << (mode == MessageLoop::kWatchRead ? "reading" : "writing") 127a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo << (persistent ? " persistently" : " just once") 128a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo << " as task_id " << task_id 129a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo << (scheduled ? " successfully" : " failed."); 130a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo 131a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo if (!scheduled) { 132a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo io_tasks_.erase(task_id); 133a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo return MessageLoop::kTaskIdNull; 134a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo } 135d671746a66d87edf9598cfbe077b3430e50a09d3Alex Deymo 13677edc5357e1ff2c507a07d4c97f943910609ee44Alex Deymo#ifndef __ANDROID_HOST__ 137d671746a66d87edf9598cfbe077b3430e50a09d3Alex Deymo // Determine if the passed fd is the binder file descriptor. For that, we need 138d671746a66d87edf9598cfbe077b3430e50a09d3Alex Deymo // to check that is a special char device and that the major and minor device 139d671746a66d87edf9598cfbe077b3430e50a09d3Alex Deymo // numbers match. The binder file descriptor can't be removed and added back 140d671746a66d87edf9598cfbe077b3430e50a09d3Alex Deymo // to an epoll group when there's work available to be done by the file 141d671746a66d87edf9598cfbe077b3430e50a09d3Alex Deymo // descriptor due to bugs in the binder driver (b/26524111) when used with 142d671746a66d87edf9598cfbe077b3430e50a09d3Alex Deymo // epoll. Therefore, we flag the binder fd and never attempt to remove it. 143d671746a66d87edf9598cfbe077b3430e50a09d3Alex Deymo // This may cause the binder file descriptor to be attended with higher 144d671746a66d87edf9598cfbe077b3430e50a09d3Alex Deymo // priority and cause starvation of other events. 145d671746a66d87edf9598cfbe077b3430e50a09d3Alex Deymo struct stat buf; 146d671746a66d87edf9598cfbe077b3430e50a09d3Alex Deymo if (fstat(fd, &buf) == 0 && 147d671746a66d87edf9598cfbe077b3430e50a09d3Alex Deymo S_ISCHR(buf.st_mode) && 148d671746a66d87edf9598cfbe077b3430e50a09d3Alex Deymo major(buf.st_rdev) == MISC_MAJOR && 149d671746a66d87edf9598cfbe077b3430e50a09d3Alex Deymo minor(buf.st_rdev) == GetBinderMinor()) { 150d671746a66d87edf9598cfbe077b3430e50a09d3Alex Deymo it_bool.first->second.RunImmediately(); 151d671746a66d87edf9598cfbe077b3430e50a09d3Alex Deymo } 15277edc5357e1ff2c507a07d4c97f943910609ee44Alex Deymo#endif 153d671746a66d87edf9598cfbe077b3430e50a09d3Alex Deymo 154a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo return task_id; 155a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo} 156a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo 157a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymobool BaseMessageLoop::CancelTask(TaskId task_id) { 158a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo if (task_id == kTaskIdNull) 159a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo return false; 160a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo auto delayed_task_it = delayed_tasks_.find(task_id); 161a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo if (delayed_task_it == delayed_tasks_.end()) { 162a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo // This might be an IOTask then. 163a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo auto io_task_it = io_tasks_.find(task_id); 164a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo if (io_task_it == io_tasks_.end()) 165a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo return false; 16607c1779e51680364060f3ec289249869ac7bc5caAlex Deymo return io_task_it->second.CancelTask(); 167a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo } 168a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo // A DelayedTask was found for this task_id at this point. 169a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo 170a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo // Check if the callback was already canceled but we have the entry in 171a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo // delayed_tasks_ since it didn't fire yet in the message loop. 172a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo if (delayed_task_it->second.closure.is_null()) 173a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo return false; 174a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo 175a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo DVLOG_LOC(delayed_task_it->second.location, 1) 176a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo << "Removing task_id " << task_id << " scheduled from this location."; 177a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo // We reset to closure to a null Closure to release all the resources 178a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo // used by this closure at this point, but we don't remove the task_id from 179a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo // delayed_tasks_ since we can't tell base::MessageLoopForIO to not run it. 180a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo delayed_task_it->second.closure = Closure(); 181a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo 182a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo return true; 183a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo} 184a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo 185a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymobool BaseMessageLoop::RunOnce(bool may_block) { 186a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo run_once_ = true; 18730ef318cd1d94e896a277324c68b89798e3dbbddAlex Deymo base::RunLoop run_loop; // Uses the base::MessageLoopForIO implicitly. 18830ef318cd1d94e896a277324c68b89798e3dbbddAlex Deymo base_run_loop_ = &run_loop; 189a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo if (!may_block) 19030ef318cd1d94e896a277324c68b89798e3dbbddAlex Deymo run_loop.RunUntilIdle(); 191a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo else 19230ef318cd1d94e896a277324c68b89798e3dbbddAlex Deymo run_loop.Run(); 19330ef318cd1d94e896a277324c68b89798e3dbbddAlex Deymo base_run_loop_ = nullptr; 194a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo // If the flag was reset to false, it means a closure was run. 195a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo if (!run_once_) 196a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo return true; 197a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo 198a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo run_once_ = false; 199a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo return false; 200a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo} 201a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo 202a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymovoid BaseMessageLoop::Run() { 20330ef318cd1d94e896a277324c68b89798e3dbbddAlex Deymo base::RunLoop run_loop; // Uses the base::MessageLoopForIO implicitly. 20430ef318cd1d94e896a277324c68b89798e3dbbddAlex Deymo base_run_loop_ = &run_loop; 20530ef318cd1d94e896a277324c68b89798e3dbbddAlex Deymo run_loop.Run(); 20630ef318cd1d94e896a277324c68b89798e3dbbddAlex Deymo base_run_loop_ = nullptr; 207a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo} 208a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo 209a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymovoid BaseMessageLoop::BreakLoop() { 21030ef318cd1d94e896a277324c68b89798e3dbbddAlex Deymo if (base_run_loop_ == nullptr) { 21130ef318cd1d94e896a277324c68b89798e3dbbddAlex Deymo DVLOG(1) << "Message loop not running, ignoring BreakLoop()."; 21230ef318cd1d94e896a277324c68b89798e3dbbddAlex Deymo return; // Message loop not running, nothing to do. 21330ef318cd1d94e896a277324c68b89798e3dbbddAlex Deymo } 21430ef318cd1d94e896a277324c68b89798e3dbbddAlex Deymo base_run_loop_->Quit(); 21530ef318cd1d94e896a277324c68b89798e3dbbddAlex Deymo} 21630ef318cd1d94e896a277324c68b89798e3dbbddAlex Deymo 21730ef318cd1d94e896a277324c68b89798e3dbbddAlex DeymoClosure BaseMessageLoop::QuitClosure() const { 21830ef318cd1d94e896a277324c68b89798e3dbbddAlex Deymo if (base_run_loop_ == nullptr) 21930ef318cd1d94e896a277324c68b89798e3dbbddAlex Deymo return base::Bind(&base::DoNothing); 22030ef318cd1d94e896a277324c68b89798e3dbbddAlex Deymo return base_run_loop_->QuitClosure(); 221a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo} 222a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo 223a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex DeymoMessageLoop::TaskId BaseMessageLoop::NextTaskId() { 224a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo TaskId res; 225a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo do { 226a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo res = ++last_id_; 227a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo // We would run out of memory before we run out of task ids. 228a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo } while (!res || 229a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo delayed_tasks_.find(res) != delayed_tasks_.end() || 230a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo io_tasks_.find(res) != io_tasks_.end()); 231a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo return res; 232a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo} 233a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo 234a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymovoid BaseMessageLoop::OnRanPostedTask(MessageLoop::TaskId task_id) { 235a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo auto task_it = delayed_tasks_.find(task_id); 236a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo DCHECK(task_it != delayed_tasks_.end()); 237a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo if (!task_it->second.closure.is_null()) { 238a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo DVLOG_LOC(task_it->second.location, 1) 239a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo << "Running delayed task_id " << task_id 240a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo << " scheduled from this location."; 241a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo // Mark the task as canceled while we are running it so CancelTask returns 242a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo // false. 243a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo Closure closure = std::move(task_it->second.closure); 244a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo task_it->second.closure = Closure(); 245a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo closure.Run(); 246a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo 247a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo // If the |run_once_| flag is set, it is because we are instructed to run 248a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo // only once callback. 249a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo if (run_once_) { 250a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo run_once_ = false; 25130ef318cd1d94e896a277324c68b89798e3dbbddAlex Deymo BreakLoop(); 252a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo } 253a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo } 254a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo delayed_tasks_.erase(task_it); 255a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo} 256a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo 25707c1779e51680364060f3ec289249869ac7bc5caAlex Deymovoid BaseMessageLoop::OnFileReadyPostedTask(MessageLoop::TaskId task_id) { 25807c1779e51680364060f3ec289249869ac7bc5caAlex Deymo auto task_it = io_tasks_.find(task_id); 25907c1779e51680364060f3ec289249869ac7bc5caAlex Deymo // Even if this task was canceled while we were waiting in the message loop 26007c1779e51680364060f3ec289249869ac7bc5caAlex Deymo // for this method to run, the entry in io_tasks_ should still be present, but 26107c1779e51680364060f3ec289249869ac7bc5caAlex Deymo // won't do anything. 26207c1779e51680364060f3ec289249869ac7bc5caAlex Deymo DCHECK(task_it != io_tasks_.end()); 26307c1779e51680364060f3ec289249869ac7bc5caAlex Deymo task_it->second.OnFileReadyPostedTask(); 26407c1779e51680364060f3ec289249869ac7bc5caAlex Deymo} 26507c1779e51680364060f3ec289249869ac7bc5caAlex Deymo 266d671746a66d87edf9598cfbe077b3430e50a09d3Alex Deymoint BaseMessageLoop::ParseBinderMinor( 267d671746a66d87edf9598cfbe077b3430e50a09d3Alex Deymo const std::string& file_contents) { 268d671746a66d87edf9598cfbe077b3430e50a09d3Alex Deymo int result = kInvalidMinor; 269d671746a66d87edf9598cfbe077b3430e50a09d3Alex Deymo // Split along '\n', then along the ' '. Note that base::SplitString trims all 270d671746a66d87edf9598cfbe077b3430e50a09d3Alex Deymo // white spaces at the beginning and end after splitting. 27180b7ee94e36e2d25a97a262d3b558bbf130c2a01Alex Vakulenko std::vector<std::string> lines = 27280b7ee94e36e2d25a97a262d3b558bbf130c2a01Alex Vakulenko base::SplitString(file_contents, "\n", base::TRIM_WHITESPACE, 27380b7ee94e36e2d25a97a262d3b558bbf130c2a01Alex Vakulenko base::SPLIT_WANT_ALL); 274d671746a66d87edf9598cfbe077b3430e50a09d3Alex Deymo for (const std::string& line : lines) { 275d671746a66d87edf9598cfbe077b3430e50a09d3Alex Deymo if (line.empty()) 276d671746a66d87edf9598cfbe077b3430e50a09d3Alex Deymo continue; 277d671746a66d87edf9598cfbe077b3430e50a09d3Alex Deymo std::string number; 278d671746a66d87edf9598cfbe077b3430e50a09d3Alex Deymo std::string name; 279d671746a66d87edf9598cfbe077b3430e50a09d3Alex Deymo if (!string_utils::SplitAtFirst(line, " ", &number, &name, false)) 280d671746a66d87edf9598cfbe077b3430e50a09d3Alex Deymo continue; 281d671746a66d87edf9598cfbe077b3430e50a09d3Alex Deymo 282d671746a66d87edf9598cfbe077b3430e50a09d3Alex Deymo if (name == kBinderDriverName && base::StringToInt(number, &result)) 283d671746a66d87edf9598cfbe077b3430e50a09d3Alex Deymo break; 284d671746a66d87edf9598cfbe077b3430e50a09d3Alex Deymo } 285d671746a66d87edf9598cfbe077b3430e50a09d3Alex Deymo return result; 286d671746a66d87edf9598cfbe077b3430e50a09d3Alex Deymo} 287d671746a66d87edf9598cfbe077b3430e50a09d3Alex Deymo 288d671746a66d87edf9598cfbe077b3430e50a09d3Alex Deymounsigned int BaseMessageLoop::GetBinderMinor() { 289d671746a66d87edf9598cfbe077b3430e50a09d3Alex Deymo if (binder_minor_ != kUninitializedMinor) 290d671746a66d87edf9598cfbe077b3430e50a09d3Alex Deymo return binder_minor_; 291d671746a66d87edf9598cfbe077b3430e50a09d3Alex Deymo 292d671746a66d87edf9598cfbe077b3430e50a09d3Alex Deymo std::string proc_misc; 293d671746a66d87edf9598cfbe077b3430e50a09d3Alex Deymo if (!base::ReadFileToString(base::FilePath(kMiscMinorPath), &proc_misc)) 294d671746a66d87edf9598cfbe077b3430e50a09d3Alex Deymo return binder_minor_; 295d671746a66d87edf9598cfbe077b3430e50a09d3Alex Deymo binder_minor_ = ParseBinderMinor(proc_misc); 296d671746a66d87edf9598cfbe077b3430e50a09d3Alex Deymo return binder_minor_; 297d671746a66d87edf9598cfbe077b3430e50a09d3Alex Deymo} 298d671746a66d87edf9598cfbe077b3430e50a09d3Alex Deymo 299a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex DeymoBaseMessageLoop::IOTask::IOTask(const tracked_objects::Location& location, 300a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo BaseMessageLoop* loop, 301a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo MessageLoop::TaskId task_id, 30207c1779e51680364060f3ec289249869ac7bc5caAlex Deymo int fd, 30307c1779e51680364060f3ec289249869ac7bc5caAlex Deymo base::MessageLoopForIO::Mode base_mode, 304a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo bool persistent, 305a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo const Closure& task) 306a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo : location_(location), loop_(loop), task_id_(task_id), 30707c1779e51680364060f3ec289249869ac7bc5caAlex Deymo fd_(fd), base_mode_(base_mode), persistent_(persistent), closure_(task) {} 308a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo 30907c1779e51680364060f3ec289249869ac7bc5caAlex Deymobool BaseMessageLoop::IOTask::StartWatching() { 31007c1779e51680364060f3ec289249869ac7bc5caAlex Deymo return loop_->base_loop_->WatchFileDescriptor( 31107c1779e51680364060f3ec289249869ac7bc5caAlex Deymo fd_, persistent_, base_mode_, &fd_watcher_, this); 312a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo} 313a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo 31407c1779e51680364060f3ec289249869ac7bc5caAlex Deymovoid BaseMessageLoop::IOTask::StopWatching() { 31507c1779e51680364060f3ec289249869ac7bc5caAlex Deymo // This is safe to call even if we are not watching for it. 31607c1779e51680364060f3ec289249869ac7bc5caAlex Deymo fd_watcher_.StopWatchingFileDescriptor(); 31707c1779e51680364060f3ec289249869ac7bc5caAlex Deymo} 31807c1779e51680364060f3ec289249869ac7bc5caAlex Deymo 31907c1779e51680364060f3ec289249869ac7bc5caAlex Deymovoid BaseMessageLoop::IOTask::OnFileCanReadWithoutBlocking(int /* fd */) { 32007c1779e51680364060f3ec289249869ac7bc5caAlex Deymo OnFileReady(); 32107c1779e51680364060f3ec289249869ac7bc5caAlex Deymo} 32207c1779e51680364060f3ec289249869ac7bc5caAlex Deymo 32307c1779e51680364060f3ec289249869ac7bc5caAlex Deymovoid BaseMessageLoop::IOTask::OnFileCanWriteWithoutBlocking(int /* fd */) { 32407c1779e51680364060f3ec289249869ac7bc5caAlex Deymo OnFileReady(); 32507c1779e51680364060f3ec289249869ac7bc5caAlex Deymo} 32607c1779e51680364060f3ec289249869ac7bc5caAlex Deymo 32707c1779e51680364060f3ec289249869ac7bc5caAlex Deymovoid BaseMessageLoop::IOTask::OnFileReady() { 328d671746a66d87edf9598cfbe077b3430e50a09d3Alex Deymo // For file descriptors marked with the immediate_run flag, we don't call 329d671746a66d87edf9598cfbe077b3430e50a09d3Alex Deymo // StopWatching() and wait, instead we dispatch the callback immediately. 330d671746a66d87edf9598cfbe077b3430e50a09d3Alex Deymo if (immediate_run_) { 331d671746a66d87edf9598cfbe077b3430e50a09d3Alex Deymo posted_task_pending_ = true; 332d671746a66d87edf9598cfbe077b3430e50a09d3Alex Deymo OnFileReadyPostedTask(); 333d671746a66d87edf9598cfbe077b3430e50a09d3Alex Deymo return; 334d671746a66d87edf9598cfbe077b3430e50a09d3Alex Deymo } 335d671746a66d87edf9598cfbe077b3430e50a09d3Alex Deymo 33607c1779e51680364060f3ec289249869ac7bc5caAlex Deymo // When the file descriptor becomes available we stop watching for it and 33707c1779e51680364060f3ec289249869ac7bc5caAlex Deymo // schedule a task to run the callback from the main loop. The callback will 338d671746a66d87edf9598cfbe077b3430e50a09d3Alex Deymo // run using the same scheduler used to run other delayed tasks, avoiding 33907c1779e51680364060f3ec289249869ac7bc5caAlex Deymo // starvation of the available posted tasks if there are file descriptors 34007c1779e51680364060f3ec289249869ac7bc5caAlex Deymo // always available. The new posted task will use the same TaskId as the 34107c1779e51680364060f3ec289249869ac7bc5caAlex Deymo // current file descriptor watching task an could be canceled in either state, 34207c1779e51680364060f3ec289249869ac7bc5caAlex Deymo // when waiting for the file descriptor or waiting in the main loop. 34307c1779e51680364060f3ec289249869ac7bc5caAlex Deymo StopWatching(); 34407c1779e51680364060f3ec289249869ac7bc5caAlex Deymo bool base_scheduled = loop_->base_loop_->task_runner()->PostTask( 34507c1779e51680364060f3ec289249869ac7bc5caAlex Deymo location_, 34607c1779e51680364060f3ec289249869ac7bc5caAlex Deymo base::Bind(&BaseMessageLoop::OnFileReadyPostedTask, 34707c1779e51680364060f3ec289249869ac7bc5caAlex Deymo loop_->weak_ptr_factory_.GetWeakPtr(), 34807c1779e51680364060f3ec289249869ac7bc5caAlex Deymo task_id_)); 34907c1779e51680364060f3ec289249869ac7bc5caAlex Deymo posted_task_pending_ = true; 35007c1779e51680364060f3ec289249869ac7bc5caAlex Deymo if (base_scheduled) { 35107c1779e51680364060f3ec289249869ac7bc5caAlex Deymo DVLOG_LOC(location_, 1) 35207c1779e51680364060f3ec289249869ac7bc5caAlex Deymo << "Dispatching task_id " << task_id_ << " for " 35307c1779e51680364060f3ec289249869ac7bc5caAlex Deymo << (base_mode_ == base::MessageLoopForIO::WATCH_READ ? 35407c1779e51680364060f3ec289249869ac7bc5caAlex Deymo "reading" : "writing") 35507c1779e51680364060f3ec289249869ac7bc5caAlex Deymo << " file descriptor " << fd_ << ", scheduled from this location."; 35607c1779e51680364060f3ec289249869ac7bc5caAlex Deymo } else { 35707c1779e51680364060f3ec289249869ac7bc5caAlex Deymo // In the rare case that PostTask() fails, we fall back to run it directly. 35807c1779e51680364060f3ec289249869ac7bc5caAlex Deymo // This would indicate a bigger problem with the message loop setup. 35907c1779e51680364060f3ec289249869ac7bc5caAlex Deymo LOG(ERROR) << "Error on base::MessageLoopForIO::PostTask()."; 36007c1779e51680364060f3ec289249869ac7bc5caAlex Deymo OnFileReadyPostedTask(); 36107c1779e51680364060f3ec289249869ac7bc5caAlex Deymo } 362a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo} 363a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo 36407c1779e51680364060f3ec289249869ac7bc5caAlex Deymovoid BaseMessageLoop::IOTask::OnFileReadyPostedTask() { 365a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo // We can't access |this| after running the |closure_| since it could call 366a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo // CancelTask on its own task_id, so we copy the members we need now. 367a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo BaseMessageLoop* loop_ptr = loop_; 36807c1779e51680364060f3ec289249869ac7bc5caAlex Deymo DCHECK(posted_task_pending_ = true); 36907c1779e51680364060f3ec289249869ac7bc5caAlex Deymo posted_task_pending_ = false; 37007c1779e51680364060f3ec289249869ac7bc5caAlex Deymo 37107c1779e51680364060f3ec289249869ac7bc5caAlex Deymo // If this task was already canceled, the closure will be null and there is 37207c1779e51680364060f3ec289249869ac7bc5caAlex Deymo // nothing else to do here. This execution doesn't count a step for RunOnce() 37307c1779e51680364060f3ec289249869ac7bc5caAlex Deymo // unless we have a callback to run. 37407c1779e51680364060f3ec289249869ac7bc5caAlex Deymo if (closure_.is_null()) { 37507c1779e51680364060f3ec289249869ac7bc5caAlex Deymo loop_->io_tasks_.erase(task_id_); 37607c1779e51680364060f3ec289249869ac7bc5caAlex Deymo return; 37707c1779e51680364060f3ec289249869ac7bc5caAlex Deymo } 378a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo 379a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo DVLOG_LOC(location_, 1) 38007c1779e51680364060f3ec289249869ac7bc5caAlex Deymo << "Running task_id " << task_id_ << " for " 38107c1779e51680364060f3ec289249869ac7bc5caAlex Deymo << (base_mode_ == base::MessageLoopForIO::WATCH_READ ? 38207c1779e51680364060f3ec289249869ac7bc5caAlex Deymo "reading" : "writing") 38307c1779e51680364060f3ec289249869ac7bc5caAlex Deymo << " file descriptor " << fd_ << ", scheduled from this location."; 384a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo 385a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo if (persistent_) { 386a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo // In the persistent case we just run the callback. If this callback cancels 38707c1779e51680364060f3ec289249869ac7bc5caAlex Deymo // the task id, we can't access |this| anymore, so we re-start watching the 388d671746a66d87edf9598cfbe077b3430e50a09d3Alex Deymo // file descriptor before running the callback, unless this is a fd where 389d671746a66d87edf9598cfbe077b3430e50a09d3Alex Deymo // we didn't stop watching the file descriptor when it became available. 390d671746a66d87edf9598cfbe077b3430e50a09d3Alex Deymo if (!immediate_run_) 391d671746a66d87edf9598cfbe077b3430e50a09d3Alex Deymo StartWatching(); 392a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo closure_.Run(); 393a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo } else { 394a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo // This will destroy |this|, the fd_watcher and therefore stop watching this 395a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo // file descriptor. 396a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo Closure closure_copy = std::move(closure_); 397a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo loop_->io_tasks_.erase(task_id_); 398a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo // Run the closure from the local copy we just made. 399a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo closure_copy.Run(); 400a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo } 401a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo 402a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo if (loop_ptr->run_once_) { 403a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo loop_ptr->run_once_ = false; 40430ef318cd1d94e896a277324c68b89798e3dbbddAlex Deymo loop_ptr->BreakLoop(); 405a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo } 406a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo} 407a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo 40807c1779e51680364060f3ec289249869ac7bc5caAlex Deymobool BaseMessageLoop::IOTask::CancelTask() { 40907c1779e51680364060f3ec289249869ac7bc5caAlex Deymo if (closure_.is_null()) 41007c1779e51680364060f3ec289249869ac7bc5caAlex Deymo return false; 41107c1779e51680364060f3ec289249869ac7bc5caAlex Deymo 41207c1779e51680364060f3ec289249869ac7bc5caAlex Deymo DVLOG_LOC(location_, 1) 41307c1779e51680364060f3ec289249869ac7bc5caAlex Deymo << "Removing task_id " << task_id_ << " scheduled from this location."; 41407c1779e51680364060f3ec289249869ac7bc5caAlex Deymo 41507c1779e51680364060f3ec289249869ac7bc5caAlex Deymo if (!posted_task_pending_) { 41607c1779e51680364060f3ec289249869ac7bc5caAlex Deymo // Destroying the FileDescriptorWatcher implicitly stops watching the file 41707c1779e51680364060f3ec289249869ac7bc5caAlex Deymo // descriptor. This will delete our instance. 41807c1779e51680364060f3ec289249869ac7bc5caAlex Deymo loop_->io_tasks_.erase(task_id_); 41907c1779e51680364060f3ec289249869ac7bc5caAlex Deymo return true; 42007c1779e51680364060f3ec289249869ac7bc5caAlex Deymo } 42107c1779e51680364060f3ec289249869ac7bc5caAlex Deymo // The IOTask is waiting for the message loop to run its delayed task, so 42207c1779e51680364060f3ec289249869ac7bc5caAlex Deymo // it is not watching for the file descriptor. We release the closure 42307c1779e51680364060f3ec289249869ac7bc5caAlex Deymo // resources now but keep the IOTask instance alive while we wait for the 42407c1779e51680364060f3ec289249869ac7bc5caAlex Deymo // callback to run and delete the IOTask. 42507c1779e51680364060f3ec289249869ac7bc5caAlex Deymo closure_ = Closure(); 42607c1779e51680364060f3ec289249869ac7bc5caAlex Deymo return true; 42707c1779e51680364060f3ec289249869ac7bc5caAlex Deymo} 42807c1779e51680364060f3ec289249869ac7bc5caAlex Deymo 4299ed0cab99f18acb3570a35e9408f24355f6b8324Alex Vakulenko} // namespace brillo 430