DXR is a code search and navigation tool aimed at making sense of large projects. It supports full-text and regex searches as well as structural queries.

Implementation

Mercurial (409f3966645a)

VCS Links

Line Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#ifndef nsPrefetchService_h__
#define nsPrefetchService_h__

#include "nsCPrefetchService.h"
#include "nsIObserver.h"
#include "nsIInterfaceRequestor.h"
#include "nsIChannelEventSink.h"
#include "nsIRedirectResultListener.h"
#include "nsIWebProgressListener.h"
#include "nsIStreamListener.h"
#include "nsIChannel.h"
#include "nsIURI.h"
#include "nsWeakReference.h"
#include "nsCOMPtr.h"
#include "nsAutoPtr.h"
#include "mozilla/Attributes.h"
#include <deque>

class nsPrefetchService;
class nsPrefetchNode;

//-----------------------------------------------------------------------------
// nsPrefetchService
//-----------------------------------------------------------------------------

class nsPrefetchService final : public nsIPrefetchService
                              , public nsIWebProgressListener
                              , public nsIObserver
                              , public nsSupportsWeakReference
{
public:
    NS_DECL_ISUPPORTS
    NS_DECL_NSIPREFETCHSERVICE
    NS_DECL_NSIWEBPROGRESSLISTENER
    NS_DECL_NSIOBSERVER

    nsPrefetchService();

    nsresult Init();
    void     RemoveNodeAndMaybeStartNextPrefetchURI(nsPrefetchNode *aFinished);
    void     ProcessNextPrefetchURI();

    void NotifyLoadRequested(nsPrefetchNode *node);
    void NotifyLoadCompleted(nsPrefetchNode *node);
    void DispatchEvent(nsPrefetchNode *node, bool aSuccess);

private:
    ~nsPrefetchService();

    nsresult Prefetch(nsIURI *aURI,
                      nsIURI *aReferrerURI,
                      nsINode *aSource,
                      bool aExplicit);

    nsresult Preload(nsIURI *aURI,
                     nsIURI *aReferrerURI,
                     nsINode *aSource,
                     nsContentPolicyType aPolicyType);

    void     AddProgressListener();
    void     RemoveProgressListener();
    nsresult EnqueueURI(nsIURI *aURI, nsIURI *aReferrerURI,
                        nsINode *aSource, nsPrefetchNode **node);
    void     EmptyPrefetchQueue();

    void     StartPrefetching();
    void     StopPrefetching();
    void     StopCurrentPrefetchsPreloads(bool aPreload);
    void     StopAll();
    nsresult CheckURIScheme(nsIURI *aURI, nsIURI *aReferrerURI);

    std::deque<RefPtr<nsPrefetchNode>> mPrefetchQueue;
    nsTArray<RefPtr<nsPrefetchNode>>   mCurrentNodes;
    int32_t                            mMaxParallelism;
    int32_t                            mStopCount;
    bool                               mHaveProcessed;
    bool                               mPrefetchDisabled;
    bool                               mPreloadDisabled;

    // In usual case prefetch does not start until all normal loads are done.
    // Aggressive mode ignores normal loads and just start prefetch ASAP.
    // It's mainly for testing purpose and discoraged for normal use;
    // see https://bugzilla.mozilla.org/show_bug.cgi?id=1281415 for details.
    bool                               mAggressive;
};

//-----------------------------------------------------------------------------
// nsPreFetchingNode
//-----------------------------------------------------------------------------

class nsPrefetchNode final : public nsIStreamListener
                           , public nsIInterfaceRequestor
                           , public nsIChannelEventSink
                           , public nsIRedirectResultListener
{
public:
    NS_DECL_ISUPPORTS
    NS_DECL_NSIREQUESTOBSERVER
    NS_DECL_NSISTREAMLISTENER
    NS_DECL_NSIINTERFACEREQUESTOR
    NS_DECL_NSICHANNELEVENTSINK
    NS_DECL_NSIREDIRECTRESULTLISTENER

    nsPrefetchNode(nsPrefetchService *aPrefetchService,
                   nsIURI *aURI,
                   nsIURI *aReferrerURI,
                   nsINode *aSource,
                   nsContentPolicyType aPolicyType,
                   bool aPreload);

    nsresult OpenChannel();
    nsresult CancelChannel(nsresult error);

    nsCOMPtr<nsIURI>                      mURI;
    nsCOMPtr<nsIURI>                      mReferrerURI;
    nsTArray<nsCOMPtr<nsIWeakReference>>  mSources;

    // The policy type to be used for fetching the resource.
    nsContentPolicyType                   mPolicyType;
    // nsPrefetchNode is used for prefetching and preloading resource.
    // mPreload is true if a resource is preloaded. Preloads and
    // prefetches are fetched in different phases (during load and
    // after a page load), therefore we need to distinguish them.
    bool                                  mPreload;

private:
    ~nsPrefetchNode() {}

    RefPtr<nsPrefetchService>   mService;
    nsCOMPtr<nsIChannel>        mChannel;
    nsCOMPtr<nsIChannel>        mRedirectChannel;
    int64_t                     mBytesRead;
    bool                        mShouldFireLoadEvent;
};

#endif // !nsPrefetchService_h__