Source code

Revision control

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
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* 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 mozilla_net_Tickler_h
#define mozilla_net_Tickler_h

// The tickler sends a regular 0 byte UDP heartbeat out to a
// particular address for a short time after it has been touched. This
// is used on some mobile wifi chipsets to mitigate Power Save Polling
// (PSP) Mode when we are anticipating a response packet
// soon. Typically PSP adds 100ms of latency to a read event because
// the packet delivery is not triggered until the 802.11 beacon is
// delivered to the host (100ms is the standard Access Point
// configuration for the beacon interval.) Requesting a frequent
// transmission and getting a CTS frame from the AP at least that
// frequently allows for low latency receives when we have reason to
// expect them (e.g a SYN-ACK).
//
// The tickler is used to allow RTT based phases of web transport to
// complete quickly when on wifi - ARP, DNS, TCP handshake, SSL
// handshake, HTTP headers, and the TCP slow start phase. The
// transaction is given up to 400 miliseconds by default to get
// through those phases before the tickler is disabled.
//
// The tickler only applies to wifi on mobile right now. Hopefully it
// can also be restricted to particular handset models in the future.

#if defined(ANDROID) && !defined(MOZ_PROXY_BYPASS_PROTECTION)
#  define MOZ_USE_WIFI_TICKLER
#endif

#include "mozilla/Attributes.h"
#include "nsISupports.h"
#include <stdint.h>

#ifdef MOZ_USE_WIFI_TICKLER
#  include "mozilla/Mutex.h"
#  include "mozilla/TimeStamp.h"
#  include "nsAutoPtr.h"
#  include "nsISupports.h"
#  include "nsIThread.h"
#  include "nsITimer.h"
#  include "nsWeakReference.h"
#  include "prio.h"

class nsIPrefBranch;
#endif

namespace mozilla {
namespace net {

#ifdef MOZ_USE_WIFI_TICKLER

// 8f769ed6-207c-4af9-9f7e-9e832da3754e
#  define NS_TICKLER_IID                               \
    {                                                  \
      0x8f769ed6, 0x207c, 0x4af9, {                    \
        0x9f, 0x7e, 0x9e, 0x83, 0x2d, 0xa3, 0x75, 0x4e \
      }                                                \
    }

class Tickler final : public nsSupportsWeakReference {
 public:
  NS_DECL_THREADSAFE_ISUPPORTS
  NS_DECLARE_STATIC_IID_ACCESSOR(NS_TICKLER_IID)

  // These methods are main thread only
  Tickler();
  void Cancel();
  nsresult Init();
  void SetIPV4Address(uint32_t address);
  void SetIPV4Port(uint16_t port);

  // Tickle the tickler to (re-)start the activity.
  // May call from any thread
  void Tickle();

 private:
  ~Tickler();

  friend class TicklerTimer;
  Mutex mLock;
  nsCOMPtr<nsIThread> mThread;
  nsCOMPtr<nsITimer> mTimer;
  nsCOMPtr<nsIPrefBranch> mPrefs;

  bool mActive;
  bool mCanceled;
  bool mEnabled;
  uint32_t mDelay;
  TimeDuration mDuration;
  PRFileDesc* mFD;

  TimeStamp mLastTickle;
  PRNetAddr mAddr;

  // These functions may be called from any thread
  void PostCheckTickler();
  void MaybeStartTickler();
  void MaybeStartTicklerUnlocked();

  // Tickler thread only
  void CheckTickler();
  void StartTickler();
  void StopTickler();
};

NS_DEFINE_STATIC_IID_ACCESSOR(Tickler, NS_TICKLER_IID)

#else  // not defined MOZ_USE_WIFI_TICKLER

class Tickler final : public nsISupports {
  ~Tickler() = default;

 public:
  NS_DECL_THREADSAFE_ISUPPORTS

  Tickler() = default;
  nsresult Init() { return NS_ERROR_NOT_IMPLEMENTED; }
  void Cancel() {}
  void SetIPV4Address(uint32_t){};
  void SetIPV4Port(uint16_t) {}
  void Tickle() {}
};

#endif  // defined MOZ_USE_WIFI_TICKLER

}  // namespace net
}  // namespace mozilla

#endif  // mozilla_net_Tickler_h