Thu, 15 Jan 2015 21:03:48 +0100
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__