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 (56e7b9127e89)

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
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* 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 nsHTMLDNSPrefetch_h___
#define nsHTMLDNSPrefetch_h___

#include "nsCOMPtr.h"
#include "nsString.h"

#include "nsIDNSListener.h"
#include "nsIWebProgressListener.h"
#include "nsWeakReference.h"
#include "nsIObserver.h"

class nsIDocument;
class nsITimer;
namespace mozilla {
namespace dom {
class Link;
} // namespace dom
} // namespace mozilla

namespace mozilla {
namespace net {
class NeckoParent;
} // namespace net
} // namespace mozilla

class nsHTMLDNSPrefetch
{
public:
  // The required aDocument parameter is the context requesting the prefetch - under
  // certain circumstances (e.g. headers, or security context) associated with
  // the context the prefetch will not be performed.
  static bool     IsAllowed(nsIDocument *aDocument);

  static nsresult Initialize();
  static nsresult Shutdown();

  // Call one of the Prefetch* methods to start the lookup.
  //
  // The URI versions will defer DNS lookup until pageload is
  // complete, while the string versions submit the lookup to
  // the DNS system immediately. The URI version is somewhat lighter
  // weight, but its request is also more likely to be dropped due to a
  // full queue and it may only be used from the main thread.

  static nsresult PrefetchHigh(mozilla::dom::Link *aElement);
  static nsresult PrefetchMedium(mozilla::dom::Link *aElement);
  static nsresult PrefetchLow(mozilla::dom::Link *aElement);
  static nsresult PrefetchHigh(const nsAString &host,
                               const mozilla::OriginAttributes &aOriginAttributes);
  static nsresult PrefetchMedium(const nsAString &host,
                                 const mozilla::OriginAttributes &aOriginAttributes);
  static nsresult PrefetchLow(const nsAString &host,
                              const mozilla::OriginAttributes &aOriginAttributes);
  static nsresult CancelPrefetchLow(const nsAString &host,
                                    const mozilla::OriginAttributes &aOriginAttributes,
                                    nsresult aReason);
  static nsresult CancelPrefetchLow(mozilla::dom::Link *aElement,
                                    nsresult aReason);

  static void LinkDestroyed(mozilla::dom::Link* aLink);

private:
  static nsresult Prefetch(const nsAString &host,
                           const mozilla::OriginAttributes &aOriginAttributes,
                           uint16_t flags);
  static nsresult Prefetch(mozilla::dom::Link *aElement, uint16_t flags);
  static nsresult CancelPrefetch(const nsAString &hostname,
                                 const mozilla::OriginAttributes &aOriginAttributes,
                                 uint16_t flags,
                                 nsresult aReason);
  static nsresult CancelPrefetch(mozilla::dom::Link *aElement,
                                 uint16_t flags,
                                 nsresult aReason);

public:
  class nsListener final : public nsIDNSListener
  {
    // This class exists to give a safe callback no-op DNSListener
  public:
    NS_DECL_THREADSAFE_ISUPPORTS
    NS_DECL_NSIDNSLISTENER

    nsListener()  {}
  private:
    ~nsListener() {}
  };

  class nsDeferrals final: public nsIWebProgressListener
                         , public nsSupportsWeakReference
                         , public nsIObserver
  {
  public:
    NS_DECL_ISUPPORTS
    NS_DECL_NSIWEBPROGRESSLISTENER
    NS_DECL_NSIOBSERVER

    nsDeferrals();

    void Activate();
    nsresult Add(uint16_t flags, mozilla::dom::Link *aElement);

    void RemoveUnboundLinks();

  private:
    ~nsDeferrals();
    void Flush();

    void SubmitQueue();

    uint16_t                  mHead;
    uint16_t                  mTail;
    uint32_t                  mActiveLoaderCount;

    nsCOMPtr<nsITimer>        mTimer;
    bool                      mTimerArmed;
    static void Tick(nsITimer *aTimer, void *aClosure);

    static const int          sMaxDeferred = 512;  // keep power of 2 for masking
    static const int          sMaxDeferredMask = (sMaxDeferred - 1);

    struct deferred_entry
    {
      uint16_t                         mFlags;
      // Link implementation clears this raw pointer in its destructor.
      mozilla::dom::Link*              mElement;
    } mEntries[sMaxDeferred];
  };

  friend class mozilla::net::NeckoParent;
};

#endif