1From e18f110107399803dd070088c601f9a5540a2a3f Mon Sep 17 00:00:00 2001 2From: Hidehiko Abe <hidehiko@chromium.org> 3Date: Thu, 3 Oct 2019 02:04:53 +0900 4Subject: [PATCH] components/timers: fix fd leak in AlarmTimer 5 6This is fixed upstream but will take a while to roll back 7into Chrome OS. 8 9BUG=chromium:984593 10TEST=enable/disable wifi repeatedly and see that there is no 11 growth of open timerfds 12 13Change-Id: If2af8f8ddf6b9dc31cda36fe5f5454ca0c5819de 14--- 15 components/timers/alarm_timer_chromeos.cc | 8 ++++---- 16 components/timers/alarm_timer_chromeos.h | 15 ++++++++------- 17 2 files changed, 12 insertions(+), 11 deletions(-) 18 19diff --git a/components/timers/alarm_timer_chromeos.cc b/components/timers/alarm_timer_chromeos.cc 20index 0b43134..f14d889 100644 21--- a/components/timers/alarm_timer_chromeos.cc 22+++ b/components/timers/alarm_timer_chromeos.cc 23@@ -80,7 +80,7 @@ void SimpleAlarmTimer::Reset() { 24 alarm_time.it_value.tv_nsec = 25 (delay.InMicroseconds() % base::Time::kMicrosecondsPerSecond) * 26 base::Time::kNanosecondsPerMicrosecond; 27- if (timerfd_settime(alarm_fd_, 0, &alarm_time, NULL) < 0) 28+ if (timerfd_settime(alarm_fd_.get(), 0, &alarm_time, NULL) < 0) 29 PLOG(ERROR) << "Error while setting alarm time. Timer will not fire"; 30 31 // The timer is running. 32@@ -97,7 +97,7 @@ void SimpleAlarmTimer::Reset() { 33 base::debug::TaskAnnotator().WillQueueTask("SimpleAlarmTimer::Reset", 34 pending_task_.get()); 35 alarm_fd_watcher_ = base::FileDescriptorWatcher::WatchReadable( 36- alarm_fd_, 37+ alarm_fd_.get(), 38 base::BindRepeating(&SimpleAlarmTimer::OnAlarmFdReadableWithoutBlocking, 39 weak_factory_.GetWeakPtr())); 40 } 41@@ -109,7 +109,7 @@ void SimpleAlarmTimer::OnAlarmFdReadableWithoutBlocking() { 42 43 // Read from |alarm_fd_| to ack the event. 44 char val[sizeof(uint64_t)]; 45- if (!base::ReadFromFD(alarm_fd_, val, sizeof(uint64_t))) 46+ if (!base::ReadFromFD(alarm_fd_.get(), val, sizeof(uint64_t))) 47 PLOG(DFATAL) << "Unable to read from timer file descriptor."; 48 49 OnTimerFired(); 50@@ -137,7 +137,7 @@ void SimpleAlarmTimer::OnTimerFired() { 51 } 52 53 bool SimpleAlarmTimer::CanWakeFromSuspend() const { 54- return alarm_fd_ != -1; 55+ return alarm_fd_.is_valid(); 56 } 57 58 } // namespace timers 59diff --git a/components/timers/alarm_timer_chromeos.h b/components/timers/alarm_timer_chromeos.h 60index 1ff689e..100ba81 100644 61--- a/components/timers/alarm_timer_chromeos.h 62+++ b/components/timers/alarm_timer_chromeos.h 63@@ -8,6 +8,7 @@ 64 #include <memory> 65 66 #include "base/files/file_descriptor_watcher_posix.h" 67+#include "base/files/scoped_file.h" 68 #include "base/macros.h" 69 #include "base/memory/scoped_refptr.h" 70 #include "base/memory/weak_ptr.h" 71@@ -43,6 +44,12 @@ class SimpleAlarmTimer : public base::RetainingOneShotTimer { 72 void Stop() override; 73 void Reset() override; 74 75+ // Tracks whether the timer has the ability to wake the system up from 76+ // suspend. This is a runtime check because we won't know if the system 77+ // supports being woken up from suspend until the constructor actually tries 78+ // to set it up. 79+ bool CanWakeFromSuspend() const; 80+ 81 private: 82 // Called when |alarm_fd_| is readable without blocking. Reads data from 83 // |alarm_fd_| and calls OnTimerFired(). 84@@ -51,14 +58,8 @@ class SimpleAlarmTimer : public base::RetainingOneShotTimer { 85 // Called when the timer fires. Runs the callback. 86 void OnTimerFired(); 87 88- // Tracks whether the timer has the ability to wake the system up from 89- // suspend. This is a runtime check because we won't know if the system 90- // supports being woken up from suspend until the constructor actually tries 91- // to set it up. 92- bool CanWakeFromSuspend() const; 93- 94 // Timer file descriptor. 95- const int alarm_fd_; 96+ base::ScopedFD alarm_fd_; 97 98 // Watches |alarm_fd_|. 99 std::unique_ptr<base::FileDescriptorWatcher::Controller> alarm_fd_watcher_; 100-- 1012.23.0.581.g78d2f28ef7-goog 102 103