1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/netwerk/base/src/nsSocketTransportService2.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,241 @@ 1.4 +/* vim:set ts=4 sw=4 sts=4 ci et: */ 1.5 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.7 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.8 + 1.9 +#ifndef nsSocketTransportService2_h__ 1.10 +#define nsSocketTransportService2_h__ 1.11 + 1.12 +#include "nsPISocketTransportService.h" 1.13 +#include "nsIThreadInternal.h" 1.14 +#include "nsIRunnable.h" 1.15 +#include "nsEventQueue.h" 1.16 +#include "nsCOMPtr.h" 1.17 +#include "prinrval.h" 1.18 +#include "prlog.h" 1.19 +#include "prinit.h" 1.20 +#include "nsIObserver.h" 1.21 +#include "mozilla/Mutex.h" 1.22 +#include "mozilla/net/DashboardTypes.h" 1.23 + 1.24 +class nsASocketHandler; 1.25 +struct PRPollDesc; 1.26 + 1.27 +//----------------------------------------------------------------------------- 1.28 + 1.29 +#if defined(PR_LOGGING) 1.30 +// 1.31 +// set NSPR_LOG_MODULES=nsSocketTransport:5 1.32 +// 1.33 +extern PRLogModuleInfo *gSocketTransportLog; 1.34 +#endif 1.35 +#define SOCKET_LOG(args) PR_LOG(gSocketTransportLog, PR_LOG_DEBUG, args) 1.36 +#define SOCKET_LOG_ENABLED() PR_LOG_TEST(gSocketTransportLog, PR_LOG_DEBUG) 1.37 + 1.38 +//----------------------------------------------------------------------------- 1.39 + 1.40 +#define NS_SOCKET_POLL_TIMEOUT PR_INTERVAL_NO_TIMEOUT 1.41 + 1.42 +//----------------------------------------------------------------------------- 1.43 + 1.44 +namespace mozilla { 1.45 +namespace net { 1.46 +// These maximums are borrowed from the linux kernel. 1.47 +static const int32_t kMaxTCPKeepIdle = 32767; // ~9 hours. 1.48 +static const int32_t kMaxTCPKeepIntvl = 32767; 1.49 +static const int32_t kMaxTCPKeepCount = 127; 1.50 +static const int32_t kDefaultTCPKeepCount = 1.51 +#if defined (XP_WIN) 1.52 + 10; // Hardcoded in Windows. 1.53 +#elif defined (XP_MACOSX) 1.54 + 8; // Hardcoded in OSX. 1.55 +#else 1.56 + 4; // Specifiable in Linux. 1.57 +#endif 1.58 +} 1.59 +} 1.60 + 1.61 +//----------------------------------------------------------------------------- 1.62 + 1.63 +class nsSocketTransportService : public nsPISocketTransportService 1.64 + , public nsIEventTarget 1.65 + , public nsIThreadObserver 1.66 + , public nsIRunnable 1.67 + , public nsIObserver 1.68 +{ 1.69 + typedef mozilla::Mutex Mutex; 1.70 + 1.71 +public: 1.72 + NS_DECL_THREADSAFE_ISUPPORTS 1.73 + NS_DECL_NSPISOCKETTRANSPORTSERVICE 1.74 + NS_DECL_NSISOCKETTRANSPORTSERVICE 1.75 + NS_DECL_NSIEVENTTARGET 1.76 + NS_DECL_NSITHREADOBSERVER 1.77 + NS_DECL_NSIRUNNABLE 1.78 + NS_DECL_NSIOBSERVER 1.79 + 1.80 + nsSocketTransportService(); 1.81 + 1.82 + // Max Socket count may need to get initialized/used by nsHttpHandler 1.83 + // before this class is initialized. 1.84 + static uint32_t gMaxCount; 1.85 + static PRCallOnceType gMaxCountInitOnce; 1.86 + static PRStatus DiscoverMaxCount(); 1.87 + 1.88 + // 1.89 + // the number of sockets that can be attached at any given time is 1.90 + // limited. this is done because some operating systems (e.g., Win9x) 1.91 + // limit the number of sockets that can be created by an application. 1.92 + // AttachSocket will fail if the limit is exceeded. consumers should 1.93 + // call CanAttachSocket and check the result before creating a socket. 1.94 + // 1.95 + bool CanAttachSocket() { 1.96 + return mActiveCount + mIdleCount < gMaxCount; 1.97 + } 1.98 + 1.99 + // Called by the networking dashboard on the socket thread only 1.100 + // Fills the passed array with socket information 1.101 + void GetSocketConnections(nsTArray<mozilla::net::SocketInfo> *); 1.102 + uint64_t GetSentBytes() { return mSentBytesCount; } 1.103 + uint64_t GetReceivedBytes() { return mReceivedBytesCount; } 1.104 + 1.105 + // Returns true if keepalives are enabled in prefs. 1.106 + bool IsKeepaliveEnabled() { return mKeepaliveEnabledPref; } 1.107 +protected: 1.108 + 1.109 + virtual ~nsSocketTransportService(); 1.110 + 1.111 +private: 1.112 + 1.113 + //------------------------------------------------------------------------- 1.114 + // misc (any thread) 1.115 + //------------------------------------------------------------------------- 1.116 + 1.117 + nsCOMPtr<nsIThread> mThread; // protected by mLock 1.118 + PRFileDesc *mThreadEvent; 1.119 + // protected by mLock. mThreadEvent may change 1.120 + // if the old pollable event is broken. only 1.121 + // the socket thread may change mThreadEvent; 1.122 + // it needs to lock mLock only when it changes 1.123 + // mThreadEvent. other threads don't change 1.124 + // mThreadEvent; they need to lock mLock 1.125 + // whenever they access mThreadEvent. 1.126 + bool mAutodialEnabled; 1.127 + // pref to control autodial code 1.128 + 1.129 + // Returns mThread, protecting the get-and-addref with mLock 1.130 + already_AddRefed<nsIThread> GetThreadSafely(); 1.131 + 1.132 + //------------------------------------------------------------------------- 1.133 + // initialization and shutdown (any thread) 1.134 + //------------------------------------------------------------------------- 1.135 + 1.136 + Mutex mLock; 1.137 + bool mInitialized; 1.138 + bool mShuttingDown; 1.139 + // indicates whether we are currently in the 1.140 + // process of shutting down 1.141 + bool mOffline; 1.142 + bool mGoingOffline; 1.143 + 1.144 + // Detaches all sockets. 1.145 + void Reset(bool aGuardLocals); 1.146 + 1.147 + //------------------------------------------------------------------------- 1.148 + // socket lists (socket thread only) 1.149 + // 1.150 + // only "active" sockets are on the poll list. the active list is kept 1.151 + // in sync with the poll list such that: 1.152 + // 1.153 + // mActiveList[k].mFD == mPollList[k+1].fd 1.154 + // 1.155 + // where k=0,1,2,... 1.156 + //------------------------------------------------------------------------- 1.157 + 1.158 + struct SocketContext 1.159 + { 1.160 + PRFileDesc *mFD; 1.161 + nsASocketHandler *mHandler; 1.162 + uint16_t mElapsedTime; // time elapsed w/o activity 1.163 + }; 1.164 + 1.165 + SocketContext *mActiveList; /* mListSize entries */ 1.166 + SocketContext *mIdleList; /* mListSize entries */ 1.167 + 1.168 + uint32_t mActiveListSize; 1.169 + uint32_t mIdleListSize; 1.170 + uint32_t mActiveCount; 1.171 + uint32_t mIdleCount; 1.172 + 1.173 + nsresult DetachSocket(SocketContext *, SocketContext *); 1.174 + nsresult AddToIdleList(SocketContext *); 1.175 + nsresult AddToPollList(SocketContext *); 1.176 + void RemoveFromIdleList(SocketContext *); 1.177 + void RemoveFromPollList(SocketContext *); 1.178 + void MoveToIdleList(SocketContext *sock); 1.179 + void MoveToPollList(SocketContext *sock); 1.180 + 1.181 + bool GrowActiveList(); 1.182 + bool GrowIdleList(); 1.183 + void InitMaxCount(); 1.184 + 1.185 + // Total bytes number transfered through all the sockets except active ones 1.186 + uint64_t mSentBytesCount; 1.187 + uint64_t mReceivedBytesCount; 1.188 + //------------------------------------------------------------------------- 1.189 + // poll list (socket thread only) 1.190 + // 1.191 + // first element of the poll list is mThreadEvent (or null if the pollable 1.192 + // event cannot be created). 1.193 + //------------------------------------------------------------------------- 1.194 + 1.195 + PRPollDesc *mPollList; /* mListSize + 1 entries */ 1.196 + 1.197 + PRIntervalTime PollTimeout(); // computes ideal poll timeout 1.198 + nsresult DoPollIteration(bool wait); 1.199 + // perfoms a single poll iteration 1.200 + int32_t Poll(bool wait, uint32_t *interval); 1.201 + // calls PR_Poll. the out param 1.202 + // interval indicates the poll 1.203 + // duration in seconds. 1.204 + 1.205 + //------------------------------------------------------------------------- 1.206 + // pending socket queue - see NotifyWhenCanAttachSocket 1.207 + //------------------------------------------------------------------------- 1.208 + 1.209 + nsEventQueue mPendingSocketQ; // queue of nsIRunnable objects 1.210 + 1.211 + // Preference Monitor for SendBufferSize and Keepalive prefs. 1.212 + nsresult UpdatePrefs(); 1.213 + int32_t mSendBufferSize; 1.214 + // Number of seconds of connection is idle before first keepalive ping. 1.215 + int32_t mKeepaliveIdleTimeS; 1.216 + // Number of seconds between retries should keepalive pings fail. 1.217 + int32_t mKeepaliveRetryIntervalS; 1.218 + // Number of keepalive probes to send. 1.219 + int32_t mKeepaliveProbeCount; 1.220 + // True if TCP keepalive is enabled globally. 1.221 + bool mKeepaliveEnabledPref; 1.222 + 1.223 + void OnKeepaliveEnabledPrefChange(); 1.224 + void NotifyKeepaliveEnabledPrefChange(SocketContext *sock); 1.225 + 1.226 + // Socket thread only for dynamically adjusting max socket size 1.227 +#if defined(XP_WIN) 1.228 + void ProbeMaxCount(); 1.229 +#endif 1.230 + bool mProbedMaxCount; 1.231 + 1.232 + void AnalyzeConnection(nsTArray<mozilla::net::SocketInfo> *data, 1.233 + SocketContext *context, bool aActive); 1.234 + 1.235 + void ClosePrivateConnections(); 1.236 + void DetachSocketWithGuard(bool aGuardLocals, 1.237 + SocketContext *socketList, 1.238 + int32_t index); 1.239 +}; 1.240 + 1.241 +extern nsSocketTransportService *gSocketTransportService; 1.242 +extern PRThread *gSocketThread; 1.243 + 1.244 +#endif // !nsSocketTransportService_h__