netwerk/protocol/http/nsHttpConnectionMgr.h

Thu, 15 Jan 2015 21:03:48 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 15 Jan 2015 21:03:48 +0100
branch
TOR_BUG_9701
changeset 11
deefc01c0e14
permissions
-rw-r--r--

Integrate friendly tips from Tor colleagues to make (or not) 4.5 alpha 3;
This includes removal of overloaded (but unused) methods, and addition of
a overlooked call to DataStruct::SetData(nsISupports, uint32_t, bool.)

     1 /* vim:set ts=4 sw=4 sts=4 et cin: */
     2 /* This Source Code Form is subject to the terms of the Mozilla Public
     3  * License, v. 2.0. If a copy of the MPL was not distributed with this
     4  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     6 #ifndef nsHttpConnectionMgr_h__
     7 #define nsHttpConnectionMgr_h__
     9 #include "nsHttpConnection.h"
    10 #include "nsHttpTransaction.h"
    11 #include "nsTArray.h"
    12 #include "nsThreadUtils.h"
    13 #include "nsClassHashtable.h"
    14 #include "nsDataHashtable.h"
    15 #include "nsAutoPtr.h"
    16 #include "mozilla/ReentrantMonitor.h"
    17 #include "mozilla/TimeStamp.h"
    18 #include "mozilla/Attributes.h"
    20 #include "nsIObserver.h"
    21 #include "nsITimer.h"
    22 #include "nsIRandomGenerator.h"
    24 // We need our own optional debug define because pipelining behavior
    25 // is significantly altered by rendering speed (which is abysmal on
    26 // debug builds)
    27 #ifdef DEBUG
    28 # define WTF_DEBUG
    29 #endif
    31 #ifdef WTF_DEBUG
    32 # define WTF_TEST
    33 #endif 
    35 class nsIHttpUpgradeListener;
    37 namespace mozilla {
    38 namespace net {
    39 class EventTokenBucket;
    40 struct HttpRetParams;
    42 //-----------------------------------------------------------------------------
    44 class nsHttpConnectionMgr : public nsIObserver
    45 {
    46 public:
    47     NS_DECL_THREADSAFE_ISUPPORTS
    48     NS_DECL_NSIOBSERVER
    50     // parameter names
    51     enum nsParamName {
    52         MAX_CONNECTIONS,
    53         MAX_PERSISTENT_CONNECTIONS_PER_HOST,
    54         MAX_PERSISTENT_CONNECTIONS_PER_PROXY,
    55         MAX_REQUEST_DELAY,
    56         MAX_PIPELINED_REQUESTS,
    57         MAX_OPTIMISTIC_PIPELINED_REQUESTS
    58     };
    60     //-------------------------------------------------------------------------
    61     // NOTE: functions below may only be called on the main thread.
    62     //-------------------------------------------------------------------------
    64     nsHttpConnectionMgr();
    66     nsresult Init(uint16_t maxConnections,
    67                   uint16_t maxPersistentConnectionsPerHost,
    68                   uint16_t maxPersistentConnectionsPerProxy,
    69                   uint16_t maxRequestDelay,
    70                   uint16_t maxPipelinedRequests,
    71                   uint16_t maxOptimisticPipelinedRequests);
    72     nsresult Shutdown();
    74     //-------------------------------------------------------------------------
    75     // NOTE: functions below may be called on any thread.
    76     //-------------------------------------------------------------------------
    78     // Schedules next pruning of dead connection to happen after
    79     // given time.
    80     void PruneDeadConnectionsAfter(uint32_t time);
    82     // Stops timer scheduled for next pruning of dead connections if
    83     // there are no more idle connections or active spdy ones
    84     void ConditionallyStopPruneDeadConnectionsTimer();
    86     // Stops timer used for the read timeout tick if there are no currently
    87     // active connections.
    88     void ConditionallyStopTimeoutTick();
    90     // adds a transaction to the list of managed transactions.
    91     nsresult AddTransaction(nsHttpTransaction *, int32_t priority);
    93     // called to reschedule the given transaction.  it must already have been
    94     // added to the connection manager via AddTransaction.
    95     nsresult RescheduleTransaction(nsHttpTransaction *, int32_t priority);
    97     // cancels a transaction w/ the given reason.
    98     nsresult CancelTransaction(nsHttpTransaction *, nsresult reason);
   100     // called to force the connection manager to prune its list of idle
   101     // connections.
   102     nsresult PruneDeadConnections();
   104     // Close all idle persistent connections and prevent any active connections
   105     // from being reused. Optional connection info resets CI specific
   106     // information such as Happy Eyeballs history.
   107     nsresult DoShiftReloadConnectionCleanup(nsHttpConnectionInfo *);
   109     // called to get a reference to the socket transport service.  the socket
   110     // transport service is not available when the connection manager is down.
   111     nsresult GetSocketThreadTarget(nsIEventTarget **);
   113     // called to indicate a transaction for the connectionInfo is likely coming
   114     // soon. The connection manager may use this information to start a TCP
   115     // and/or SSL level handshake for that resource immediately so that it is
   116     // ready when the transaction is submitted. No obligation is taken on by the
   117     // connection manager, nor is the submitter obligated to actually submit a
   118     // real transaction for this connectionInfo.
   119     nsresult SpeculativeConnect(nsHttpConnectionInfo *,
   120                                 nsIInterfaceRequestor *,
   121                                 uint32_t caps = 0);
   123     // called when a connection is done processing a transaction.  if the
   124     // connection can be reused then it will be added to the idle list, else
   125     // it will be closed.
   126     nsresult ReclaimConnection(nsHttpConnection *conn);
   128     // called by the main thread to execute the taketransport() logic on the
   129     // socket thread after a 101 response has been received and the socket
   130     // needs to be transferred to an expectant upgrade listener such as
   131     // websockets.
   132     nsresult CompleteUpgrade(nsAHttpConnection *aConn,
   133                              nsIHttpUpgradeListener *aUpgradeListener);
   135     // called to update a parameter after the connection manager has already
   136     // been initialized.
   137     nsresult UpdateParam(nsParamName name, uint16_t value);
   139     // called from main thread to post a new request token bucket
   140     // to the socket thread
   141     nsresult UpdateRequestTokenBucket(EventTokenBucket *aBucket);
   143     // Pipielining Interfaces and Datatypes
   145     const static uint32_t kPipelineInfoTypeMask = 0xffff0000;
   146     const static uint32_t kPipelineInfoIDMask   = ~kPipelineInfoTypeMask;
   148     const static uint32_t kPipelineInfoTypeRed     = 0x00010000;
   149     const static uint32_t kPipelineInfoTypeBad     = 0x00020000;
   150     const static uint32_t kPipelineInfoTypeNeutral = 0x00040000;
   151     const static uint32_t kPipelineInfoTypeGood    = 0x00080000;
   153     enum PipelineFeedbackInfoType
   154     {
   155         // Used when an HTTP response less than 1.1 is received
   156         RedVersionTooLow = kPipelineInfoTypeRed | kPipelineInfoTypeBad | 0x0001,
   158         // Used when a HTTP Server response header that is on the banned from
   159         // pipelining list is received
   160         RedBannedServer = kPipelineInfoTypeRed | kPipelineInfoTypeBad | 0x0002,
   162         // Used when a response is terminated early, when it fails an
   163         // integrity check such as assoc-req or when a 304 contained a Last-Modified
   164         // differnet than the entry being validated.
   165         RedCorruptedContent = kPipelineInfoTypeRed | kPipelineInfoTypeBad | 0x0004,
   167         // Used when a pipeline is only partly satisfied - for instance if the
   168         // server closed the connection after responding to the first
   169         // request but left some requests unprocessed.
   170         RedCanceledPipeline = kPipelineInfoTypeRed | kPipelineInfoTypeBad | 0x0005,
   172         // Used when a connection that we expected to stay persistently open
   173         // was closed by the server. Not used when simply timed out.
   174         BadExplicitClose = kPipelineInfoTypeBad | 0x0003,
   176         // Used when there is a gap of around 400 - 1200ms in between data being
   177         // read from the server
   178         BadSlowReadMinor = kPipelineInfoTypeBad | 0x0006,
   180         // Used when there is a gap of > 1200ms in between data being
   181         // read from the server
   182         BadSlowReadMajor = kPipelineInfoTypeBad | 0x0007,
   184         // Used when a response is received that is not framed with either chunked
   185         // encoding or a complete content length.
   186         BadInsufficientFraming = kPipelineInfoTypeBad | 0x0008,
   188         // Used when a very large response is recevied in a potential pipelining
   189         // context. Large responses cause head of line blocking.
   190         BadUnexpectedLarge = kPipelineInfoTypeBad | 0x000B,
   192         // Used when a response is received that has headers that appear to support
   193         // pipelining.
   194         NeutralExpectedOK = kPipelineInfoTypeNeutral | 0x0009,
   196         // Used when a response is received successfully to a pipelined request.
   197         GoodCompletedOK = kPipelineInfoTypeGood | 0x000A
   198     };
   200     // called to provide information relevant to the pipelining manager
   201     // may be called from any thread
   202     void     PipelineFeedbackInfo(nsHttpConnectionInfo *,
   203                                   PipelineFeedbackInfoType info,
   204                                   nsHttpConnection *,
   205                                   uint32_t);
   207     void ReportFailedToProcess(nsIURI *uri);
   209     // Causes a large amount of connection diagnostic information to be
   210     // printed to the javascript console
   211     void PrintDiagnostics();
   213     //-------------------------------------------------------------------------
   214     // NOTE: functions below may be called only on the socket thread.
   215     //-------------------------------------------------------------------------
   217     // called to force the transaction queue to be processed once more, giving
   218     // preference to the specified connection.
   219     nsresult ProcessPendingQ(nsHttpConnectionInfo *);
   220     bool     ProcessPendingQForEntry(nsHttpConnectionInfo *);
   222     // Try and process all pending transactions
   223     nsresult ProcessPendingQ();
   225     // This is used to force an idle connection to be closed and removed from
   226     // the idle connection list. It is called when the idle connection detects
   227     // that the network peer has closed the transport.
   228     nsresult CloseIdleConnection(nsHttpConnection *);
   230     // The connection manager needs to know when a normal HTTP connection has been
   231     // upgraded to SPDY because the dispatch and idle semantics are a little
   232     // bit different.
   233     void ReportSpdyConnection(nsHttpConnection *, bool usingSpdy);
   235     // A spdy server can supply cwnd information for the session that is used
   236     // in future sessions to speed up the opening portions of the connection.
   237     void ReportSpdyCWNDSetting(nsHttpConnectionInfo *host, uint32_t cwndValue);
   238     uint32_t GetSpdyCWNDSetting(nsHttpConnectionInfo *host);
   240     bool     SupportsPipelining(nsHttpConnectionInfo *);
   242     bool GetConnectionData(nsTArray<HttpRetParams> *);
   244     void ResetIPFamilyPreference(nsHttpConnectionInfo *);
   246 private:
   247     virtual ~nsHttpConnectionMgr();
   249     enum PipeliningState {
   250         // Host has proven itself pipeline capable through past experience and
   251         // large pipeline depths are allowed on multiple connections.
   252         PS_GREEN,
   254         // Not enough information is available yet with this host to be certain
   255         // of pipeline capability. Small pipelines on a single connection are
   256         // allowed in order to decide whether or not to proceed to green.
   257         PS_YELLOW,
   259         // One or more bad events has happened that indicate that pipelining
   260         // to this host (or a particular type of transaction with this host)
   261         // is a bad idea. Pipelining is not currently allowed, but time and
   262         // other positive experiences will eventually allow it to try again.
   263         PS_RED
   264     };
   266     class nsHalfOpenSocket;
   268     // nsConnectionEntry
   269     //
   270     // mCT maps connection info hash key to nsConnectionEntry object, which
   271     // contains list of active and idle connections as well as the list of
   272     // pending transactions.
   273     //
   274     class nsConnectionEntry
   275     {
   276     public:
   277         nsConnectionEntry(nsHttpConnectionInfo *ci);
   278         ~nsConnectionEntry();
   280         nsHttpConnectionInfo        *mConnInfo;
   281         nsTArray<nsHttpTransaction*> mPendingQ;    // pending transaction queue
   282         nsTArray<nsHttpConnection*>  mActiveConns; // active connections
   283         nsTArray<nsHttpConnection*>  mIdleConns;   // idle persistent connections
   284         nsTArray<nsHalfOpenSocket*>  mHalfOpens;   // half open connections
   286         // calculate the number of half open sockets that have not had at least 1
   287         // connection complete
   288         uint32_t UnconnectedHalfOpens();
   290         // Remove a particular half open socket from the mHalfOpens array
   291         void RemoveHalfOpen(nsHalfOpenSocket *);
   293         // Pipeline depths for various states
   294         const static uint32_t kPipelineUnlimited  = 1024; // fully open - extended green
   295         const static uint32_t kPipelineOpen       = 6;    // 6 on each conn - normal green
   296         const static uint32_t kPipelineRestricted = 2;    // 2 on just 1 conn in yellow
   298         nsHttpConnectionMgr::PipeliningState PipelineState();
   299         void OnPipelineFeedbackInfo(
   300             nsHttpConnectionMgr::PipelineFeedbackInfoType info,
   301             nsHttpConnection *, uint32_t);
   302         bool SupportsPipelining();
   303         uint32_t MaxPipelineDepth(nsAHttpTransaction::Classifier classification);
   304         void CreditPenalty();
   306         nsHttpConnectionMgr::PipeliningState mPipelineState;
   308         void SetYellowConnection(nsHttpConnection *);
   309         void OnYellowComplete();
   310         uint32_t                  mYellowGoodEvents;
   311         uint32_t                  mYellowBadEvents;
   312         nsHttpConnection         *mYellowConnection;
   314         // initialGreenDepth is the max depth of a pipeline when you first
   315         // transition to green. Normally this is kPipelineOpen, but it can
   316         // be kPipelineUnlimited in aggressive mode.
   317         uint32_t                  mInitialGreenDepth;
   319         // greenDepth is the current max allowed depth of a pipeline when
   320         // in the green state. Normally this starts as kPipelineOpen and
   321         // grows to kPipelineUnlimited after a pipeline of depth 3 has been
   322         // successfully transacted.
   323         uint32_t                  mGreenDepth;
   325         // pipeliningPenalty is the current amount of penalty points this host
   326         // entry has earned for participating in events that are not conducive
   327         // to good pipelines - such as head of line blocking, canceled pipelines,
   328         // etc.. penalties are paid back either through elapsed time or simply
   329         // healthy transactions. Having penalty points means that this host is
   330         // not currently eligible for pipelines.
   331         int16_t                   mPipeliningPenalty;
   333         // some penalty points only apply to particular classifications of
   334         // transactions - this allows a server that perhaps has head of line
   335         // blocking problems on CGI queries to still serve JS pipelined.
   336         int16_t                   mPipeliningClassPenalty[nsAHttpTransaction::CLASS_MAX];
   338         // for calculating penalty repair credits
   339         TimeStamp        mLastCreditTime;
   341         // Spdy sometimes resolves the address in the socket manager in order
   342         // to re-coalesce sharded HTTP hosts. The dotted decimal address is
   343         // combined with the Anonymous flag from the connection information
   344         // to build the hash key for hosts in the same ip pool.
   345         //
   346         // When a set of hosts are coalesced together one of them is marked
   347         // mSpdyPreferred. The mapping is maintained in the connection mananger
   348         // mSpdyPreferred hash.
   349         //
   350         nsCString mCoalescingKey;
   352         // The value of a recevied SPDY settings type 5 previously received
   353         // for this connection entry and the time it was set.
   354         uint32_t            mSpdyCWND;
   355         TimeStamp  mSpdyCWNDTimeStamp;
   357         // To have the UsingSpdy flag means some host with the same connection
   358         // entry has done NPN=spdy/* at some point. It does not mean every
   359         // connection is currently using spdy.
   360         bool mUsingSpdy;
   362         // mTestedSpdy is set after NPN negotiation has occurred and we know
   363         // with confidence whether a host speaks spdy or not (which is reflected
   364         // in mUsingSpdy). Before mTestedSpdy is set, handshake parallelism is
   365         // minimized so that we can multiplex on a single spdy connection.
   366         bool mTestedSpdy;
   368         bool mSpdyPreferred;
   370         // Flags to remember our happy-eyeballs decision.
   371         // Reset only by Ctrl-F5 reload.
   372         // True when we've first connected an IPv4 server for this host,
   373         // initially false.
   374         bool mPreferIPv4 : 1;
   375         // True when we've first connected an IPv6 server for this host,
   376         // initially false.
   377         bool mPreferIPv6 : 1;
   379         // Set the IP family preference flags according the connected family
   380         void RecordIPFamilyPreference(uint16_t family);
   381         // Resets all flags to their default values
   382         void ResetIPFamilyPreference();
   383     };
   385     // nsConnectionHandle
   386     //
   387     // thin wrapper around a real connection, used to keep track of references
   388     // to the connection to determine when the connection may be reused.  the
   389     // transaction (or pipeline) owns a reference to this handle.  this extra
   390     // layer of indirection greatly simplifies consumer code, avoiding the
   391     // need for consumer code to know when to give the connection back to the
   392     // connection manager.
   393     //
   394     class nsConnectionHandle : public nsAHttpConnection
   395     {
   396     public:
   397         NS_DECL_THREADSAFE_ISUPPORTS
   398         NS_DECL_NSAHTTPCONNECTION(mConn)
   400         nsConnectionHandle(nsHttpConnection *conn) { NS_ADDREF(mConn = conn); }
   401         virtual ~nsConnectionHandle();
   403         nsHttpConnection *mConn;
   404     };
   406     // nsHalfOpenSocket is used to hold the state of an opening TCP socket
   407     // while we wait for it to establish and bind it to a connection
   409     class nsHalfOpenSocket MOZ_FINAL : public nsIOutputStreamCallback,
   410                                        public nsITransportEventSink,
   411                                        public nsIInterfaceRequestor,
   412                                        public nsITimerCallback
   413     {
   414     public:
   415         NS_DECL_THREADSAFE_ISUPPORTS
   416         NS_DECL_NSIOUTPUTSTREAMCALLBACK
   417         NS_DECL_NSITRANSPORTEVENTSINK
   418         NS_DECL_NSIINTERFACEREQUESTOR
   419         NS_DECL_NSITIMERCALLBACK
   421         nsHalfOpenSocket(nsConnectionEntry *ent,
   422                          nsAHttpTransaction *trans,
   423                          uint32_t caps);
   424         ~nsHalfOpenSocket();
   426         nsresult SetupStreams(nsISocketTransport **,
   427                               nsIAsyncInputStream **,
   428                               nsIAsyncOutputStream **,
   429                               bool isBackup);
   430         nsresult SetupPrimaryStreams();
   431         nsresult SetupBackupStreams();
   432         void     SetupBackupTimer();
   433         void     CancelBackupTimer();
   434         void     Abandon();
   435         double   Duration(TimeStamp epoch);
   436         nsISocketTransport *SocketTransport() { return mSocketTransport; }
   437         nsISocketTransport *BackupTransport() { return mBackupTransport; }
   439         nsAHttpTransaction *Transaction() { return mTransaction; }
   441         bool IsSpeculative() { return mSpeculative; }
   442         void SetSpeculative(bool val) { mSpeculative = val; }
   444         bool HasConnected() { return mHasConnected; }
   446         void PrintDiagnostics(nsCString &log);
   447     private:
   448         nsConnectionEntry              *mEnt;
   449         nsRefPtr<nsAHttpTransaction>   mTransaction;
   450         nsCOMPtr<nsISocketTransport>   mSocketTransport;
   451         nsCOMPtr<nsIAsyncOutputStream> mStreamOut;
   452         nsCOMPtr<nsIAsyncInputStream>  mStreamIn;
   453         uint32_t                       mCaps;
   455         // mSpeculative is set if the socket was created from
   456         // SpeculativeConnect(). It is cleared when a transaction would normally
   457         // start a new connection from scratch but instead finds this one in
   458         // the half open list and claims it for its own use. (which due to
   459         // the vagaries of scheduling from the pending queue might not actually
   460         // match up - but it prevents a speculative connection from opening
   461         // more connections that are needed.)
   462         bool                           mSpeculative;
   464         TimeStamp             mPrimarySynStarted;
   465         TimeStamp             mBackupSynStarted;
   467         // for syn retry
   468         nsCOMPtr<nsITimer>             mSynTimer;
   469         nsCOMPtr<nsISocketTransport>   mBackupTransport;
   470         nsCOMPtr<nsIAsyncOutputStream> mBackupStreamOut;
   471         nsCOMPtr<nsIAsyncInputStream>  mBackupStreamIn;
   473         bool                           mHasConnected;
   474     };
   475     friend class nsHalfOpenSocket;
   477     //-------------------------------------------------------------------------
   478     // NOTE: these members may be accessed from any thread (use mReentrantMonitor)
   479     //-------------------------------------------------------------------------
   481     ReentrantMonitor    mReentrantMonitor;
   482     nsCOMPtr<nsIEventTarget>     mSocketThreadTarget;
   484     // connection limits
   485     uint16_t mMaxConns;
   486     uint16_t mMaxPersistConnsPerHost;
   487     uint16_t mMaxPersistConnsPerProxy;
   488     uint16_t mMaxRequestDelay; // in seconds
   489     uint16_t mMaxPipelinedRequests;
   490     uint16_t mMaxOptimisticPipelinedRequests;
   491     bool mIsShuttingDown;
   493     //-------------------------------------------------------------------------
   494     // NOTE: these members are only accessed on the socket transport thread
   495     //-------------------------------------------------------------------------
   497     static PLDHashOperator ProcessOneTransactionCB(const nsACString &, nsAutoPtr<nsConnectionEntry> &, void *);
   498     static PLDHashOperator ProcessAllTransactionsCB(const nsACString &, nsAutoPtr<nsConnectionEntry> &, void *);
   500     static PLDHashOperator PruneDeadConnectionsCB(const nsACString &, nsAutoPtr<nsConnectionEntry> &, void *);
   501     static PLDHashOperator ShutdownPassCB(const nsACString &, nsAutoPtr<nsConnectionEntry> &, void *);
   502     static PLDHashOperator PurgeExcessIdleConnectionsCB(const nsACString &, nsAutoPtr<nsConnectionEntry> &, void *);
   503     static PLDHashOperator PurgeExcessSpdyConnectionsCB(const nsACString &, nsAutoPtr<nsConnectionEntry> &, void *);
   504     static PLDHashOperator ClosePersistentConnectionsCB(const nsACString &, nsAutoPtr<nsConnectionEntry> &, void *);
   505     bool     ProcessPendingQForEntry(nsConnectionEntry *, bool considerAll);
   506     bool     IsUnderPressure(nsConnectionEntry *ent,
   507                              nsHttpTransaction::Classifier classification);
   508     bool     AtActiveConnectionLimit(nsConnectionEntry *, uint32_t caps);
   509     nsresult TryDispatchTransaction(nsConnectionEntry *ent,
   510                                     bool onlyReusedConnection,
   511                                     nsHttpTransaction *trans);
   512     nsresult DispatchTransaction(nsConnectionEntry *,
   513                                  nsHttpTransaction *,
   514                                  nsHttpConnection *);
   515     nsresult DispatchAbstractTransaction(nsConnectionEntry *,
   516                                          nsAHttpTransaction *,
   517                                          uint32_t,
   518                                          nsHttpConnection *,
   519                                          int32_t);
   520     nsresult BuildPipeline(nsConnectionEntry *,
   521                            nsAHttpTransaction *,
   522                            nsHttpPipeline **);
   523     bool     HasPipelines(nsConnectionEntry *);
   524     bool     RestrictConnections(nsConnectionEntry *, bool = false);
   525     nsresult ProcessNewTransaction(nsHttpTransaction *);
   526     nsresult EnsureSocketThreadTarget();
   527     void     ClosePersistentConnections(nsConnectionEntry *ent);
   528     void     ReportProxyTelemetry(nsConnectionEntry *ent);
   529     nsresult CreateTransport(nsConnectionEntry *, nsAHttpTransaction *,
   530                              uint32_t, bool);
   531     void     AddActiveConn(nsHttpConnection *, nsConnectionEntry *);
   532     void     DecrementActiveConnCount(nsHttpConnection *);
   533     void     StartedConnect();
   534     void     RecvdConnect();
   536     nsConnectionEntry *GetOrCreateConnectionEntry(nsHttpConnectionInfo *);
   538     nsresult MakeNewConnection(nsConnectionEntry *ent,
   539                                nsHttpTransaction *trans);
   540     bool     AddToBestPipeline(nsConnectionEntry *ent,
   541                                    nsHttpTransaction *trans,
   542                                    nsHttpTransaction::Classifier classification,
   543                                    uint16_t depthLimit);
   545     // Manage the preferred spdy connection entry for this address
   546     nsConnectionEntry *GetSpdyPreferredEnt(nsConnectionEntry *aOriginalEntry);
   547     void               RemoveSpdyPreferredEnt(nsACString &aDottedDecimal);
   548     nsHttpConnection  *GetSpdyPreferredConn(nsConnectionEntry *ent);
   549     nsDataHashtable<nsCStringHashKey, nsConnectionEntry *>   mSpdyPreferredHash;
   550     nsConnectionEntry *LookupConnectionEntry(nsHttpConnectionInfo *ci,
   551                                              nsHttpConnection *conn,
   552                                              nsHttpTransaction *trans);
   554     void               ProcessSpdyPendingQ(nsConnectionEntry *ent);
   555     static PLDHashOperator ProcessSpdyPendingQCB(
   556         const nsACString &key, nsAutoPtr<nsConnectionEntry> &ent,
   557         void *closure);
   559     // message handlers have this signature
   560     typedef void (nsHttpConnectionMgr:: *nsConnEventHandler)(int32_t, void *);
   562     // nsConnEvent
   563     //
   564     // subclass of nsRunnable used to marshall events to the socket transport
   565     // thread.  this class is used to implement PostEvent.
   566     //
   567     class nsConnEvent;
   568     friend class nsConnEvent;
   569     class nsConnEvent : public nsRunnable
   570     {
   571     public:
   572         nsConnEvent(nsHttpConnectionMgr *mgr,
   573                     nsConnEventHandler handler,
   574                     int32_t iparam,
   575                     void *vparam)
   576             : mMgr(mgr)
   577             , mHandler(handler)
   578             , mIParam(iparam)
   579             , mVParam(vparam)
   580         {
   581             NS_ADDREF(mMgr);
   582         }
   584         NS_IMETHOD Run()
   585         {
   586             (mMgr->*mHandler)(mIParam, mVParam);
   587             return NS_OK;
   588         }
   590     private:
   591         virtual ~nsConnEvent()
   592         {
   593             NS_RELEASE(mMgr);
   594         }
   596         nsHttpConnectionMgr *mMgr;
   597         nsConnEventHandler   mHandler;
   598         int32_t              mIParam;
   599         void                *mVParam;
   600     };
   602     nsresult PostEvent(nsConnEventHandler  handler,
   603                        int32_t             iparam = 0,
   604                        void               *vparam = nullptr);
   606     // message handlers
   607     void OnMsgShutdown             (int32_t, void *);
   608     void OnMsgShutdownConfirm      (int32_t, void *);
   609     void OnMsgNewTransaction       (int32_t, void *);
   610     void OnMsgReschedTransaction   (int32_t, void *);
   611     void OnMsgCancelTransaction    (int32_t, void *);
   612     void OnMsgProcessPendingQ      (int32_t, void *);
   613     void OnMsgPruneDeadConnections (int32_t, void *);
   614     void OnMsgSpeculativeConnect   (int32_t, void *);
   615     void OnMsgReclaimConnection    (int32_t, void *);
   616     void OnMsgCompleteUpgrade      (int32_t, void *);
   617     void OnMsgUpdateParam          (int32_t, void *);
   618     void OnMsgDoShiftReloadConnectionCleanup (int32_t, void *);
   619     void OnMsgProcessFeedback      (int32_t, void *);
   620     void OnMsgProcessAllSpdyPendingQ (int32_t, void *);
   621     void OnMsgUpdateRequestTokenBucket (int32_t, void *);
   623     // Total number of active connections in all of the ConnectionEntry objects
   624     // that are accessed from mCT connection table.
   625     uint16_t mNumActiveConns;
   626     // Total number of idle connections in all of the ConnectionEntry objects
   627     // that are accessed from mCT connection table.
   628     uint16_t mNumIdleConns;
   629     // Total number of spdy connections which are a subset of the active conns
   630     uint16_t mNumSpdyActiveConns;
   631     // Total number of connections in mHalfOpens ConnectionEntry objects
   632     // that are accessed from mCT connection table
   633     uint32_t mNumHalfOpenConns;
   635     // Holds time in seconds for next wake-up to prune dead connections.
   636     uint64_t mTimeOfNextWakeUp;
   637     // Timer for next pruning of dead connections.
   638     nsCOMPtr<nsITimer> mTimer;
   640     // A 1s tick to call nsHttpConnection::ReadTimeoutTick on
   641     // active http/1 connections and check for orphaned half opens.
   642     // Disabled when there are no active or half open connections.
   643     nsCOMPtr<nsITimer> mTimeoutTick;
   644     bool mTimeoutTickArmed;
   645     uint32_t mTimeoutTickNext;
   647     //
   648     // the connection table
   649     //
   650     // this table is indexed by connection key.  each entry is a
   651     // nsConnectionEntry object. It is unlocked and therefore must only
   652     // be accessed from the socket thread.
   653     //
   654     nsClassHashtable<nsCStringHashKey, nsConnectionEntry> mCT;
   656     static PLDHashOperator ReadConnectionEntry(const nsACString &key,
   657                                                nsAutoPtr<nsConnectionEntry> &ent,
   658                                                void *aArg);
   660     // Read Timeout Tick handlers
   661     void ActivateTimeoutTick();
   662     void TimeoutTick();
   663     static PLDHashOperator TimeoutTickCB(const nsACString &key,
   664                                          nsAutoPtr<nsConnectionEntry> &ent,
   665                                          void *closure);
   667     // For diagnostics
   668     void OnMsgPrintDiagnostics(int32_t, void *);
   669     static PLDHashOperator PrintDiagnosticsCB(const nsACString &key,
   670                                               nsAutoPtr<nsConnectionEntry> &ent,
   671                                               void *closure);
   672     nsCString mLogData;
   673 };
   675 }} // namespace mozilla::net
   677 #endif // !nsHttpConnectionMgr_h__

mercurial