Bug 1432429 DelayHttpChannelQueue 5/14
MozReview-Commit-ID: HbvegayNkkD
new file mode 100644
--- /dev/null
+++ b/netwerk/protocol/http/DelayHttpChannelQueue.cpp
@@ -0,0 +1,123 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* vim:set et cin ts=4 sw=4 sts=4: */
+/* 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/. */
+
+#include "DelayHttpChannelQueue.h"
+#include "mozilla/Services.h"
+#include "mozilla/StaticPtr.h"
+
+using namespace mozilla;
+using namespace mozilla::net;
+
+namespace {
+StaticRefPtr<DelayHttpChannelQueue> sDelayHttpChannelQueue;
+}
+
+bool
+DelayHttpChannelQueue::AttemptQueueChannel(nsHttpChannel* aChannel)
+{
+ MOZ_ASSERT(aChannel);
+ MOZ_ASSERT(NS_IsMainThread());
+
+ if (!sDelayHttpChannelQueue) {
+ RefPtr<DelayHttpChannelQueue> queue = new DelayHttpChannelQueue();
+ if (!queue->Initialize()) {
+ return false;
+ }
+
+ sDelayHttpChannelQueue = queue;
+ }
+
+ if (NS_WARN_IF(!sDelayHttpChannelQueue->mQueue.AppendElement(aChannel, fallible))) {
+ return false;
+ }
+
+ return true;
+}
+
+DelayHttpChannelQueue::DelayHttpChannelQueue()
+{
+ MOZ_ASSERT(NS_IsMainThread());
+}
+
+DelayHttpChannelQueue::~DelayHttpChannelQueue()
+{
+ MOZ_ASSERT(NS_IsMainThread());
+}
+
+bool
+DelayHttpChannelQueue::Initialize()
+{
+ MOZ_ASSERT(NS_IsMainThread());
+
+ nsCOMPtr<nsIObserverService> obs = services::GetObserverService();
+ if (NS_WARN_IF(!obs)) {
+ return false;
+ }
+
+ nsresult rv = obs->AddObserver(this, "fuzzyfox-fire-outbound", false);
+ if (NS_WARN_IF(NS_FAILED(rv))) {
+ return false;
+ }
+
+ rv = obs->AddObserver(this, "xpcom-shutdown", false);
+ if (NS_WARN_IF(NS_FAILED(rv))) {
+ return false;
+ }
+
+ return true;
+}
+
+NS_IMETHODIMP
+DelayHttpChannelQueue::Observe(nsISupports* aSubject, const char* aTopic,
+ const char16_t* aData)
+{
+ MOZ_ASSERT(NS_IsMainThread());
+
+ if (!strcmp(aTopic, "fuzzyfox-fire-outbound")) {
+ FireQueue();
+ return NS_OK;
+ }
+
+ MOZ_ASSERT(!strcmp(aTopic, "xpcom-shutdown"));
+
+ nsCOMPtr<nsIObserverService> obs = services::GetObserverService();
+ if (NS_WARN_IF(!obs)) {
+ return NS_OK;
+ }
+
+ obs->RemoveObserver(this, "fuzzyfox-fire-outbound");
+ obs->RemoveObserver(this, "xpcom-shutdown");
+
+ return NS_OK;
+}
+
+void
+DelayHttpChannelQueue::FireQueue()
+{
+ MOZ_ASSERT(NS_IsMainThread());
+
+ if (mQueue.IsEmpty()) {
+ return;
+ }
+
+ //TODO: get this from the DOM clock?
+ TimeStamp ts = TimeStamp::Now();
+
+ FallibleTArray<RefPtr<nsHttpChannel>> queue;
+ queue.SwapElements(mQueue);
+
+ for (RefPtr<nsHttpChannel>& channel : queue) {
+ channel->AsyncOpenFinal(ts);
+ }
+}
+
+NS_INTERFACE_MAP_BEGIN(DelayHttpChannelQueue)
+ NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIObserver)
+ NS_INTERFACE_MAP_ENTRY(nsIObserver)
+NS_INTERFACE_MAP_END
+
+NS_IMPL_ADDREF(DelayHttpChannelQueue)
+NS_IMPL_RELEASE(DelayHttpChannelQueue)
new file mode 100644
--- /dev/null
+++ b/netwerk/protocol/http/DelayHttpChannelQueue.h
@@ -0,0 +1,43 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* vim:set et cin ts=4 sw=4 sts=4: */
+/* 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_DelayHttpChannelQueue_h
+#define mozilla_net_DelayHttpChannelQueue_h
+
+#include "nsIObserver.h"
+#include "nsTArray.h"
+
+namespace mozilla {
+namespace net {
+
+class nsHttpChannel;
+
+class DelayHttpChannelQueue final : public nsIObserver
+{
+public:
+ static bool
+ AttemptQueueChannel(nsHttpChannel* aChannel);
+
+ NS_DECL_ISUPPORTS
+ NS_DECL_NSIOBSERVER
+
+private:
+ DelayHttpChannelQueue();
+ ~DelayHttpChannelQueue();
+
+ bool
+ Initialize();
+
+ void
+ FireQueue();
+
+ FallibleTArray<RefPtr<nsHttpChannel>> mQueue;
+};
+
+} // net namespace
+} // mozilla namespace
+
+#endif // mozilla_net_DelayHttpChannelQueue_h
--- a/netwerk/protocol/http/moz.build
+++ b/netwerk/protocol/http/moz.build
@@ -95,16 +95,21 @@ UNIFIED_SOURCES += [
'nsHttpResponseHead.cpp',
'nsHttpTransaction.cpp',
'nsServerTiming.cpp',
'NullHttpChannel.cpp',
'NullHttpTransaction.cpp',
'TunnelUtils.cpp',
]
+if CONFIG['MOZ_FUZZYFOX']:
+ UNIFIED_SOURCES += [
+ 'DelayHttpChannelQueue.cpp',
+ ]
+
# These files cannot be built in unified mode because of OS X headers.
SOURCES += [
'nsHttpHandler.cpp',
]
IPDL_SOURCES += [
'PAltDataOutputStream.ipdl',
'PHttpBackgroundChannel.ipdl',
--- a/netwerk/protocol/http/nsHttpChannel.cpp
+++ b/netwerk/protocol/http/nsHttpChannel.cpp
@@ -6011,24 +6011,41 @@ nsHttpChannel::AsyncOpen(nsIStreamListen
}
mIsPending = true;
mWasOpened = true;
mListener = listener;
mListenerContext = context;
+#ifdef MOZ_FUZZYFOX
+ // PauseTask/DelayHttpChannel queuing
+ if (!DelayHttpChannelQueue::AttemptQueueChannel(this)) {
+ // If failed, the channel must continue.
+ AsyncOpenFinal(TimeStamp::Now());
+ }
+
+ return NS_OK;
+}
+
+nsresult
+nsHttpChannel::AsyncOpenFinal(TimeStamp aTimeStamp)
+{
+ // Added due to PauseTask/DelayHttpChannel
+ nsresult rv;
+#endif
+
if (mLoadGroup)
mLoadGroup->AddRequest(this, nullptr);
// record asyncopen time unconditionally and clear it if we
// don't want it after OnModifyRequest() weighs in. But waiting for
// that to complete would mean we don't include proxy resolution in the
// timing.
- mAsyncOpenTime = TimeStamp::Now();
+ mAsyncOpenTime = aTimeStamp;
// Remember we have Authorization header set here. We need to check on it
// just once and early, AsyncOpen is the best place.
mCustomAuthHeader = mRequestHead.HasHeader(nsHttp::Authorization);
// The common case for HTTP channels is to begin proxy resolution and return
// at this point. The only time we know mProxyInfo already is if we're
// proxying a non-http protocol like ftp. We don't need to discover proxy
--- a/netwerk/protocol/http/nsHttpChannel.h
+++ b/netwerk/protocol/http/nsHttpChannel.h
@@ -28,16 +28,20 @@
#include "nsIStreamListener.h"
#include "nsISupportsPrimitives.h"
#include "nsICorsPreflightCallback.h"
#include "AlternateServices.h"
#include "nsIRaceCacheWithNetwork.h"
#include "mozilla/extensions/PStreamFilterParent.h"
#include "mozilla/Mutex.h"
+#ifdef MOZ_FUZZYFOX
+#include "DelayHttpChannelQueue.h"
+#endif
+
class nsDNSPrefetch;
class nsICancelable;
class nsIHttpChannelAuthProvider;
class nsInputStreamPump;
class nsISSLStatus;
namespace mozilla { namespace net {
@@ -196,16 +200,20 @@ public:
HttpChannelSecurityWarningReporter* GetWarningReporter();
public: /* internal necko use only */
uint32_t GetRequestTime() const
{
return mRequestTime;
}
+#ifdef MOZ_FUZZYFOX
+ nsresult AsyncOpenFinal(TimeStamp aTimeStamp);
+#endif
+
MOZ_MUST_USE nsresult OpenCacheEntry(bool usingSSL);
MOZ_MUST_USE nsresult OpenCacheEntryInternal(bool isHttps,
nsIApplicationCache *applicationCache,
bool noAppCache);
MOZ_MUST_USE nsresult ContinueConnect();
MOZ_MUST_USE nsresult StartRedirectChannelToURI(nsIURI *, uint32_t);