base_message_loop.cc revision 922d235dca34496fd30e1b15b2bf24b4a6949288
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 44922d235dca34496fd30e1b15b2bf24b4a6949288Alex DeymoBaseMessageLoop::BaseMessageLoop() { 45922d235dca34496fd30e1b15b2bf24b4a6949288Alex Deymo CHECK(!base::MessageLoopForIO::current()) 46922d235dca34496fd30e1b15b2bf24b4a6949288Alex Deymo << "You can't create two MessageLoopForIO instances."; 47922d235dca34496fd30e1b15b2bf24b4a6949288Alex Deymo owned_base_loop_.reset(new base::MessageLoopForIO); 48922d235dca34496fd30e1b15b2bf24b4a6949288Alex Deymo base_loop_ = owned_base_loop_.get(); 49922d235dca34496fd30e1b15b2bf24b4a6949288Alex Deymo} 50922d235dca34496fd30e1b15b2bf24b4a6949288Alex Deymo 51a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex DeymoBaseMessageLoop::BaseMessageLoop(base::MessageLoopForIO* base_loop) 52922d235dca34496fd30e1b15b2bf24b4a6949288Alex Deymo : base_loop_(base_loop) {} 53a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo 54a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex DeymoBaseMessageLoop::~BaseMessageLoop() { 55a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo for (auto& io_task : io_tasks_) { 56a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo DVLOG_LOC(io_task.second.location(), 1) 57a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo << "Removing file descriptor watcher task_id " << io_task.first 58a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo << " leaked on BaseMessageLoop, scheduled from this location."; 5907c1779e51680364060f3ec289249869ac7bc5caAlex Deymo io_task.second.StopWatching(); 60a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo } 61a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo 62a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo // Note all pending canceled delayed tasks when destroying the message loop. 63a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo size_t lazily_deleted_tasks = 0; 64a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo for (const auto& delayed_task : delayed_tasks_) { 65a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo if (delayed_task.second.closure.is_null()) { 66a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo lazily_deleted_tasks++; 67a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo } else { 68a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo DVLOG_LOC(delayed_task.second.location, 1) 69a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo << "Removing delayed task_id " << delayed_task.first 70a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo << " leaked on BaseMessageLoop, scheduled from this location."; 71a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo } 72a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo } 73a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo if (lazily_deleted_tasks) { 74a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo LOG(INFO) << "Leaking " << lazily_deleted_tasks << " canceled tasks."; 75a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo } 76a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo} 77a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo 78a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex DeymoMessageLoop::TaskId BaseMessageLoop::PostDelayedTask( 79a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo const tracked_objects::Location& from_here, 80a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo const Closure &task, 81a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo base::TimeDelta delay) { 82a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo TaskId task_id = NextTaskId(); 83a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo bool base_scheduled = base_loop_->task_runner()->PostDelayedTask( 84a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo from_here, 85a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo base::Bind(&BaseMessageLoop::OnRanPostedTask, 86a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo weak_ptr_factory_.GetWeakPtr(), 87a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo task_id), 88a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo delay); 89a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo DVLOG_LOC(from_here, 1) << "Scheduling delayed task_id " << task_id 90a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo << " to run in " << delay << "."; 91a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo if (!base_scheduled) 92a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo return MessageLoop::kTaskIdNull; 93a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo 94a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo delayed_tasks_.emplace(task_id, 95a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo DelayedTask{from_here, task_id, std::move(task)}); 96a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo return task_id; 97a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo} 98a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo 99a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex DeymoMessageLoop::TaskId BaseMessageLoop::WatchFileDescriptor( 100a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo const tracked_objects::Location& from_here, 101a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo int fd, 102a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo WatchMode mode, 103a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo bool persistent, 104a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo const Closure &task) { 105a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo // base::MessageLoopForIO CHECKS that "fd >= 0", so we handle that case here. 106a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo if (fd < 0) 107a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo return MessageLoop::kTaskIdNull; 108a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo 109a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo base::MessageLoopForIO::Mode base_mode = base::MessageLoopForIO::WATCH_READ; 110a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo switch (mode) { 111a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo case MessageLoop::kWatchRead: 112a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo base_mode = base::MessageLoopForIO::WATCH_READ; 113a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo break; 114a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo case MessageLoop::kWatchWrite: 115a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo base_mode = base::MessageLoopForIO::WATCH_WRITE; 116a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo break; 117a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo default: 118a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo return MessageLoop::kTaskIdNull; 119a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo } 120a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo 121a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo TaskId task_id = NextTaskId(); 122a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo auto it_bool = io_tasks_.emplace( 123a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo std::piecewise_construct, 124a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo std::forward_as_tuple(task_id), 12507c1779e51680364060f3ec289249869ac7bc5caAlex Deymo std::forward_as_tuple( 12607c1779e51680364060f3ec289249869ac7bc5caAlex Deymo from_here, this, task_id, fd, base_mode, persistent, task)); 127a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo // This should always insert a new element. 128a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo DCHECK(it_bool.second); 12907c1779e51680364060f3ec289249869ac7bc5caAlex Deymo bool scheduled = it_bool.first->second.StartWatching(); 130a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo DVLOG_LOC(from_here, 1) 131a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo << "Watching fd " << fd << " for " 132a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo << (mode == MessageLoop::kWatchRead ? "reading" : "writing") 133a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo << (persistent ? " persistently" : " just once") 134a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo << " as task_id " << task_id 135a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo << (scheduled ? " successfully" : " failed."); 136a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo 137a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo if (!scheduled) { 138a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo io_tasks_.erase(task_id); 139a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo return MessageLoop::kTaskIdNull; 140a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo } 141d671746a66d87edf9598cfbe077b3430e50a09d3Alex Deymo 14277edc5357e1ff2c507a07d4c97f943910609ee44Alex Deymo#ifndef __ANDROID_HOST__ 143d671746a66d87edf9598cfbe077b3430e50a09d3Alex Deymo // Determine if the passed fd is the binder file descriptor. For that, we need 144d671746a66d87edf9598cfbe077b3430e50a09d3Alex Deymo // to check that is a special char device and that the major and minor device 145d671746a66d87edf9598cfbe077b3430e50a09d3Alex Deymo // numbers match. The binder file descriptor can't be removed and added back 146d671746a66d87edf9598cfbe077b3430e50a09d3Alex Deymo // to an epoll group when there's work available to be done by the file 147d671746a66d87edf9598cfbe077b3430e50a09d3Alex Deymo // descriptor due to bugs in the binder driver (b/26524111) when used with 148d671746a66d87edf9598cfbe077b3430e50a09d3Alex Deymo // epoll. Therefore, we flag the binder fd and never attempt to remove it. 149d671746a66d87edf9598cfbe077b3430e50a09d3Alex Deymo // This may cause the binder file descriptor to be attended with higher 150d671746a66d87edf9598cfbe077b3430e50a09d3Alex Deymo // priority and cause starvation of other events. 151d671746a66d87edf9598cfbe077b3430e50a09d3Alex Deymo struct stat buf; 152d671746a66d87edf9598cfbe077b3430e50a09d3Alex Deymo if (fstat(fd, &buf) == 0 && 153d671746a66d87edf9598cfbe077b3430e50a09d3Alex Deymo S_ISCHR(buf.st_mode) && 154d671746a66d87edf9598cfbe077b3430e50a09d3Alex Deymo major(buf.st_rdev) == MISC_MAJOR && 155d671746a66d87edf9598cfbe077b3430e50a09d3Alex Deymo minor(buf.st_rdev) == GetBinderMinor()) { 156d671746a66d87edf9598cfbe077b3430e50a09d3Alex Deymo it_bool.first->second.RunImmediately(); 157d671746a66d87edf9598cfbe077b3430e50a09d3Alex Deymo } 15877edc5357e1ff2c507a07d4c97f943910609ee44Alex Deymo#endif 159d671746a66d87edf9598cfbe077b3430e50a09d3Alex Deymo 160a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo return task_id; 161a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo} 162a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo 163a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymobool BaseMessageLoop::CancelTask(TaskId task_id) { 164a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo if (task_id == kTaskIdNull) 165a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo return false; 166a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo auto delayed_task_it = delayed_tasks_.find(task_id); 167a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo if (delayed_task_it == delayed_tasks_.end()) { 168a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo // This might be an IOTask then. 169a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo auto io_task_it = io_tasks_.find(task_id); 170a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo if (io_task_it == io_tasks_.end()) 171a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo return false; 17207c1779e51680364060f3ec289249869ac7bc5caAlex Deymo return io_task_it->second.CancelTask(); 173a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo } 174a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo // A DelayedTask was found for this task_id at this point. 175a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo 176a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo // Check if the callback was already canceled but we have the entry in 177a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo // delayed_tasks_ since it didn't fire yet in the message loop. 178a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo if (delayed_task_it->second.closure.is_null()) 179a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo return false; 180a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo 181a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo DVLOG_LOC(delayed_task_it->second.location, 1) 182a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo << "Removing task_id " << task_id << " scheduled from this location."; 183a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo // We reset to closure to a null Closure to release all the resources 184a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo // used by this closure at this point, but we don't remove the task_id from 185a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo // delayed_tasks_ since we can't tell base::MessageLoopForIO to not run it. 186a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo delayed_task_it->second.closure = Closure(); 187a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo 188a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo return true; 189a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo} 190a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo 191a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymobool BaseMessageLoop::RunOnce(bool may_block) { 192a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo run_once_ = true; 19330ef318cd1d94e896a277324c68b89798e3dbbddAlex Deymo base::RunLoop run_loop; // Uses the base::MessageLoopForIO implicitly. 19430ef318cd1d94e896a277324c68b89798e3dbbddAlex Deymo base_run_loop_ = &run_loop; 195a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo if (!may_block) 19630ef318cd1d94e896a277324c68b89798e3dbbddAlex Deymo run_loop.RunUntilIdle(); 197a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo else 19830ef318cd1d94e896a277324c68b89798e3dbbddAlex Deymo run_loop.Run(); 19930ef318cd1d94e896a277324c68b89798e3dbbddAlex Deymo base_run_loop_ = nullptr; 200a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo // If the flag was reset to false, it means a closure was run. 201a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo if (!run_once_) 202a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo return true; 203a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo 204a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo run_once_ = false; 205a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo return false; 206a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo} 207a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo 208a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymovoid BaseMessageLoop::Run() { 20930ef318cd1d94e896a277324c68b89798e3dbbddAlex Deymo base::RunLoop run_loop; // Uses the base::MessageLoopForIO implicitly. 21030ef318cd1d94e896a277324c68b89798e3dbbddAlex Deymo base_run_loop_ = &run_loop; 21130ef318cd1d94e896a277324c68b89798e3dbbddAlex Deymo run_loop.Run(); 21230ef318cd1d94e896a277324c68b89798e3dbbddAlex Deymo base_run_loop_ = nullptr; 213a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo} 214a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo 215a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymovoid BaseMessageLoop::BreakLoop() { 21630ef318cd1d94e896a277324c68b89798e3dbbddAlex Deymo if (base_run_loop_ == nullptr) { 21730ef318cd1d94e896a277324c68b89798e3dbbddAlex Deymo DVLOG(1) << "Message loop not running, ignoring BreakLoop()."; 21830ef318cd1d94e896a277324c68b89798e3dbbddAlex Deymo return; // Message loop not running, nothing to do. 21930ef318cd1d94e896a277324c68b89798e3dbbddAlex Deymo } 22030ef318cd1d94e896a277324c68b89798e3dbbddAlex Deymo base_run_loop_->Quit(); 22130ef318cd1d94e896a277324c68b89798e3dbbddAlex Deymo} 22230ef318cd1d94e896a277324c68b89798e3dbbddAlex Deymo 22330ef318cd1d94e896a277324c68b89798e3dbbddAlex DeymoClosure BaseMessageLoop::QuitClosure() const { 22430ef318cd1d94e896a277324c68b89798e3dbbddAlex Deymo if (base_run_loop_ == nullptr) 22530ef318cd1d94e896a277324c68b89798e3dbbddAlex Deymo return base::Bind(&base::DoNothing); 22630ef318cd1d94e896a277324c68b89798e3dbbddAlex Deymo return base_run_loop_->QuitClosure(); 227a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo} 228a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo 229a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex DeymoMessageLoop::TaskId BaseMessageLoop::NextTaskId() { 230a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo TaskId res; 231a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo do { 232a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo res = ++last_id_; 233a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo // We would run out of memory before we run out of task ids. 234a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo } while (!res || 235a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo delayed_tasks_.find(res) != delayed_tasks_.end() || 236a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo io_tasks_.find(res) != io_tasks_.end()); 237a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo return res; 238a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo} 239a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo 240a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymovoid BaseMessageLoop::OnRanPostedTask(MessageLoop::TaskId task_id) { 241a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo auto task_it = delayed_tasks_.find(task_id); 242a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo DCHECK(task_it != delayed_tasks_.end()); 243a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo if (!task_it->second.closure.is_null()) { 244a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo DVLOG_LOC(task_it->second.location, 1) 245a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo << "Running delayed task_id " << task_id 246a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo << " scheduled from this location."; 247a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo // Mark the task as canceled while we are running it so CancelTask returns 248a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo // false. 249a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo Closure closure = std::move(task_it->second.closure); 250a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo task_it->second.closure = Closure(); 251a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo closure.Run(); 252a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo 253a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo // If the |run_once_| flag is set, it is because we are instructed to run 254a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo // only once callback. 255a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo if (run_once_) { 256a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo run_once_ = false; 25730ef318cd1d94e896a277324c68b89798e3dbbddAlex Deymo BreakLoop(); 258a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo } 259a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo } 260a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo delayed_tasks_.erase(task_it); 261a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo} 262a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo 26307c1779e51680364060f3ec289249869ac7bc5caAlex Deymovoid BaseMessageLoop::OnFileReadyPostedTask(MessageLoop::TaskId task_id) { 26407c1779e51680364060f3ec289249869ac7bc5caAlex Deymo auto task_it = io_tasks_.find(task_id); 26507c1779e51680364060f3ec289249869ac7bc5caAlex Deymo // Even if this task was canceled while we were waiting in the message loop 26607c1779e51680364060f3ec289249869ac7bc5caAlex Deymo // for this method to run, the entry in io_tasks_ should still be present, but 26707c1779e51680364060f3ec289249869ac7bc5caAlex Deymo // won't do anything. 26807c1779e51680364060f3ec289249869ac7bc5caAlex Deymo DCHECK(task_it != io_tasks_.end()); 26907c1779e51680364060f3ec289249869ac7bc5caAlex Deymo task_it->second.OnFileReadyPostedTask(); 27007c1779e51680364060f3ec289249869ac7bc5caAlex Deymo} 27107c1779e51680364060f3ec289249869ac7bc5caAlex Deymo 272d671746a66d87edf9598cfbe077b3430e50a09d3Alex Deymoint BaseMessageLoop::ParseBinderMinor( 273d671746a66d87edf9598cfbe077b3430e50a09d3Alex Deymo const std::string& file_contents) { 274d671746a66d87edf9598cfbe077b3430e50a09d3Alex Deymo int result = kInvalidMinor; 275d671746a66d87edf9598cfbe077b3430e50a09d3Alex Deymo // Split along '\n', then along the ' '. Note that base::SplitString trims all 276d671746a66d87edf9598cfbe077b3430e50a09d3Alex Deymo // white spaces at the beginning and end after splitting. 277922d235dca34496fd30e1b15b2bf24b4a6949288Alex Deymo std::vector<std::string> lines = 27880b7ee94e36e2d25a97a262d3b558bbf130c2a01Alex Vakulenko base::SplitString(file_contents, "\n", base::TRIM_WHITESPACE, 27980b7ee94e36e2d25a97a262d3b558bbf130c2a01Alex Vakulenko base::SPLIT_WANT_ALL); 280d671746a66d87edf9598cfbe077b3430e50a09d3Alex Deymo for (const std::string& line : lines) { 281d671746a66d87edf9598cfbe077b3430e50a09d3Alex Deymo if (line.empty()) 282d671746a66d87edf9598cfbe077b3430e50a09d3Alex Deymo continue; 283d671746a66d87edf9598cfbe077b3430e50a09d3Alex Deymo std::string number; 284d671746a66d87edf9598cfbe077b3430e50a09d3Alex Deymo std::string name; 285d671746a66d87edf9598cfbe077b3430e50a09d3Alex Deymo if (!string_utils::SplitAtFirst(line, " ", &number, &name, false)) 286d671746a66d87edf9598cfbe077b3430e50a09d3Alex Deymo continue; 287d671746a66d87edf9598cfbe077b3430e50a09d3Alex Deymo 288d671746a66d87edf9598cfbe077b3430e50a09d3Alex Deymo if (name == kBinderDriverName && base::StringToInt(number, &result)) 289d671746a66d87edf9598cfbe077b3430e50a09d3Alex Deymo break; 290d671746a66d87edf9598cfbe077b3430e50a09d3Alex Deymo } 291d671746a66d87edf9598cfbe077b3430e50a09d3Alex Deymo return result; 292d671746a66d87edf9598cfbe077b3430e50a09d3Alex Deymo} 293d671746a66d87edf9598cfbe077b3430e50a09d3Alex Deymo 294d671746a66d87edf9598cfbe077b3430e50a09d3Alex Deymounsigned int BaseMessageLoop::GetBinderMinor() { 295d671746a66d87edf9598cfbe077b3430e50a09d3Alex Deymo if (binder_minor_ != kUninitializedMinor) 296d671746a66d87edf9598cfbe077b3430e50a09d3Alex Deymo return binder_minor_; 297d671746a66d87edf9598cfbe077b3430e50a09d3Alex Deymo 298d671746a66d87edf9598cfbe077b3430e50a09d3Alex Deymo std::string proc_misc; 299d671746a66d87edf9598cfbe077b3430e50a09d3Alex Deymo if (!base::ReadFileToString(base::FilePath(kMiscMinorPath), &proc_misc)) 300d671746a66d87edf9598cfbe077b3430e50a09d3Alex Deymo return binder_minor_; 301d671746a66d87edf9598cfbe077b3430e50a09d3Alex Deymo binder_minor_ = ParseBinderMinor(proc_misc); 302d671746a66d87edf9598cfbe077b3430e50a09d3Alex Deymo return binder_minor_; 303d671746a66d87edf9598cfbe077b3430e50a09d3Alex Deymo} 304d671746a66d87edf9598cfbe077b3430e50a09d3Alex Deymo 305a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex DeymoBaseMessageLoop::IOTask::IOTask(const tracked_objects::Location& location, 306a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo BaseMessageLoop* loop, 307a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo MessageLoop::TaskId task_id, 30807c1779e51680364060f3ec289249869ac7bc5caAlex Deymo int fd, 30907c1779e51680364060f3ec289249869ac7bc5caAlex Deymo base::MessageLoopForIO::Mode base_mode, 310a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo bool persistent, 311a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo const Closure& task) 312a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo : location_(location), loop_(loop), task_id_(task_id), 31307c1779e51680364060f3ec289249869ac7bc5caAlex Deymo fd_(fd), base_mode_(base_mode), persistent_(persistent), closure_(task) {} 314a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo 31507c1779e51680364060f3ec289249869ac7bc5caAlex Deymobool BaseMessageLoop::IOTask::StartWatching() { 31607c1779e51680364060f3ec289249869ac7bc5caAlex Deymo return loop_->base_loop_->WatchFileDescriptor( 31707c1779e51680364060f3ec289249869ac7bc5caAlex Deymo fd_, persistent_, base_mode_, &fd_watcher_, this); 318a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo} 319a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo 32007c1779e51680364060f3ec289249869ac7bc5caAlex Deymovoid BaseMessageLoop::IOTask::StopWatching() { 32107c1779e51680364060f3ec289249869ac7bc5caAlex Deymo // This is safe to call even if we are not watching for it. 32207c1779e51680364060f3ec289249869ac7bc5caAlex Deymo fd_watcher_.StopWatchingFileDescriptor(); 32307c1779e51680364060f3ec289249869ac7bc5caAlex Deymo} 32407c1779e51680364060f3ec289249869ac7bc5caAlex Deymo 32507c1779e51680364060f3ec289249869ac7bc5caAlex Deymovoid BaseMessageLoop::IOTask::OnFileCanReadWithoutBlocking(int /* fd */) { 32607c1779e51680364060f3ec289249869ac7bc5caAlex Deymo OnFileReady(); 32707c1779e51680364060f3ec289249869ac7bc5caAlex Deymo} 32807c1779e51680364060f3ec289249869ac7bc5caAlex Deymo 32907c1779e51680364060f3ec289249869ac7bc5caAlex Deymovoid BaseMessageLoop::IOTask::OnFileCanWriteWithoutBlocking(int /* fd */) { 33007c1779e51680364060f3ec289249869ac7bc5caAlex Deymo OnFileReady(); 33107c1779e51680364060f3ec289249869ac7bc5caAlex Deymo} 33207c1779e51680364060f3ec289249869ac7bc5caAlex Deymo 33307c1779e51680364060f3ec289249869ac7bc5caAlex Deymovoid BaseMessageLoop::IOTask::OnFileReady() { 334d671746a66d87edf9598cfbe077b3430e50a09d3Alex Deymo // For file descriptors marked with the immediate_run flag, we don't call 335d671746a66d87edf9598cfbe077b3430e50a09d3Alex Deymo // StopWatching() and wait, instead we dispatch the callback immediately. 336d671746a66d87edf9598cfbe077b3430e50a09d3Alex Deymo if (immediate_run_) { 337d671746a66d87edf9598cfbe077b3430e50a09d3Alex Deymo posted_task_pending_ = true; 338d671746a66d87edf9598cfbe077b3430e50a09d3Alex Deymo OnFileReadyPostedTask(); 339d671746a66d87edf9598cfbe077b3430e50a09d3Alex Deymo return; 340d671746a66d87edf9598cfbe077b3430e50a09d3Alex Deymo } 341d671746a66d87edf9598cfbe077b3430e50a09d3Alex Deymo 34207c1779e51680364060f3ec289249869ac7bc5caAlex Deymo // When the file descriptor becomes available we stop watching for it and 34307c1779e51680364060f3ec289249869ac7bc5caAlex Deymo // schedule a task to run the callback from the main loop. The callback will 344d671746a66d87edf9598cfbe077b3430e50a09d3Alex Deymo // run using the same scheduler used to run other delayed tasks, avoiding 34507c1779e51680364060f3ec289249869ac7bc5caAlex Deymo // starvation of the available posted tasks if there are file descriptors 34607c1779e51680364060f3ec289249869ac7bc5caAlex Deymo // always available. The new posted task will use the same TaskId as the 34707c1779e51680364060f3ec289249869ac7bc5caAlex Deymo // current file descriptor watching task an could be canceled in either state, 34807c1779e51680364060f3ec289249869ac7bc5caAlex Deymo // when waiting for the file descriptor or waiting in the main loop. 34907c1779e51680364060f3ec289249869ac7bc5caAlex Deymo StopWatching(); 35007c1779e51680364060f3ec289249869ac7bc5caAlex Deymo bool base_scheduled = loop_->base_loop_->task_runner()->PostTask( 35107c1779e51680364060f3ec289249869ac7bc5caAlex Deymo location_, 35207c1779e51680364060f3ec289249869ac7bc5caAlex Deymo base::Bind(&BaseMessageLoop::OnFileReadyPostedTask, 35307c1779e51680364060f3ec289249869ac7bc5caAlex Deymo loop_->weak_ptr_factory_.GetWeakPtr(), 35407c1779e51680364060f3ec289249869ac7bc5caAlex Deymo task_id_)); 35507c1779e51680364060f3ec289249869ac7bc5caAlex Deymo posted_task_pending_ = true; 35607c1779e51680364060f3ec289249869ac7bc5caAlex Deymo if (base_scheduled) { 35707c1779e51680364060f3ec289249869ac7bc5caAlex Deymo DVLOG_LOC(location_, 1) 35807c1779e51680364060f3ec289249869ac7bc5caAlex Deymo << "Dispatching task_id " << task_id_ << " for " 35907c1779e51680364060f3ec289249869ac7bc5caAlex Deymo << (base_mode_ == base::MessageLoopForIO::WATCH_READ ? 36007c1779e51680364060f3ec289249869ac7bc5caAlex Deymo "reading" : "writing") 36107c1779e51680364060f3ec289249869ac7bc5caAlex Deymo << " file descriptor " << fd_ << ", scheduled from this location."; 36207c1779e51680364060f3ec289249869ac7bc5caAlex Deymo } else { 36307c1779e51680364060f3ec289249869ac7bc5caAlex Deymo // In the rare case that PostTask() fails, we fall back to run it directly. 36407c1779e51680364060f3ec289249869ac7bc5caAlex Deymo // This would indicate a bigger problem with the message loop setup. 36507c1779e51680364060f3ec289249869ac7bc5caAlex Deymo LOG(ERROR) << "Error on base::MessageLoopForIO::PostTask()."; 36607c1779e51680364060f3ec289249869ac7bc5caAlex Deymo OnFileReadyPostedTask(); 36707c1779e51680364060f3ec289249869ac7bc5caAlex Deymo } 368a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo} 369a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo 37007c1779e51680364060f3ec289249869ac7bc5caAlex Deymovoid BaseMessageLoop::IOTask::OnFileReadyPostedTask() { 371a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo // We can't access |this| after running the |closure_| since it could call 372a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo // CancelTask on its own task_id, so we copy the members we need now. 373a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo BaseMessageLoop* loop_ptr = loop_; 37407c1779e51680364060f3ec289249869ac7bc5caAlex Deymo DCHECK(posted_task_pending_ = true); 37507c1779e51680364060f3ec289249869ac7bc5caAlex Deymo posted_task_pending_ = false; 37607c1779e51680364060f3ec289249869ac7bc5caAlex Deymo 37707c1779e51680364060f3ec289249869ac7bc5caAlex Deymo // If this task was already canceled, the closure will be null and there is 37807c1779e51680364060f3ec289249869ac7bc5caAlex Deymo // nothing else to do here. This execution doesn't count a step for RunOnce() 37907c1779e51680364060f3ec289249869ac7bc5caAlex Deymo // unless we have a callback to run. 38007c1779e51680364060f3ec289249869ac7bc5caAlex Deymo if (closure_.is_null()) { 38107c1779e51680364060f3ec289249869ac7bc5caAlex Deymo loop_->io_tasks_.erase(task_id_); 38207c1779e51680364060f3ec289249869ac7bc5caAlex Deymo return; 38307c1779e51680364060f3ec289249869ac7bc5caAlex Deymo } 384a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo 385a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo DVLOG_LOC(location_, 1) 38607c1779e51680364060f3ec289249869ac7bc5caAlex Deymo << "Running task_id " << task_id_ << " for " 38707c1779e51680364060f3ec289249869ac7bc5caAlex Deymo << (base_mode_ == base::MessageLoopForIO::WATCH_READ ? 38807c1779e51680364060f3ec289249869ac7bc5caAlex Deymo "reading" : "writing") 38907c1779e51680364060f3ec289249869ac7bc5caAlex Deymo << " file descriptor " << fd_ << ", scheduled from this location."; 390a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo 391a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo if (persistent_) { 392a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo // In the persistent case we just run the callback. If this callback cancels 39307c1779e51680364060f3ec289249869ac7bc5caAlex Deymo // the task id, we can't access |this| anymore, so we re-start watching the 394d671746a66d87edf9598cfbe077b3430e50a09d3Alex Deymo // file descriptor before running the callback, unless this is a fd where 395d671746a66d87edf9598cfbe077b3430e50a09d3Alex Deymo // we didn't stop watching the file descriptor when it became available. 396d671746a66d87edf9598cfbe077b3430e50a09d3Alex Deymo if (!immediate_run_) 397d671746a66d87edf9598cfbe077b3430e50a09d3Alex Deymo StartWatching(); 398a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo closure_.Run(); 399a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo } else { 400a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo // This will destroy |this|, the fd_watcher and therefore stop watching this 401a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo // file descriptor. 402a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo Closure closure_copy = std::move(closure_); 403a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo loop_->io_tasks_.erase(task_id_); 404a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo // Run the closure from the local copy we just made. 405a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo closure_copy.Run(); 406a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo } 407a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo 408a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo if (loop_ptr->run_once_) { 409a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo loop_ptr->run_once_ = false; 41030ef318cd1d94e896a277324c68b89798e3dbbddAlex Deymo loop_ptr->BreakLoop(); 411a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo } 412a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo} 413a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo 41407c1779e51680364060f3ec289249869ac7bc5caAlex Deymobool BaseMessageLoop::IOTask::CancelTask() { 41507c1779e51680364060f3ec289249869ac7bc5caAlex Deymo if (closure_.is_null()) 41607c1779e51680364060f3ec289249869ac7bc5caAlex Deymo return false; 41707c1779e51680364060f3ec289249869ac7bc5caAlex Deymo 41807c1779e51680364060f3ec289249869ac7bc5caAlex Deymo DVLOG_LOC(location_, 1) 41907c1779e51680364060f3ec289249869ac7bc5caAlex Deymo << "Removing task_id " << task_id_ << " scheduled from this location."; 42007c1779e51680364060f3ec289249869ac7bc5caAlex Deymo 42107c1779e51680364060f3ec289249869ac7bc5caAlex Deymo if (!posted_task_pending_) { 42207c1779e51680364060f3ec289249869ac7bc5caAlex Deymo // Destroying the FileDescriptorWatcher implicitly stops watching the file 42307c1779e51680364060f3ec289249869ac7bc5caAlex Deymo // descriptor. This will delete our instance. 42407c1779e51680364060f3ec289249869ac7bc5caAlex Deymo loop_->io_tasks_.erase(task_id_); 42507c1779e51680364060f3ec289249869ac7bc5caAlex Deymo return true; 42607c1779e51680364060f3ec289249869ac7bc5caAlex Deymo } 42707c1779e51680364060f3ec289249869ac7bc5caAlex Deymo // The IOTask is waiting for the message loop to run its delayed task, so 42807c1779e51680364060f3ec289249869ac7bc5caAlex Deymo // it is not watching for the file descriptor. We release the closure 42907c1779e51680364060f3ec289249869ac7bc5caAlex Deymo // resources now but keep the IOTask instance alive while we wait for the 43007c1779e51680364060f3ec289249869ac7bc5caAlex Deymo // callback to run and delete the IOTask. 43107c1779e51680364060f3ec289249869ac7bc5caAlex Deymo closure_ = Closure(); 43207c1779e51680364060f3ec289249869ac7bc5caAlex Deymo return true; 43307c1779e51680364060f3ec289249869ac7bc5caAlex Deymo} 43407c1779e51680364060f3ec289249869ac7bc5caAlex Deymo 4359ed0cab99f18acb3570a35e9408f24355f6b8324Alex Vakulenko} // namespace brillo 436