1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */ 3 /* This Source Code Form is subject to the terms of the Mozilla Public 4 * License, v. 2.0. If a copy of the MPL was not distributed with this 5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 7 #include "AvailableMemoryWatcher.h" 8 9 #include "mozilla/ClearOnShutdown.h" 10 #include "mozilla/dom/Promise.h" 11 #include "mozilla/ErrorResult.h" 12 #include "mozilla/RefPtr.h" 13 #include "mozilla/StaticPtr.h" 14 #include "nsMemoryPressure.h" 15 #include "nsXULAppAPI.h" 16 17 namespace mozilla { 18 19 // Use this class as the initial value of 20 // nsAvailableMemoryWatcherBase::mCallback until RegisterCallback() is called 21 // so that nsAvailableMemoryWatcherBase does not have to check if its callback 22 // object is valid or not. 23 class NullTabUnloader final : public nsITabUnloader { 24 ~NullTabUnloader() = default; 25 26 public: 27 NullTabUnloader() = default; 28 29 NS_DECL_ISUPPORTS 30 NS_DECL_NSITABUNLOADER 31 }; 32 NS_IMPL_ISUPPORTS(NullTabUnloader,nsITabUnloader)33NS_IMPL_ISUPPORTS(NullTabUnloader, nsITabUnloader) 34 35 NS_IMETHODIMP NullTabUnloader::UnloadTabAsync() { 36 return NS_ERROR_NOT_IMPLEMENTED; 37 } 38 39 StaticRefPtr<nsAvailableMemoryWatcherBase> 40 nsAvailableMemoryWatcherBase::sSingleton; 41 42 /*static*/ 43 already_AddRefed<nsAvailableMemoryWatcherBase> GetSingleton()44nsAvailableMemoryWatcherBase::GetSingleton() { 45 if (!sSingleton) { 46 sSingleton = CreateAvailableMemoryWatcher(); 47 ClearOnShutdown(&sSingleton); 48 } 49 50 return do_AddRef(sSingleton); 51 } 52 53 NS_IMPL_ISUPPORTS(nsAvailableMemoryWatcherBase, nsIAvailableMemoryWatcherBase); 54 nsAvailableMemoryWatcherBase()55nsAvailableMemoryWatcherBase::nsAvailableMemoryWatcherBase() 56 : mTabUnloader(new NullTabUnloader) { 57 MOZ_ASSERT(XRE_IsParentProcess(), 58 "Watching memory only in the main process."); 59 } 60 RegisterTabUnloader(nsITabUnloader * aTabUnloader)61nsresult nsAvailableMemoryWatcherBase::RegisterTabUnloader( 62 nsITabUnloader* aTabUnloader) { 63 mTabUnloader = aTabUnloader; 64 return NS_OK; 65 } 66 OnUnloadAttemptCompleted(nsresult aResult)67nsresult nsAvailableMemoryWatcherBase::OnUnloadAttemptCompleted( 68 nsresult aResult) { 69 if (aResult == NS_ERROR_NOT_AVAILABLE) { 70 // If there was no unloadable tab, declare the memory-pressure 71 NS_NotifyOfEventualMemoryPressure(MemoryPressureState::LowMemory); 72 } 73 return NS_OK; 74 } 75 76 // Define the fallback method for a platform for which a platform-specific 77 // CreateAvailableMemoryWatcher() is not defined. 78 #if !defined(XP_WIN) CreateAvailableMemoryWatcher()79already_AddRefed<nsAvailableMemoryWatcherBase> CreateAvailableMemoryWatcher() { 80 RefPtr instance(new nsAvailableMemoryWatcherBase); 81 return do_AddRef(instance); 82 } 83 #endif 84 85 } // namespace mozilla 86