netwerk/cache2/CacheFileIOManager.h

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

     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/. */
     5 #ifndef CacheFileIOManager__h__
     6 #define CacheFileIOManager__h__
     8 #include "CacheIOThread.h"
     9 #include "nsIEventTarget.h"
    10 #include "nsITimer.h"
    11 #include "nsCOMPtr.h"
    12 #include "mozilla/SHA1.h"
    13 #include "mozilla/TimeStamp.h"
    14 #include "nsTArray.h"
    15 #include "nsString.h"
    16 #include "nsTHashtable.h"
    17 #include "prio.h"
    19 //#define DEBUG_HANDLES 1
    21 class nsIFile;
    22 class nsITimer;
    23 class nsIDirectoryEnumerator;
    24 class nsILoadContextInfo;
    26 namespace mozilla {
    27 namespace net {
    29 class CacheFile;
    30 #ifdef DEBUG_HANDLES
    31 class CacheFileHandlesEntry;
    32 #endif
    34 const char kEntriesDir[] = "entries";
    35 const char kDoomedDir[]  = "doomed";
    36 const char kTrashDir[]   = "trash";
    39 class CacheFileHandle : public nsISupports
    40 {
    41 public:
    42   NS_DECL_THREADSAFE_ISUPPORTS
    43   bool DispatchRelease();
    45   CacheFileHandle(const SHA1Sum::Hash *aHash, bool aPriority);
    46   CacheFileHandle(const nsACString &aKey, bool aPriority);
    47   CacheFileHandle(const CacheFileHandle &aOther);
    48   void Log();
    49   bool IsDoomed() const { return mIsDoomed; }
    50   const SHA1Sum::Hash *Hash() const { return mHash; }
    51   int64_t FileSize() const { return mFileSize; }
    52   uint32_t FileSizeInK() const;
    53   bool IsPriority() const { return mPriority; }
    54   bool FileExists() const { return mFileExists; }
    55   bool IsClosed() const { return mClosed; }
    56   bool IsSpecialFile() const { return !mHash; }
    57   nsCString & Key() { return mKey; }
    59   // Memory reporting
    60   size_t SizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf) const;
    61   size_t SizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf) const;
    63 private:
    64   friend class CacheFileIOManager;
    65   friend class CacheFileHandles;
    66   friend class ReleaseNSPRHandleEvent;
    68   virtual ~CacheFileHandle();
    70   const SHA1Sum::Hash *mHash;
    71   bool                 mIsDoomed;
    72   bool                 mPriority;
    73   bool                 mClosed;
    74   bool                 mInvalid;
    75   bool                 mFileExists; // This means that the file should exists,
    76                                     // but it can be still deleted by OS/user
    77                                     // and then a subsequent OpenNSPRFileDesc()
    78                                     // will fail.
    79   nsCOMPtr<nsIFile>    mFile;
    80   int64_t              mFileSize;
    81   PRFileDesc          *mFD;  // if null then the file doesn't exists on the disk
    82   nsCString            mKey;
    83 };
    85 class CacheFileHandles {
    86 public:
    87   CacheFileHandles();
    88   ~CacheFileHandles();
    90   nsresult GetHandle(const SHA1Sum::Hash *aHash, bool aReturnDoomed, CacheFileHandle **_retval);
    91   nsresult NewHandle(const SHA1Sum::Hash *aHash, bool aPriority, CacheFileHandle **_retval);
    92   void     RemoveHandle(CacheFileHandle *aHandlle);
    93   void     GetAllHandles(nsTArray<nsRefPtr<CacheFileHandle> > *_retval);
    94   void     GetActiveHandles(nsTArray<nsRefPtr<CacheFileHandle> > *_retval);
    95   void     ClearAll();
    96   uint32_t HandleCount();
    98 #ifdef DEBUG_HANDLES
    99   void     Log(CacheFileHandlesEntry *entry);
   100 #endif
   102   // Memory reporting
   103   size_t SizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf) const;
   104   size_t SizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf) const;
   106   class HandleHashKey : public PLDHashEntryHdr
   107   {
   108   public:
   109     typedef const SHA1Sum::Hash& KeyType;
   110     typedef const SHA1Sum::Hash* KeyTypePointer;
   112     HandleHashKey(KeyTypePointer aKey)
   113     {
   114       MOZ_COUNT_CTOR(HandleHashKey);
   115       mHash = (SHA1Sum::Hash*)new uint8_t[SHA1Sum::HashSize];
   116       memcpy(mHash, aKey, sizeof(SHA1Sum::Hash));
   117     }
   118     HandleHashKey(const HandleHashKey& aOther)
   119     {
   120       NS_NOTREACHED("HandleHashKey copy constructor is forbidden!");
   121     }
   122     ~HandleHashKey()
   123     {
   124       MOZ_COUNT_DTOR(HandleHashKey);
   125     }
   127     bool KeyEquals(KeyTypePointer aKey) const
   128     {
   129       return memcmp(mHash, aKey, sizeof(SHA1Sum::Hash)) == 0;
   130     }
   131     static KeyTypePointer KeyToPointer(KeyType aKey)
   132     {
   133       return &aKey;
   134     }
   135     static PLDHashNumber HashKey(KeyTypePointer aKey)
   136     {
   137       return (reinterpret_cast<const uint32_t *>(aKey))[0];
   138     }
   140     void AddHandle(CacheFileHandle* aHandle);
   141     void RemoveHandle(CacheFileHandle* aHandle);
   142     already_AddRefed<CacheFileHandle> GetNewestHandle();
   143     void GetHandles(nsTArray<nsRefPtr<CacheFileHandle> > &aResult);
   145     SHA1Sum::Hash *Hash() const { return mHash; }
   146     bool IsEmpty() const { return mHandles.Length() == 0; }
   148     enum { ALLOW_MEMMOVE = true };
   150 #ifdef DEBUG
   151     void AssertHandlesState();
   152 #endif
   154     // Memory reporting
   155     size_t SizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf) const;
   156     size_t SizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf) const;
   158   private:
   159     nsAutoArrayPtr<SHA1Sum::Hash> mHash;
   160     // Use weak pointers since the hash table access is on a single thread
   161     // only and CacheFileHandle removes itself from this table in its dtor
   162     // that may only be called on the same thread as we work with the hashtable
   163     // since we dispatch its Release() to this thread.
   164     nsTArray<CacheFileHandle*> mHandles;
   165   };
   167 private:
   168   nsTHashtable<HandleHashKey> mTable;
   169 };
   171 ////////////////////////////////////////////////////////////////////////////////
   173 class OpenFileEvent;
   174 class CloseFileEvent;
   175 class ReadEvent;
   176 class WriteEvent;
   177 class MetadataWriteScheduleEvent;
   178 class CacheFileContextEvictor;
   180 #define CACHEFILEIOLISTENER_IID \
   181 { /* dcaf2ddc-17cf-4242-bca1-8c86936375a5 */       \
   182   0xdcaf2ddc,                                      \
   183   0x17cf,                                          \
   184   0x4242,                                          \
   185   {0xbc, 0xa1, 0x8c, 0x86, 0x93, 0x63, 0x75, 0xa5} \
   186 }
   188 class CacheFileIOListener : public nsISupports
   189 {
   190 public:
   191   NS_DECLARE_STATIC_IID_ACCESSOR(CACHEFILEIOLISTENER_IID)
   193   NS_IMETHOD OnFileOpened(CacheFileHandle *aHandle, nsresult aResult) = 0;
   194   NS_IMETHOD OnDataWritten(CacheFileHandle *aHandle, const char *aBuf,
   195                            nsresult aResult) = 0;
   196   NS_IMETHOD OnDataRead(CacheFileHandle *aHandle, char *aBuf,
   197                         nsresult aResult) = 0;
   198   NS_IMETHOD OnFileDoomed(CacheFileHandle *aHandle, nsresult aResult) = 0;
   199   NS_IMETHOD OnEOFSet(CacheFileHandle *aHandle, nsresult aResult) = 0;
   200   NS_IMETHOD OnFileRenamed(CacheFileHandle *aHandle, nsresult aResult) = 0;
   201 };
   203 NS_DEFINE_STATIC_IID_ACCESSOR(CacheFileIOListener, CACHEFILEIOLISTENER_IID)
   206 class CacheFileIOManager : public nsITimerCallback
   207 {
   208 public:
   209   NS_DECL_THREADSAFE_ISUPPORTS
   210   NS_DECL_NSITIMERCALLBACK
   212   enum {
   213     OPEN         = 0U,
   214     CREATE       = 1U,
   215     CREATE_NEW   = 2U,
   216     PRIORITY     = 4U,
   217     SPECIAL_FILE = 8U
   218   };
   220   CacheFileIOManager();
   222   static nsresult Init();
   223   static nsresult Shutdown();
   224   static nsresult OnProfile();
   225   static already_AddRefed<nsIEventTarget> IOTarget();
   226   static already_AddRefed<CacheIOThread> IOThread();
   227   static bool IsOnIOThread();
   228   static bool IsOnIOThreadOrCeased();
   229   static bool IsShutdown();
   231   // Make aFile's WriteMetadataIfNeeded be called automatically after
   232   // a short interval.
   233   static nsresult ScheduleMetadataWrite(CacheFile * aFile);
   234   // Remove aFile from the scheduling registry array.
   235   // WriteMetadataIfNeeded will not be automatically called.
   236   static nsresult UnscheduleMetadataWrite(CacheFile * aFile);
   237   // Shuts the scheduling off and flushes all pending metadata writes.
   238   static nsresult ShutdownMetadataWriteScheduling();
   240   static nsresult OpenFile(const nsACString &aKey,
   241                            uint32_t aFlags, bool aResultOnAnyThread,
   242                            CacheFileIOListener *aCallback);
   243   static nsresult Read(CacheFileHandle *aHandle, int64_t aOffset,
   244                        char *aBuf, int32_t aCount, bool aResultOnAnyThread,
   245                        CacheFileIOListener *aCallback);
   246   static nsresult Write(CacheFileHandle *aHandle, int64_t aOffset,
   247                         const char *aBuf, int32_t aCount, bool aValidate,
   248                         CacheFileIOListener *aCallback);
   249   static nsresult DoomFile(CacheFileHandle *aHandle,
   250                            CacheFileIOListener *aCallback);
   251   static nsresult DoomFileByKey(const nsACString &aKey,
   252                                 CacheFileIOListener *aCallback);
   253   static nsresult ReleaseNSPRHandle(CacheFileHandle *aHandle);
   254   static nsresult TruncateSeekSetEOF(CacheFileHandle *aHandle,
   255                                      int64_t aTruncatePos, int64_t aEOFPos,
   256                                      CacheFileIOListener *aCallback);
   257   static nsresult RenameFile(CacheFileHandle *aHandle,
   258                              const nsACString &aNewName,
   259                              CacheFileIOListener *aCallback);
   260   static nsresult EvictIfOverLimit();
   261   static nsresult EvictAll();
   262   static nsresult EvictByContext(nsILoadContextInfo *aLoadContextInfo);
   264   static nsresult InitIndexEntry(CacheFileHandle *aHandle,
   265                                  uint32_t         aAppId,
   266                                  bool             aAnonymous,
   267                                  bool             aInBrowser);
   268   static nsresult UpdateIndexEntry(CacheFileHandle *aHandle,
   269                                    const uint32_t  *aFrecency,
   270                                    const uint32_t  *aExpirationTime);
   272   static nsresult UpdateIndexEntry();
   274   enum EEnumerateMode {
   275     ENTRIES,
   276     DOOMED
   277   };
   279   static void GetCacheDirectory(nsIFile** result);
   281   // Memory reporting
   282   static size_t SizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf);
   283   static size_t SizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf);
   285 private:
   286   friend class CacheFileHandle;
   287   friend class CacheFileChunk;
   288   friend class CacheFile;
   289   friend class ShutdownEvent;
   290   friend class OpenFileEvent;
   291   friend class CloseHandleEvent;
   292   friend class ReadEvent;
   293   friend class WriteEvent;
   294   friend class DoomFileEvent;
   295   friend class DoomFileByKeyEvent;
   296   friend class ReleaseNSPRHandleEvent;
   297   friend class TruncateSeekSetEOFEvent;
   298   friend class RenameFileEvent;
   299   friend class CacheIndex;
   300   friend class MetadataWriteScheduleEvent;
   301   friend class CacheFileContextEvictor;
   303   virtual ~CacheFileIOManager();
   305   nsresult InitInternal();
   306   nsresult ShutdownInternal();
   308   nsresult OpenFileInternal(const SHA1Sum::Hash *aHash,
   309                             const nsACString &aKey,
   310                             uint32_t aFlags,
   311                             CacheFileHandle **_retval);
   312   nsresult OpenSpecialFileInternal(const nsACString &aKey,
   313                                    uint32_t aFlags,
   314                                    CacheFileHandle **_retval);
   315   nsresult CloseHandleInternal(CacheFileHandle *aHandle);
   316   nsresult ReadInternal(CacheFileHandle *aHandle, int64_t aOffset,
   317                         char *aBuf, int32_t aCount);
   318   nsresult WriteInternal(CacheFileHandle *aHandle, int64_t aOffset,
   319                          const char *aBuf, int32_t aCount, bool aValidate);
   320   nsresult DoomFileInternal(CacheFileHandle *aHandle);
   321   nsresult DoomFileByKeyInternal(const SHA1Sum::Hash *aHash);
   322   nsresult ReleaseNSPRHandleInternal(CacheFileHandle *aHandle);
   323   nsresult TruncateSeekSetEOFInternal(CacheFileHandle *aHandle,
   324                                       int64_t aTruncatePos, int64_t aEOFPos);
   325   nsresult RenameFileInternal(CacheFileHandle *aHandle,
   326                               const nsACString &aNewName);
   327   nsresult EvictIfOverLimitInternal();
   328   nsresult OverLimitEvictionInternal();
   329   nsresult EvictAllInternal();
   330   nsresult EvictByContextInternal(nsILoadContextInfo *aLoadContextInfo);
   332   nsresult TrashDirectory(nsIFile *aFile);
   333   static void OnTrashTimer(nsITimer *aTimer, void *aClosure);
   334   nsresult StartRemovingTrash();
   335   nsresult RemoveTrashInternal();
   336   nsresult FindTrashDirToRemove();
   338   nsresult CreateFile(CacheFileHandle *aHandle);
   339   static void HashToStr(const SHA1Sum::Hash *aHash, nsACString &_retval);
   340   static nsresult StrToHash(const nsACString &aHash, SHA1Sum::Hash *_retval);
   341   nsresult GetFile(const SHA1Sum::Hash *aHash, nsIFile **_retval);
   342   nsresult GetSpecialFile(const nsACString &aKey, nsIFile **_retval);
   343   nsresult GetDoomedFile(nsIFile **_retval);
   344   nsresult IsEmptyDirectory(nsIFile *aFile, bool *_retval);
   345   nsresult CheckAndCreateDir(nsIFile *aFile, const char *aDir,
   346                              bool aEnsureEmptyDir);
   347   nsresult CreateCacheTree();
   348   nsresult OpenNSPRHandle(CacheFileHandle *aHandle, bool aCreate = false);
   349   void     NSPRHandleUsed(CacheFileHandle *aHandle);
   351   // Removing all cache files during shutdown
   352   nsresult SyncRemoveDir(nsIFile *aFile, const char *aDir);
   353   void     SyncRemoveAllCacheFiles();
   355   nsresult ScheduleMetadataWriteInternal(CacheFile * aFile);
   356   nsresult UnscheduleMetadataWriteInternal(CacheFile * aFile);
   357   nsresult ShutdownMetadataWriteSchedulingInternal();
   359   static nsresult CacheIndexStateChanged();
   360   nsresult CacheIndexStateChangedInternal();
   362   // Smart size calculation. UpdateSmartCacheSize() must be called on IO thread.
   363   // It is called in EvictIfOverLimitInternal() just before we decide whether to
   364   // start overlimit eviction or not and also in OverLimitEvictionInternal()
   365   // before we start an eviction loop.
   366   nsresult UpdateSmartCacheSize();
   368   // Memory reporting (private part)
   369   size_t SizeOfExcludingThisInternal(mozilla::MallocSizeOf mallocSizeOf) const;
   371   static CacheFileIOManager           *gInstance;
   372   TimeStamp                            mStartTime;
   373   bool                                 mShuttingDown;
   374   nsRefPtr<CacheIOThread>              mIOThread;
   375   nsCOMPtr<nsIFile>                    mCacheDirectory;
   376   bool                                 mTreeCreated;
   377   CacheFileHandles                     mHandles;
   378   nsTArray<CacheFileHandle *>          mHandlesByLastUsed;
   379   nsTArray<CacheFileHandle *>          mSpecialHandles;
   380   nsTArray<nsRefPtr<CacheFile> >       mScheduledMetadataWrites;
   381   nsCOMPtr<nsITimer>                   mMetadataWritesTimer;
   382   bool                                 mOverLimitEvicting;
   383   bool                                 mRemovingTrashDirs;
   384   nsCOMPtr<nsITimer>                   mTrashTimer;
   385   nsCOMPtr<nsIFile>                    mTrashDir;
   386   nsCOMPtr<nsIDirectoryEnumerator>     mTrashDirEnumerator;
   387   nsTArray<nsCString>                  mFailedTrashDirs;
   388   nsRefPtr<CacheFileContextEvictor>    mContextEvictor;
   389   TimeStamp                            mLastSmartSizeTime;
   390 };
   392 } // net
   393 } // mozilla
   395 #endif

mercurial