michael@0: /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: #ifndef mozilla_net_Tickler_h michael@0: #define mozilla_net_Tickler_h michael@0: michael@0: // The tickler sends a regular 0 byte UDP heartbeat out to a michael@0: // particular address for a short time after it has been touched. This michael@0: // is used on some mobile wifi chipsets to mitigate Power Save Polling michael@0: // (PSP) Mode when we are anticipating a response packet michael@0: // soon. Typically PSP adds 100ms of latency to a read event because michael@0: // the packet delivery is not triggered until the 802.11 beacon is michael@0: // delivered to the host (100ms is the standard Access Point michael@0: // configuration for the beacon interval.) Requesting a frequent michael@0: // transmission and getting a CTS frame from the AP at least that michael@0: // frequently allows for low latency receives when we have reason to michael@0: // expect them (e.g a SYN-ACK). michael@0: // michael@0: // The tickler is used to allow RTT based phases of web transport to michael@0: // complete quickly when on wifi - ARP, DNS, TCP handshake, SSL michael@0: // handshake, HTTP headers, and the TCP slow start phase. The michael@0: // transaction is given up to 400 miliseconds by default to get michael@0: // through those phases before the tickler is disabled. michael@0: // michael@0: // The tickler only applies to wifi on mobile right now. Hopefully it michael@0: // can also be restricted to particular handset models in the future. michael@0: michael@0: #if defined(ANDROID) && !defined(MOZ_B2G) michael@0: #define MOZ_USE_WIFI_TICKLER michael@0: #endif michael@0: michael@0: #include "mozilla/Attributes.h" michael@0: #include "nsISupports.h" michael@0: #include michael@0: michael@0: #ifdef MOZ_USE_WIFI_TICKLER michael@0: #include "mozilla/Mutex.h" michael@0: #include "mozilla/TimeStamp.h" michael@0: #include "nsAutoPtr.h" michael@0: #include "nsISupports.h" michael@0: #include "nsIThread.h" michael@0: #include "nsITimer.h" michael@0: #include "nsWeakReference.h" michael@0: #include "prio.h" michael@0: michael@0: class nsIPrefBranch; michael@0: #endif michael@0: michael@0: namespace mozilla { michael@0: namespace net { michael@0: michael@0: #ifdef MOZ_USE_WIFI_TICKLER michael@0: michael@0: // 8f769ed6-207c-4af9-9f7e-9e832da3754e michael@0: #define NS_TICKLER_IID \ michael@0: { 0x8f769ed6, 0x207c, 0x4af9, \ michael@0: { 0x9f, 0x7e, 0x9e, 0x83, 0x2d, 0xa3, 0x75, 0x4e } } michael@0: michael@0: class Tickler MOZ_FINAL : public nsSupportsWeakReference michael@0: { michael@0: public: michael@0: NS_DECL_THREADSAFE_ISUPPORTS michael@0: NS_DECLARE_STATIC_IID_ACCESSOR(NS_TICKLER_IID) michael@0: michael@0: // These methods are main thread only michael@0: Tickler(); michael@0: ~Tickler(); michael@0: void Cancel(); michael@0: nsresult Init(); michael@0: void SetIPV4Address(uint32_t address); michael@0: void SetIPV4Port(uint16_t port); michael@0: michael@0: // Tickle the tickler to (re-)start the activity. michael@0: // May call from any thread michael@0: void Tickle(); michael@0: michael@0: private: michael@0: friend class TicklerTimer; michael@0: Mutex mLock; michael@0: nsCOMPtr mThread; michael@0: nsCOMPtr mTimer; michael@0: nsCOMPtr mPrefs; michael@0: michael@0: bool mActive; michael@0: bool mCanceled; michael@0: bool mEnabled; michael@0: uint32_t mDelay; michael@0: TimeDuration mDuration; michael@0: PRFileDesc* mFD; michael@0: michael@0: TimeStamp mLastTickle; michael@0: PRNetAddr mAddr; michael@0: michael@0: // These functions may be called from any thread michael@0: void PostCheckTickler(); michael@0: void MaybeStartTickler(); michael@0: void MaybeStartTicklerUnlocked(); michael@0: michael@0: // Tickler thread only michael@0: void CheckTickler(); michael@0: void StartTickler(); michael@0: void StopTickler(); michael@0: }; michael@0: michael@0: NS_DEFINE_STATIC_IID_ACCESSOR(Tickler, NS_TICKLER_IID) michael@0: michael@0: #else // not defined MOZ_USE_WIFI_TICKLER michael@0: michael@0: class Tickler MOZ_FINAL : public nsISupports michael@0: { michael@0: public: michael@0: NS_DECL_THREADSAFE_ISUPPORTS michael@0: michael@0: Tickler() { } michael@0: ~Tickler() { } michael@0: nsresult Init() { return NS_ERROR_NOT_IMPLEMENTED; } michael@0: void Cancel() { } michael@0: void SetIPV4Address(uint32_t) { }; michael@0: void SetIPV4Port(uint16_t) { } michael@0: void Tickle() { } michael@0: }; michael@0: michael@0: #endif // defined MOZ_USE_WIFI_TICKLER michael@0: michael@0: } // namespace mozilla::net michael@0: } // namespace mozilla michael@0: michael@0: #endif // mozilla_net_Tickler_h