Index: chrome/browser/chromeos/memory/low_memory_observer.cc |
diff --git a/chrome/browser/chromeos/memory/low_memory_observer.cc b/chrome/browser/chromeos/memory/low_memory_observer.cc |
deleted file mode 100644 |
index fbbb3fd7c7a5bb37850443cdabbddbdabacd1771..0000000000000000000000000000000000000000 |
--- a/chrome/browser/chromeos/memory/low_memory_observer.cc |
+++ /dev/null |
@@ -1,191 +0,0 @@ |
-// Copyright (c) 2012 The Chromium Authors. All rights reserved. |
-// Use of this source code is governed by a BSD-style license that can be |
-// found in the LICENSE file. |
- |
-#include "chrome/browser/chromeos/memory/low_memory_observer.h" |
- |
-#include <fcntl.h> |
- |
-#include "base/bind.h" |
-#include "base/memory/scoped_ptr.h" |
-#include "base/message_loop/message_loop.h" |
-#include "base/sys_info.h" |
-#include "base/time/time.h" |
-#include "base/timer/timer.h" |
-#include "chrome/browser/browser_process.h" |
-#include "chrome/browser/browser_process_platform_part_chromeos.h" |
-#include "chrome/browser/chromeos/memory/oom_priority_manager.h" |
-#include "content/public/browser/browser_thread.h" |
- |
-using content::BrowserThread; |
- |
-namespace chromeos { |
- |
-namespace { |
-// This is the file that will exist if low memory notification is available |
-// on the device. Whenever it becomes readable, it signals a low memory |
-// condition. |
-const char kLowMemFile[] = "/dev/chromeos-low-mem"; |
- |
-// This is the minimum amount of time in milliseconds between checks for |
-// low memory. |
-const int kLowMemoryCheckTimeoutMs = 750; |
-} // namespace |
- |
-//////////////////////////////////////////////////////////////////////////////// |
-// LowMemoryObserverImpl |
-// |
-// Does the actual work of observing. The observation work happens on the FILE |
-// thread, and the discarding of tabs happens on the UI thread. |
-// If low memory is detected, then we discard a tab, wait |
-// kLowMemoryCheckTimeoutMs milliseconds and then start watching again to see |
-// if we're still in a low memory state. This is to keep from discarding all |
-// tabs the first time we enter the state, because it takes time for the |
-// tabs to deallocate their memory. A timer isn't the perfect solution, but |
-// without any reliable indicator that a tab has had all its parts deallocated, |
-// it's the next best thing. |
-class LowMemoryObserverImpl |
- : public base::RefCountedThreadSafe<LowMemoryObserverImpl> { |
- public: |
- LowMemoryObserverImpl() : watcher_delegate_(this), file_descriptor_(-1) {} |
- |
- // Start watching the low memory file for readability. |
- // Calls to StartObserving should always be matched with calls to |
- // StopObserving. This method should only be called from the FILE thread. |
- void StartObservingOnFileThread(); |
- |
- // Stop watching the low memory file for readability. |
- // May be safely called if StartObserving has not been called. |
- // This method should only be called from the FILE thread. |
- void StopObservingOnFileThread(); |
- |
- private: |
- friend class base::RefCountedThreadSafe<LowMemoryObserverImpl>; |
- |
- ~LowMemoryObserverImpl() { |
- StopObservingOnFileThread(); |
- } |
- |
- // Start a timer to resume watching the low memory file descriptor. |
- void ScheduleNextObservation(); |
- |
- // Actually start watching the file descriptor. |
- void StartWatchingDescriptor(); |
- |
- // Delegate to receive events from WatchFileDescriptor. |
- class FileWatcherDelegate : public base::MessageLoopForIO::Watcher { |
- public: |
- explicit FileWatcherDelegate(LowMemoryObserverImpl* owner) |
- : owner_(owner) {} |
- ~FileWatcherDelegate() override {} |
- |
- // Overrides for base::MessageLoopForIO::Watcher |
- void OnFileCanWriteWithoutBlocking(int fd) override {} |
- void OnFileCanReadWithoutBlocking(int fd) override { |
- LOG(WARNING) << "Low memory condition detected. Discarding a tab."; |
- // We can only discard tabs on the UI thread. |
- base::Callback<void(void)> callback = base::Bind(&DiscardTab); |
- BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, callback); |
- owner_->ScheduleNextObservation(); |
- } |
- |
- // Sends off a discard request to the OomPriorityManager. Must be run on |
- // the UI thread. |
- static void DiscardTab() { |
- CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
- if (g_browser_process && |
- g_browser_process->platform_part()->oom_priority_manager()) { |
- g_browser_process->platform_part()-> |
- oom_priority_manager()->LogMemoryAndDiscardTab(); |
- } |
- } |
- |
- private: |
- LowMemoryObserverImpl* owner_; |
- DISALLOW_COPY_AND_ASSIGN(FileWatcherDelegate); |
- }; |
- |
- scoped_ptr<base::MessageLoopForIO::FileDescriptorWatcher> watcher_; |
- FileWatcherDelegate watcher_delegate_; |
- int file_descriptor_; |
- base::OneShotTimer<LowMemoryObserverImpl> timer_; |
- |
- DISALLOW_COPY_AND_ASSIGN(LowMemoryObserverImpl); |
-}; |
- |
-void LowMemoryObserverImpl::StartObservingOnFileThread() { |
- DCHECK_LE(file_descriptor_, 0) |
- << "Attempted to start observation when it was already started."; |
- DCHECK(watcher_.get() == NULL); |
- DCHECK_CURRENTLY_ON(BrowserThread::FILE); |
- DCHECK(base::MessageLoopForIO::current()); |
- |
- file_descriptor_ = ::open(kLowMemFile, O_RDONLY); |
- // Don't report this error unless we're really running on ChromeOS |
- // to avoid testing spam. |
- if (file_descriptor_ < 0 && base::SysInfo::IsRunningOnChromeOS()) { |
- PLOG(ERROR) << "Unable to open " << kLowMemFile; |
- return; |
- } |
- watcher_.reset(new base::MessageLoopForIO::FileDescriptorWatcher); |
- StartWatchingDescriptor(); |
-} |
- |
-void LowMemoryObserverImpl::StopObservingOnFileThread() { |
- // If StartObserving failed, StopObserving will still get called. |
- timer_.Stop(); |
- if (file_descriptor_ >= 0) { |
- DCHECK_CURRENTLY_ON(BrowserThread::FILE); |
- watcher_.reset(NULL); |
- ::close(file_descriptor_); |
- file_descriptor_ = -1; |
- } |
-} |
- |
-void LowMemoryObserverImpl::ScheduleNextObservation() { |
- timer_.Start(FROM_HERE, |
- base::TimeDelta::FromMilliseconds(kLowMemoryCheckTimeoutMs), |
- this, |
- &LowMemoryObserverImpl::StartWatchingDescriptor); |
-} |
- |
-void LowMemoryObserverImpl::StartWatchingDescriptor() { |
- DCHECK(watcher_.get()); |
- DCHECK_CURRENTLY_ON(BrowserThread::FILE); |
- DCHECK(base::MessageLoopForIO::current()); |
- if (file_descriptor_ < 0) |
- return; |
- if (!base::MessageLoopForIO::current()->WatchFileDescriptor( |
- file_descriptor_, |
- false, // persistent=false: We want it to fire once and reschedule. |
- base::MessageLoopForIO::WATCH_READ, |
- watcher_.get(), |
- &watcher_delegate_)) { |
- LOG(ERROR) << "Unable to watch " << kLowMemFile; |
- } |
-} |
- |
-//////////////////////////////////////////////////////////////////////////////// |
-// LowMemoryObserver |
- |
-LowMemoryObserver::LowMemoryObserver() : observer_(new LowMemoryObserverImpl) {} |
- |
-LowMemoryObserver::~LowMemoryObserver() { Stop(); } |
- |
-void LowMemoryObserver::Start() { |
- BrowserThread::PostTask( |
- BrowserThread::FILE, |
- FROM_HERE, |
- base::Bind(&LowMemoryObserverImpl::StartObservingOnFileThread, |
- observer_.get())); |
-} |
- |
-void LowMemoryObserver::Stop() { |
- BrowserThread::PostTask( |
- BrowserThread::FILE, |
- FROM_HERE, |
- base::Bind(&LowMemoryObserverImpl::StopObservingOnFileThread, |
- observer_.get())); |
-} |
- |
-} // namespace chromeos |