netwerk/cache/nsCacheService.h

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/netwerk/cache/nsCacheService.h	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,395 @@
     1.4 +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
     1.5 +/* vim: set ts=8 sts=4 et sw=4 tw=80: */
     1.6 +/* This Source Code Form is subject to the terms of the Mozilla Public
     1.7 + * License, v. 2.0. If a copy of the MPL was not distributed with this
     1.8 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     1.9 +
    1.10 +#ifndef _nsCacheService_h_
    1.11 +#define _nsCacheService_h_
    1.12 +
    1.13 +#include "nsICacheService.h"
    1.14 +#include "nsCacheSession.h"
    1.15 +#include "nsCacheDevice.h"
    1.16 +#include "nsCacheEntry.h"
    1.17 +#include "nsThreadUtils.h"
    1.18 +#include "nsICacheListener.h"
    1.19 +#include "nsIMemoryReporter.h"
    1.20 +
    1.21 +#include "prthread.h"
    1.22 +#include "nsIObserver.h"
    1.23 +#include "nsString.h"
    1.24 +#include "nsTArray.h"
    1.25 +#include "nsRefPtrHashtable.h"
    1.26 +#include "mozilla/CondVar.h"
    1.27 +#include "mozilla/Mutex.h"
    1.28 +#include "mozilla/Telemetry.h"
    1.29 +
    1.30 +class nsCacheRequest;
    1.31 +class nsCacheProfilePrefObserver;
    1.32 +class nsDiskCacheDevice;
    1.33 +class nsMemoryCacheDevice;
    1.34 +class nsOfflineCacheDevice;
    1.35 +class nsCacheServiceAutoLock;
    1.36 +class nsITimer;
    1.37 +class mozIStorageService;
    1.38 +
    1.39 +
    1.40 +/******************************************************************************
    1.41 + * nsNotifyDoomListener
    1.42 + *****************************************************************************/
    1.43 +
    1.44 +class nsNotifyDoomListener : public nsRunnable {
    1.45 +public:
    1.46 +    nsNotifyDoomListener(nsICacheListener *listener,
    1.47 +                         nsresult status)
    1.48 +        : mListener(listener)      // transfers reference
    1.49 +        , mStatus(status)
    1.50 +    {}
    1.51 +
    1.52 +    NS_IMETHOD Run()
    1.53 +    {
    1.54 +        mListener->OnCacheEntryDoomed(mStatus);
    1.55 +        NS_RELEASE(mListener);
    1.56 +        return NS_OK;
    1.57 +    }
    1.58 +
    1.59 +private:
    1.60 +    nsICacheListener *mListener;
    1.61 +    nsresult          mStatus;
    1.62 +};
    1.63 +
    1.64 +/******************************************************************************
    1.65 + *  nsCacheService
    1.66 + ******************************************************************************/
    1.67 +
    1.68 +class nsCacheService : public nsICacheServiceInternal,
    1.69 +                       public nsIMemoryReporter
    1.70 +{
    1.71 +public:
    1.72 +    NS_DECL_THREADSAFE_ISUPPORTS
    1.73 +    NS_DECL_NSICACHESERVICE
    1.74 +    NS_DECL_NSICACHESERVICEINTERNAL
    1.75 +    NS_DECL_NSIMEMORYREPORTER
    1.76 +
    1.77 +    nsCacheService();
    1.78 +    virtual ~nsCacheService();
    1.79 +
    1.80 +    // Define a Create method to be used with a factory:
    1.81 +    static nsresult
    1.82 +    Create(nsISupports* outer, const nsIID& iid, void* *result);
    1.83 +
    1.84 +
    1.85 +    /**
    1.86 +     * Methods called by nsCacheSession
    1.87 +     */
    1.88 +    static nsresult  OpenCacheEntry(nsCacheSession *           session,
    1.89 +                                    const nsACString &         key,
    1.90 +                                    nsCacheAccessMode          accessRequested,
    1.91 +                                    bool                       blockingMode,
    1.92 +                                    nsICacheListener *         listener,
    1.93 +                                    nsICacheEntryDescriptor ** result);
    1.94 +
    1.95 +    static nsresult  EvictEntriesForSession(nsCacheSession *   session);
    1.96 +
    1.97 +    static nsresult  IsStorageEnabledForPolicy(nsCacheStoragePolicy  storagePolicy,
    1.98 +                                               bool *              result);
    1.99 +
   1.100 +    static nsresult  DoomEntry(nsCacheSession   *session,
   1.101 +                               const nsACString &key,
   1.102 +                               nsICacheListener *listener);
   1.103 +
   1.104 +    /**
   1.105 +     * Methods called by nsCacheEntryDescriptor
   1.106 +     */
   1.107 +
   1.108 +    static void      CloseDescriptor(nsCacheEntryDescriptor * descriptor);
   1.109 +
   1.110 +    static nsresult  GetFileForEntry(nsCacheEntry *         entry,
   1.111 +                                     nsIFile **             result);
   1.112 +
   1.113 +    static nsresult  OpenInputStreamForEntry(nsCacheEntry *     entry,
   1.114 +                                             nsCacheAccessMode  mode,
   1.115 +                                             uint32_t           offset,
   1.116 +                                             nsIInputStream **  result);
   1.117 +
   1.118 +    static nsresult  OpenOutputStreamForEntry(nsCacheEntry *     entry,
   1.119 +                                              nsCacheAccessMode  mode,
   1.120 +                                              uint32_t           offset,
   1.121 +                                              nsIOutputStream ** result);
   1.122 +
   1.123 +    static nsresult  OnDataSizeChange(nsCacheEntry * entry, int32_t deltaSize);
   1.124 +
   1.125 +    static nsresult  SetCacheElement(nsCacheEntry * entry, nsISupports * element);
   1.126 +
   1.127 +    static nsresult  ValidateEntry(nsCacheEntry * entry);
   1.128 +
   1.129 +    static int32_t   CacheCompressionLevel();
   1.130 +
   1.131 +    static bool      GetClearingEntries();
   1.132 +
   1.133 +    static void      GetCacheBaseDirectoty(nsIFile ** result);
   1.134 +    static void      GetDiskCacheDirectory(nsIFile ** result);
   1.135 +    static void      GetAppCacheDirectory(nsIFile ** result);
   1.136 +
   1.137 +    /**
   1.138 +     * Methods called by any cache classes
   1.139 +     */
   1.140 +
   1.141 +    static
   1.142 +    nsCacheService * GlobalInstance()   { return gService; }
   1.143 +
   1.144 +    static nsresult  DoomEntry(nsCacheEntry * entry);
   1.145 +
   1.146 +    static bool      IsStorageEnabledForPolicy_Locked(nsCacheStoragePolicy policy);
   1.147 +
   1.148 +    /**
   1.149 +     * Called by disk cache to notify us to use the new max smart size
   1.150 +     */
   1.151 +    static void      MarkStartingFresh();
   1.152 +
   1.153 +    /**
   1.154 +     * Methods called by nsApplicationCacheService
   1.155 +     */
   1.156 +
   1.157 +    nsresult GetOfflineDevice(nsOfflineCacheDevice ** aDevice);
   1.158 +
   1.159 +    /**
   1.160 +     * Creates an offline cache device that works over a specific profile directory.
   1.161 +     * A tool to preload offline cache for profiles different from the current
   1.162 +     * application's profile directory.
   1.163 +     */
   1.164 +    nsresult GetCustomOfflineDevice(nsIFile *aProfileDir,
   1.165 +                                    int32_t aQuota,
   1.166 +                                    nsOfflineCacheDevice **aDevice);
   1.167 +
   1.168 +    // This method may be called to release an object while the cache service
   1.169 +    // lock is being held.  If a non-null target is specified and the target
   1.170 +    // does not correspond to the current thread, then the release will be
   1.171 +    // proxied to the specified target.  Otherwise, the object will be added to
   1.172 +    // the list of objects to be released when the cache service is unlocked.
   1.173 +    static void      ReleaseObject_Locked(nsISupports *    object,
   1.174 +                                          nsIEventTarget * target = nullptr);
   1.175 +
   1.176 +    static nsresult DispatchToCacheIOThread(nsIRunnable* event);
   1.177 +
   1.178 +    // Calling this method will block the calling thread until all pending
   1.179 +    // events on the cache-io thread has finished. The calling thread must
   1.180 +    // hold the cache-lock
   1.181 +    static nsresult SyncWithCacheIOThread();
   1.182 +
   1.183 +
   1.184 +    /**
   1.185 +     * Methods called by nsCacheProfilePrefObserver
   1.186 +     */
   1.187 +    static void      OnProfileShutdown(bool cleanse);
   1.188 +    static void      OnProfileChanged();
   1.189 +
   1.190 +    static void      SetDiskCacheEnabled(bool    enabled);
   1.191 +    // Sets the disk cache capacity (in kilobytes)
   1.192 +    static void      SetDiskCacheCapacity(int32_t  capacity);
   1.193 +    // Set max size for a disk-cache entry (in KB). -1 disables limit up to
   1.194 +    // 1/8th of disk cache size
   1.195 +    static void      SetDiskCacheMaxEntrySize(int32_t  maxSize);
   1.196 +    // Set max size for a memory-cache entry (in kilobytes). -1 disables
   1.197 +    // limit up to 90% of memory cache size
   1.198 +    static void      SetMemoryCacheMaxEntrySize(int32_t  maxSize);
   1.199 +
   1.200 +    static void      SetOfflineCacheEnabled(bool    enabled);
   1.201 +    // Sets the offline cache capacity (in kilobytes)
   1.202 +    static void      SetOfflineCacheCapacity(int32_t  capacity);
   1.203 +
   1.204 +    static void      SetMemoryCache();
   1.205 +
   1.206 +    static void      SetCacheCompressionLevel(int32_t level);
   1.207 +
   1.208 +    // Starts smart cache size computation if disk device is available
   1.209 +    static nsresult  SetDiskSmartSize();
   1.210 +
   1.211 +    static void      MoveOrRemoveDiskCache(nsIFile *aOldCacheDir,
   1.212 +                                           nsIFile *aNewCacheDir,
   1.213 +                                           const char *aCacheSubdir);
   1.214 +
   1.215 +    nsresult         Init();
   1.216 +    void             Shutdown();
   1.217 +
   1.218 +    static bool      IsInitialized()
   1.219 +    {
   1.220 +      if (!gService) {
   1.221 +          return false;
   1.222 +      }
   1.223 +      return gService->mInitialized;
   1.224 +    }
   1.225 +
   1.226 +    static void      AssertOwnsLock()
   1.227 +    { gService->mLock.AssertCurrentThreadOwns(); }
   1.228 +
   1.229 +    static void      LeavePrivateBrowsing();
   1.230 +    bool             IsDoomListEmpty();
   1.231 +
   1.232 +    typedef bool (*DoomCheckFn)(nsCacheEntry* entry);
   1.233 +
   1.234 +private:
   1.235 +    friend class nsCacheServiceAutoLock;
   1.236 +    friend class nsOfflineCacheDevice;
   1.237 +    friend class nsProcessRequestEvent;
   1.238 +    friend class nsSetSmartSizeEvent;
   1.239 +    friend class nsBlockOnCacheThreadEvent;
   1.240 +    friend class nsSetDiskSmartSizeCallback;
   1.241 +    friend class nsDoomEvent;
   1.242 +    friend class nsDisableOldMaxSmartSizePrefEvent;
   1.243 +    friend class nsDiskCacheMap;
   1.244 +    friend class nsAsyncDoomEvent;
   1.245 +    friend class nsCacheEntryDescriptor;
   1.246 +
   1.247 +    /**
   1.248 +     * Internal Methods
   1.249 +     */
   1.250 +
   1.251 +    static void      Lock(::mozilla::Telemetry::ID mainThreadLockerID);
   1.252 +    static void      Unlock();
   1.253 +    void             LockAcquired();
   1.254 +    void             LockReleased();
   1.255 +
   1.256 +    nsresult         CreateDiskDevice();
   1.257 +    nsresult         CreateOfflineDevice();
   1.258 +    nsresult         CreateCustomOfflineDevice(nsIFile *aProfileDir,
   1.259 +                                               int32_t aQuota,
   1.260 +                                               nsOfflineCacheDevice **aDevice);
   1.261 +    nsresult         CreateMemoryDevice();
   1.262 +
   1.263 +    nsresult         RemoveCustomOfflineDevice(nsOfflineCacheDevice *aDevice);
   1.264 +
   1.265 +    nsresult         CreateRequest(nsCacheSession *   session,
   1.266 +                                   const nsACString & clientKey,
   1.267 +                                   nsCacheAccessMode  accessRequested,
   1.268 +                                   bool               blockingMode,
   1.269 +                                   nsICacheListener * listener,
   1.270 +                                   nsCacheRequest **  request);
   1.271 +
   1.272 +    nsresult         DoomEntry_Internal(nsCacheEntry * entry,
   1.273 +                                        bool doProcessPendingRequests);
   1.274 +
   1.275 +    nsresult         EvictEntriesForClient(const char *          clientID,
   1.276 +                                           nsCacheStoragePolicy  storagePolicy);
   1.277 +
   1.278 +    // Notifies request listener asynchronously on the request's thread, and
   1.279 +    // releases the descriptor on the request's thread.  If this method fails,
   1.280 +    // the descriptor is not released.
   1.281 +    nsresult         NotifyListener(nsCacheRequest *          request,
   1.282 +                                    nsICacheEntryDescriptor * descriptor,
   1.283 +                                    nsCacheAccessMode         accessGranted,
   1.284 +                                    nsresult                  error);
   1.285 +
   1.286 +    nsresult         ActivateEntry(nsCacheRequest * request,
   1.287 +                                   nsCacheEntry ** entry,
   1.288 +                                   nsCacheEntry ** doomedEntry);
   1.289 +
   1.290 +    nsCacheDevice *  EnsureEntryHasDevice(nsCacheEntry * entry);
   1.291 +
   1.292 +    nsCacheEntry *   SearchCacheDevices(nsCString * key, nsCacheStoragePolicy policy, bool *collision);
   1.293 +
   1.294 +    void             DeactivateEntry(nsCacheEntry * entry);
   1.295 +
   1.296 +    nsresult         ProcessRequest(nsCacheRequest *           request,
   1.297 +                                    bool                       calledFromOpenCacheEntry,
   1.298 +                                    nsICacheEntryDescriptor ** result);
   1.299 +
   1.300 +    nsresult         ProcessPendingRequests(nsCacheEntry * entry);
   1.301 +
   1.302 +    void             ClearDoomList(void);
   1.303 +    void             DoomActiveEntries(DoomCheckFn check);
   1.304 +    void             CloseAllStreams();
   1.305 +    void             FireClearNetworkCacheStoredAnywhereNotification();
   1.306 +
   1.307 +    static
   1.308 +    PLDHashOperator  GetActiveEntries(PLDHashTable *    table,
   1.309 +                                      PLDHashEntryHdr * hdr,
   1.310 +                                      uint32_t          number,
   1.311 +                                      void *            arg);
   1.312 +    static
   1.313 +    PLDHashOperator  RemoveActiveEntry(PLDHashTable *    table,
   1.314 +                                       PLDHashEntryHdr * hdr,
   1.315 +                                       uint32_t          number,
   1.316 +                                       void *            arg);
   1.317 +
   1.318 +    static
   1.319 +    PLDHashOperator  ShutdownCustomCacheDeviceEnum(const nsAString& aProfileDir,
   1.320 +                                                   nsRefPtr<nsOfflineCacheDevice>& aDevice,
   1.321 +                                                   void* aUserArg);
   1.322 +#if defined(PR_LOGGING)
   1.323 +    void LogCacheStatistics();
   1.324 +#endif
   1.325 +
   1.326 +    nsresult         SetDiskSmartSize_Locked();
   1.327 +
   1.328 +    /**
   1.329 +     *  Data Members
   1.330 +     */
   1.331 +
   1.332 +    static nsCacheService *         gService;  // there can be only one...
   1.333 +
   1.334 +    nsCOMPtr<mozIStorageService>    mStorageService;
   1.335 +
   1.336 +    nsCacheProfilePrefObserver *    mObserver;
   1.337 +
   1.338 +    mozilla::Mutex                  mLock;
   1.339 +    mozilla::CondVar                mCondVar;
   1.340 +
   1.341 +    mozilla::Mutex                  mTimeStampLock;
   1.342 +    mozilla::TimeStamp              mLockAcquiredTimeStamp;
   1.343 +
   1.344 +    nsCOMPtr<nsIThread>             mCacheIOThread;
   1.345 +
   1.346 +    nsTArray<nsISupports*>          mDoomedObjects;
   1.347 +    nsCOMPtr<nsITimer>              mSmartSizeTimer;
   1.348 +
   1.349 +    bool                            mInitialized;
   1.350 +    bool                            mClearingEntries;
   1.351 +
   1.352 +    bool                            mEnableMemoryDevice;
   1.353 +    bool                            mEnableDiskDevice;
   1.354 +    bool                            mEnableOfflineDevice;
   1.355 +
   1.356 +    nsMemoryCacheDevice *           mMemoryDevice;
   1.357 +    nsDiskCacheDevice *             mDiskDevice;
   1.358 +    nsOfflineCacheDevice *          mOfflineDevice;
   1.359 +
   1.360 +    nsRefPtrHashtable<nsStringHashKey, nsOfflineCacheDevice> mCustomOfflineDevices;
   1.361 +
   1.362 +    nsCacheEntryHashTable           mActiveEntries;
   1.363 +    PRCList                         mDoomedEntries;
   1.364 +
   1.365 +    // stats
   1.366 +
   1.367 +    uint32_t                        mTotalEntries;
   1.368 +    uint32_t                        mCacheHits;
   1.369 +    uint32_t                        mCacheMisses;
   1.370 +    uint32_t                        mMaxKeyLength;
   1.371 +    uint32_t                        mMaxDataSize;
   1.372 +    uint32_t                        mMaxMetaSize;
   1.373 +
   1.374 +    // Unexpected error totals
   1.375 +    uint32_t                        mDeactivateFailures;
   1.376 +    uint32_t                        mDeactivatedUnboundEntries;
   1.377 +};
   1.378 +
   1.379 +/******************************************************************************
   1.380 + *  nsCacheServiceAutoLock
   1.381 + ******************************************************************************/
   1.382 +
   1.383 +#define LOCK_TELEM(x) \
   1.384 +  (::mozilla::Telemetry::CACHE_SERVICE_LOCK_WAIT_MAINTHREAD_##x)
   1.385 +
   1.386 +// Instantiate this class to acquire the cache service lock for a particular
   1.387 +// execution scope.
   1.388 +class nsCacheServiceAutoLock {
   1.389 +public:
   1.390 +    nsCacheServiceAutoLock(mozilla::Telemetry::ID mainThreadLockerID) {
   1.391 +        nsCacheService::Lock(mainThreadLockerID);
   1.392 +    }
   1.393 +    ~nsCacheServiceAutoLock() {
   1.394 +        nsCacheService::Unlock();
   1.395 +    }
   1.396 +};
   1.397 +
   1.398 +#endif // _nsCacheService_h_

mercurial