LCOV - code coverage report
Current view: top level - netwerk/cache2 - CacheStorageService.h (source / functions) Hit Total Coverage
Test: output.info Lines: 8 26 30.8 %
Date: 2017-07-14 16:53:18 Functions: 5 21 23.8 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* This Source Code Form is subject to the terms of the Mozilla Public
       2             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       3             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
       4             : 
       5             : #ifndef CacheStorageService__h__
       6             : #define CacheStorageService__h__
       7             : 
       8             : #include "nsICacheStorageService.h"
       9             : #include "nsIMemoryReporter.h"
      10             : #include "nsITimer.h"
      11             : #include "nsICacheTesting.h"
      12             : 
      13             : #include "nsClassHashtable.h"
      14             : #include "nsDataHashtable.h"
      15             : #include "nsString.h"
      16             : #include "nsThreadUtils.h"
      17             : #include "nsProxyRelease.h"
      18             : #include "mozilla/Monitor.h"
      19             : #include "mozilla/Mutex.h"
      20             : #include "mozilla/Atomics.h"
      21             : #include "mozilla/TimeStamp.h"
      22             : #include "nsTArray.h"
      23             : 
      24             : class nsIURI;
      25             : class nsICacheEntryDoomCallback;
      26             : class nsICacheStorageVisitor;
      27             : class nsIRunnable;
      28             : class nsIThread;
      29             : class nsIEventTarget;
      30             : 
      31             : namespace mozilla {
      32             : namespace net {
      33             : 
      34             : class CacheStorageService;
      35             : class CacheStorage;
      36             : class CacheEntry;
      37             : class CacheEntryHandle;
      38             : 
      39             : class CacheMemoryConsumer
      40             : {
      41             : private:
      42             :   friend class CacheStorageService;
      43             :   uint32_t mReportedMemoryConsumption : 30;
      44             :   uint32_t mFlags : 2;
      45             : 
      46             : private:
      47             :   CacheMemoryConsumer() = delete;
      48             : 
      49             : protected:
      50             :   enum {
      51             :     // No special treatment, reports always to the disk-entries pool.
      52             :     NORMAL = 0,
      53             :     // This consumer is belonging to a memory-only cache entry, used to decide
      54             :     // which of the two disk and memory pools count this consumption at.
      55             :     MEMORY_ONLY = 1 << 0,
      56             :     // Prevent reports of this consumer at all, used for disk data chunks since
      57             :     // we throw them away as soon as the entry is not used by any consumer and
      58             :     // don't want to make them wipe the whole pool out during their short life.
      59             :     DONT_REPORT = 1 << 1
      60             :   };
      61             : 
      62             :   explicit CacheMemoryConsumer(uint32_t aFlags);
      63           4 :   ~CacheMemoryConsumer() { DoMemoryReport(0); }
      64             :   void DoMemoryReport(uint32_t aCurrentSize);
      65             : };
      66             : 
      67             : class CacheStorageService final : public nsICacheStorageService
      68             :                                 , public nsIMemoryReporter
      69             :                                 , public nsITimerCallback
      70             :                                 , public nsICacheTesting
      71             : {
      72             : public:
      73             :   NS_DECL_THREADSAFE_ISUPPORTS
      74             :   NS_DECL_NSICACHESTORAGESERVICE
      75             :   NS_DECL_NSIMEMORYREPORTER
      76             :   NS_DECL_NSITIMERCALLBACK
      77             :   NS_DECL_NSICACHETESTING
      78             : 
      79             :   CacheStorageService();
      80             : 
      81             :   void Shutdown();
      82             :   void DropPrivateBrowsingEntries();
      83             : 
      84             :   // Takes care of deleting any pending trashes for both cache1 and cache2
      85             :   // as well as the cache directory of an inactive cache version when requested.
      86             :   static void CleaupCacheDirectories(uint32_t aVersion, uint32_t aActive);
      87             : 
      88         204 :   static CacheStorageService* Self() { return sSelf; }
      89             :   static nsISupports* SelfISupports() { return static_cast<nsICacheStorageService*>(Self()); }
      90             :   nsresult Dispatch(nsIRunnable* aEvent);
      91           0 :   static bool IsRunning() { return sSelf && !sSelf->mShutdown; }
      92             :   static bool IsOnManagementThread();
      93             :   already_AddRefed<nsIEventTarget> Thread() const;
      94          10 :   mozilla::Mutex& Lock() { return mLock; }
      95             : 
      96             :   // Tracks entries that may be forced valid in a pruned hashtable.
      97             :   nsDataHashtable<nsCStringHashKey, TimeStamp> mForcedValidEntries;
      98             :   void ForcedValidEntriesPrune(TimeStamp &now);
      99             : 
     100             :   // Helper thread-safe interface to pass entry info, only difference from
     101             :   // nsICacheStorageVisitor is that instead of nsIURI only the uri spec is
     102             :   // passed.
     103           0 :   class EntryInfoCallback {
     104             :   public:
     105             :     virtual void OnEntryInfo(const nsACString & aURISpec, const nsACString & aIdEnhance,
     106             :                              int64_t aDataSize, int32_t aFetchCount,
     107             :                              uint32_t aLastModifiedTime, uint32_t aExpirationTime,
     108             :                              bool aPinned, nsILoadContextInfo* aInfo) = 0;
     109             :   };
     110             : 
     111             :   // Invokes OnEntryInfo for the given aEntry, synchronously.
     112             :   static void GetCacheEntryInfo(CacheEntry* aEntry, EntryInfoCallback *aVisitor);
     113             : 
     114             :   nsresult GetCacheIndexEntryAttrs(CacheStorage const* aStorage,
     115             :                                    const nsACString &aURI,
     116             :                                    const nsACString &aIdExtension,
     117             :                                    bool *aHasAltData,
     118             :                                    uint32_t *aFileSizeKb);
     119             : 
     120             :   static uint32_t CacheQueueSize(bool highPriority);
     121             : 
     122             :   // Memory reporting
     123             :   size_t SizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf) const;
     124             :   size_t SizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf) const;
     125           0 :   MOZ_DEFINE_MALLOC_SIZE_OF(MallocSizeOf)
     126             : 
     127             : private:
     128             :   virtual ~CacheStorageService();
     129             :   void ShutdownBackground();
     130             : 
     131             : private:
     132             :   // The following methods may only be called on the management
     133             :   // thread.
     134             :   friend class CacheEntry;
     135             : 
     136             :   /**
     137             :    * Registers the entry in management ordered arrays, a mechanism
     138             :    * helping with weighted purge of entries.
     139             :    * Management arrays keep hard reference to the entry.  Entry is
     140             :    * responsible to remove it self or the service is responsible to
     141             :    * remove the entry when it's no longer needed.
     142             :    */
     143             :   void RegisterEntry(CacheEntry* aEntry);
     144             : 
     145             :   /**
     146             :    * Deregisters the entry from management arrays.  References are
     147             :    * then released.
     148             :    */
     149             :   void UnregisterEntry(CacheEntry* aEntry);
     150             : 
     151             :   /**
     152             :    * Removes the entry from the related entry hash table, if still present.
     153             :    */
     154             :   bool RemoveEntry(CacheEntry* aEntry, bool aOnlyUnreferenced = false);
     155             : 
     156             :   /**
     157             :    * Tells the storage service whether this entry is only to be stored in
     158             :    * memory.
     159             :    */
     160             :   void RecordMemoryOnlyEntry(CacheEntry* aEntry,
     161             :                              bool aOnlyInMemory,
     162             :                              bool aOverwrite);
     163             : 
     164             :   /**
     165             :    * Sets a cache entry valid (overrides the default loading behavior by loading
     166             :    * directly from cache) for the given number of seconds
     167             :    * See nsICacheEntry.idl for more details
     168             :    */
     169             :   void ForceEntryValidFor(nsACString const &aContextKey,
     170             :                           nsACString const &aEntryKey,
     171             :                           uint32_t aSecondsToTheFuture);
     172             : 
     173             :   /**
     174             :    * Remove the validity info
     175             :    */
     176             :   void RemoveEntryForceValid(nsACString const &aContextKey,
     177             :                              nsACString const &aEntryKey);
     178             : 
     179             :   /**
     180             :    * Retrieves the status of the cache entry to see if it has been forced valid
     181             :    * (so it will loaded directly from cache without further validation)
     182             :    */
     183             :   bool IsForcedValidEntry(nsACString const &aContextKey,
     184             :                           nsACString const &aEntryKey);
     185             : 
     186             : private:
     187             :   friend class CacheIndex;
     188             : 
     189             :   /**
     190             :    * CacheIndex uses this to prevent a cache entry from being prememptively
     191             :    * thrown away when forced valid
     192             :    * See nsICacheEntry.idl for more details
     193             :    */
     194             :   bool IsForcedValidEntry(nsACString const &aEntryKeyWithContext);
     195             : 
     196             : private:
     197             :   // These are helpers for telemetry monitoring of the memory pools.
     198             :   void TelemetryPrune(TimeStamp &now);
     199             :   void TelemetryRecordEntryCreation(CacheEntry const* entry);
     200             :   void TelemetryRecordEntryRemoval(CacheEntry const* entry);
     201             : 
     202             : private:
     203             :   // Following methods are thread safe to call.
     204             :   friend class CacheStorage;
     205             : 
     206             :   /**
     207             :    * Get, or create when not existing and demanded, an entry for the storage
     208             :    * and uri+id extension.
     209             :    */
     210             :   nsresult AddStorageEntry(CacheStorage const* aStorage,
     211             :                            const nsACString & aURI,
     212             :                            const nsACString & aIdExtension,
     213             :                            bool aReplace,
     214             :                            CacheEntryHandle** aResult);
     215             : 
     216             :   /**
     217             :    * Check existance of an entry.  This may throw NS_ERROR_NOT_AVAILABLE
     218             :    * when the information cannot be obtained synchronously w/o blocking.
     219             :    */
     220             :   nsresult CheckStorageEntry(CacheStorage const* aStorage,
     221             :                              const nsACString & aURI,
     222             :                              const nsACString & aIdExtension,
     223             :                              bool* aResult);
     224             : 
     225             :   /**
     226             :    * Removes the entry from the related entry hash table, if still present
     227             :    * and returns it.
     228             :    */
     229             :   nsresult DoomStorageEntry(CacheStorage const* aStorage,
     230             :                             const nsACString & aURI,
     231             :                             const nsACString & aIdExtension,
     232             :                             nsICacheEntryDoomCallback* aCallback);
     233             : 
     234             :   /**
     235             :    * Removes and returns entry table for the storage.
     236             :    */
     237             :   nsresult DoomStorageEntries(CacheStorage const* aStorage,
     238             :                               nsICacheEntryDoomCallback* aCallback);
     239             : 
     240             :   /**
     241             :    * Walk all entiries beloging to the storage.
     242             :    */
     243             :   nsresult WalkStorageEntries(CacheStorage const* aStorage,
     244             :                               bool aVisitEntries,
     245             :                               nsICacheStorageVisitor* aVisitor);
     246             : 
     247             : private:
     248             :   friend class CacheFileIOManager;
     249             : 
     250             :   /**
     251             :    * CacheFileIOManager uses this method to notify CacheStorageService that
     252             :    * an active entry was removed. This method is called even if the entry
     253             :    * removal was originated by CacheStorageService.
     254             :    */
     255             :   void CacheFileDoomed(nsILoadContextInfo* aLoadContextInfo,
     256             :                        const nsACString & aIdExtension,
     257             :                        const nsACString & aURISpec);
     258             : 
     259             :   /**
     260             :    * Tries to find an existing entry in the hashtables and synchronously call
     261             :    * OnCacheEntryInfo of the aVisitor callback when found.
     262             :    * @retuns
     263             :    *   true, when the entry has been found that also implies the callbacks has
     264             :    *        beem invoked
     265             :    *   false, when an entry has not been found
     266             :    */
     267             :   bool GetCacheEntryInfo(nsILoadContextInfo* aLoadContextInfo,
     268             :                          const nsACString & aIdExtension,
     269             :                          const nsACString & aURISpec,
     270             :                          EntryInfoCallback *aCallback);
     271             : 
     272             : private:
     273             :   friend class CacheMemoryConsumer;
     274             : 
     275             :   /**
     276             :    * When memory consumption of this entry radically changes, this method
     277             :    * is called to reflect the size of allocated memory.  This call may purge
     278             :    * unspecified number of entries from memory (but not from disk).
     279             :    */
     280             :   void OnMemoryConsumptionChange(CacheMemoryConsumer* aConsumer,
     281             :                                  uint32_t aCurrentMemoryConsumption);
     282             : 
     283             :   /**
     284             :    * If not already pending, it schedules mPurgeTimer that fires after 1 second
     285             :    * and dispatches PurgeOverMemoryLimit().
     286             :    */
     287             :   void SchedulePurgeOverMemoryLimit();
     288             : 
     289             :   /**
     290             :    * Called on the management thread, removes all expired and then least used
     291             :    * entries from the memory, first from the disk pool and then from the memory
     292             :    * pool.
     293             :    */
     294             :   void PurgeOverMemoryLimit();
     295             : 
     296             : private:
     297             :   nsresult DoomStorageEntries(const nsACString& aContextKey,
     298             :                               nsILoadContextInfo* aContext,
     299             :                               bool aDiskStorage,
     300             :                               bool aPin,
     301             :                               nsICacheEntryDoomCallback* aCallback);
     302             :   nsresult AddStorageEntry(const nsACString& aContextKey,
     303             :                            const nsACString & aURI,
     304             :                            const nsACString & aIdExtension,
     305             :                            bool aWriteToDisk,
     306             :                            bool aSkipSizeCheck,
     307             :                            bool aPin,
     308             :                            bool aReplace,
     309             :                            CacheEntryHandle** aResult);
     310             : 
     311             :   static CacheStorageService* sSelf;
     312             : 
     313             :   mozilla::Mutex mLock;
     314             :   mozilla::Mutex mForcedValidEntriesLock;
     315             : 
     316             :   bool mShutdown;
     317             : 
     318             :   // Accessible only on the service thread
     319             :   class MemoryPool
     320             :   {
     321             :   public:
     322             :     enum EType
     323             :     {
     324             :       DISK,
     325             :       MEMORY,
     326             :     } mType;
     327             : 
     328             :     explicit MemoryPool(EType aType);
     329             :     ~MemoryPool();
     330             : 
     331             :     nsTArray<RefPtr<CacheEntry> > mFrecencyArray;
     332             :     nsTArray<RefPtr<CacheEntry> > mExpirationArray;
     333             :     Atomic<uint32_t, Relaxed> mMemorySize;
     334             : 
     335             :     bool OnMemoryConsumptionChange(uint32_t aSavedMemorySize,
     336             :                                    uint32_t aCurrentMemoryConsumption);
     337             :     /**
     338             :      * Purges entries from memory based on the frecency ordered array.
     339             :      */
     340             :     void PurgeOverMemoryLimit();
     341             :     void PurgeExpired();
     342             :     void PurgeByFrecency(bool &aFrecencyNeedsSort, uint32_t aWhat);
     343             :     void PurgeAll(uint32_t aWhat);
     344             : 
     345             :   private:
     346             :     uint32_t Limit() const;
     347             :     MemoryPool() = delete;
     348             :   };
     349             : 
     350             :   MemoryPool mDiskPool;
     351             :   MemoryPool mMemoryPool;
     352             :   TimeStamp mLastPurgeTime;
     353          22 :   MemoryPool& Pool(bool aUsingDisk)
     354             :   {
     355          22 :     return aUsingDisk ? mDiskPool : mMemoryPool;
     356             :   }
     357           0 :   MemoryPool const& Pool(bool aUsingDisk) const
     358             :   {
     359           0 :     return aUsingDisk ? mDiskPool : mMemoryPool;
     360             :   }
     361             : 
     362             :   nsCOMPtr<nsITimer> mPurgeTimer;
     363             : 
     364             :   class PurgeFromMemoryRunnable : public Runnable
     365             :   {
     366             :   public:
     367           0 :     PurgeFromMemoryRunnable(CacheStorageService* aService, uint32_t aWhat)
     368           0 :       : Runnable("net::CacheStorageService::PurgeFromMemoryRunnable")
     369             :       , mService(aService)
     370           0 :       , mWhat(aWhat)
     371             :     {
     372           0 :     }
     373             : 
     374             :   private:
     375           0 :     virtual ~PurgeFromMemoryRunnable() { }
     376             : 
     377             :     NS_IMETHOD Run() override;
     378             : 
     379             :     RefPtr<CacheStorageService> mService;
     380             :     uint32_t mWhat;
     381             :   };
     382             : 
     383             :   // Used just for telemetry purposes, accessed only on the management thread.
     384             :   // Note: not included in the memory reporter, this is not expected to be huge
     385             :   // and also would be complicated to report since reporting happens on the main
     386             :   // thread but this table is manipulated on the management thread.
     387             :   nsDataHashtable<nsCStringHashKey, mozilla::TimeStamp> mPurgeTimeStamps;
     388             : 
     389             :   // nsICacheTesting
     390             :   class IOThreadSuspender : public Runnable
     391             :   {
     392             :   public:
     393           0 :     IOThreadSuspender()
     394           0 :       : Runnable("net::CacheStorageService::IOThreadSuspender")
     395             :       , mMon("IOThreadSuspender")
     396           0 :       , mSignaled(false)
     397             :     {
     398           0 :     }
     399             :     void Notify();
     400             :   private:
     401           0 :     virtual ~IOThreadSuspender() { }
     402             :     NS_IMETHOD Run() override;
     403             : 
     404             :     Monitor mMon;
     405             :     bool mSignaled;
     406             :   };
     407             : 
     408             :   RefPtr<IOThreadSuspender> mActiveIOSuspender;
     409             : };
     410             : 
     411             : template<class T>
     412          49 : void ProxyRelease(const char* aName, nsCOMPtr<T> &object, nsIEventTarget* target)
     413             : {
     414          49 :   NS_ProxyRelease(aName, target, object.forget());
     415          49 : }
     416             : 
     417             : template<class T>
     418           0 : void ProxyReleaseMainThread(const char* aName, nsCOMPtr<T> &object)
     419             : {
     420           0 :   ProxyRelease(aName, object, GetMainThreadEventTarget());
     421           0 : }
     422             : 
     423             : } // namespace net
     424             : } // namespace mozilla
     425             : 
     426             : #define NS_CACHE_STORAGE_SERVICE_CID \
     427             :   { 0xea70b098, 0x5014, 0x4e21, \
     428             :   { 0xae, 0xe1, 0x75, 0xe6, 0xb2, 0xc4, 0xb8, 0xe0 } } \
     429             : 
     430             : #define NS_CACHE_STORAGE_SERVICE_CONTRACTID \
     431             :   "@mozilla.org/netwerk/cache-storage-service;1"
     432             : 
     433             : #define NS_CACHE_STORAGE_SERVICE_CONTRACTID2 \
     434             :   "@mozilla.org/network/cache-storage-service;1"
     435             : 
     436             : #endif

Generated by: LCOV version 1.13