summaryrefslogtreecommitdiffstats
path: root/netwerk/base/Tickler.h
blob: 264ecefebb1d64d7625daa53c405d3ac8b3665ae (plain)
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
/* -*- 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 "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 MOZ_UNANNOTATED;
  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