Bug 1127618 - make push caches work in e10s. r=mcmanus r=froydnj IGNORE IDL

This commit is contained in:
Nicholas Hurley 2015-07-31 13:50:08 -07:00
parent c2f1ab6c42
commit 8642eb435f
44 changed files with 644 additions and 225 deletions

View File

@ -0,0 +1,203 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 ;*; */
/* vim: set sw=2 ts=8 et tw=80 : */
/* 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 "nsAutoPtr.h"
#include "nsIObserverService.h"
#include "nsIUUIDGenerator.h"
#include "nsServiceManagerUtils.h"
#include "nsThreadUtils.h"
#include "SchedulingContextService.h"
#include "mozilla/Atomics.h"
#include "mozilla/Services.h"
#include "mozilla/net/PSpdyPush.h"
namespace mozilla {
namespace net {
// nsISchedulingContext
class SchedulingContext final : public nsISchedulingContext
{
public:
NS_DECL_THREADSAFE_ISUPPORTS
NS_DECL_NSISCHEDULINGCONTEXT
explicit SchedulingContext(const nsID& id);
private:
virtual ~SchedulingContext();
nsID mID;
char mCID[NSID_LENGTH];
Atomic<uint32_t> mBlockingTransactionCount;
nsAutoPtr<SpdyPushCache> mSpdyCache;
};
NS_IMPL_ISUPPORTS(SchedulingContext, nsISchedulingContext)
SchedulingContext::SchedulingContext(const nsID& aID)
: mBlockingTransactionCount(0)
{
mID = aID;
mID.ToProvidedString(mCID);
}
SchedulingContext::~SchedulingContext()
{
}
NS_IMETHODIMP
SchedulingContext::GetBlockingTransactionCount(uint32_t *aBlockingTransactionCount)
{
NS_ENSURE_ARG_POINTER(aBlockingTransactionCount);
*aBlockingTransactionCount = mBlockingTransactionCount;
return NS_OK;
}
NS_IMETHODIMP
SchedulingContext::AddBlockingTransaction()
{
mBlockingTransactionCount++;
return NS_OK;
}
NS_IMETHODIMP
SchedulingContext::RemoveBlockingTransaction(uint32_t *outval)
{
NS_ENSURE_ARG_POINTER(outval);
mBlockingTransactionCount--;
*outval = mBlockingTransactionCount;
return NS_OK;
}
/* [noscript] attribute SpdyPushCachePtr spdyPushCache; */
NS_IMETHODIMP
SchedulingContext::GetSpdyPushCache(mozilla::net::SpdyPushCache **aSpdyPushCache)
{
*aSpdyPushCache = mSpdyCache.get();
return NS_OK;
}
NS_IMETHODIMP
SchedulingContext::SetSpdyPushCache(mozilla::net::SpdyPushCache *aSpdyPushCache)
{
mSpdyCache = aSpdyPushCache;
return NS_OK;
}
/* [noscript] readonly attribute nsID ID; */
NS_IMETHODIMP
SchedulingContext::GetID(nsID *outval)
{
NS_ENSURE_ARG_POINTER(outval);
*outval = mID;
return NS_OK;
}
//nsISchedulingContextService
SchedulingContextService *SchedulingContextService::sSelf = nullptr;
NS_IMPL_ISUPPORTS(SchedulingContextService, nsISchedulingContextService, nsIObserver)
SchedulingContextService::SchedulingContextService()
{
MOZ_ASSERT(!sSelf, "multiple scs instances!");
MOZ_ASSERT(NS_IsMainThread());
sSelf = this;
}
SchedulingContextService::~SchedulingContextService()
{
MOZ_ASSERT(NS_IsMainThread());
Shutdown();
sSelf = nullptr;
}
nsresult
SchedulingContextService::Init()
{
MOZ_ASSERT(NS_IsMainThread());
nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
if (!obs) {
return NS_ERROR_NOT_AVAILABLE;
}
return obs->AddObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID, false);
}
void
SchedulingContextService::Shutdown()
{
MOZ_ASSERT(NS_IsMainThread());
mTable.Clear();
}
/* static */ nsresult
SchedulingContextService::Create(nsISupports *aOuter, const nsIID& aIID, void **aResult)
{
MOZ_ASSERT(NS_IsMainThread());
if (aOuter != nullptr) {
return NS_ERROR_NO_AGGREGATION;
}
nsRefPtr<SchedulingContextService> svc = new SchedulingContextService();
nsresult rv = svc->Init();
NS_ENSURE_SUCCESS(rv, rv);
return svc->QueryInterface(aIID, aResult);
}
NS_IMETHODIMP
SchedulingContextService::GetSchedulingContext(const nsID& scID, nsISchedulingContext **sc)
{
MOZ_ASSERT(NS_IsMainThread());
NS_ENSURE_ARG_POINTER(sc);
*sc = nullptr;
if (!mTable.Get(scID, sc)) {
nsCOMPtr<nsISchedulingContext> newSC = new SchedulingContext(scID);
mTable.Put(scID, newSC);
newSC.swap(*sc);
}
return NS_OK;
}
NS_IMETHODIMP
SchedulingContextService::NewSchedulingContextID(nsID *scID)
{
MOZ_ASSERT(NS_IsMainThread());
if (!mUUIDGen) {
nsresult rv;
mUUIDGen = do_GetService("@mozilla.org/uuid-generator;1", &rv);
NS_ENSURE_SUCCESS(rv, rv);
}
return mUUIDGen->GenerateUUIDInPlace(scID);
}
NS_IMETHODIMP
SchedulingContextService::RemoveSchedulingContext(const nsID& scID)
{
MOZ_ASSERT(NS_IsMainThread());
mTable.Remove(scID);
return NS_OK;
}
NS_IMETHODIMP
SchedulingContextService::Observe(nsISupports *subject, const char *topic,
const char16_t *data_unicode)
{
MOZ_ASSERT(NS_IsMainThread());
if (!strcmp(NS_XPCOM_SHUTDOWN_OBSERVER_ID, topic)) {
Shutdown();
}
return NS_OK;
}
} // ::mozilla::net
} // ::mozilla

View File

@ -0,0 +1,46 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 ;*; */
/* vim: set sw=2 ts=8 et tw=80 : */
/* 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__SchedulingContextService_h
#define mozilla__net__SchedulingContextService_h
#include "nsCOMPtr.h"
#include "nsInterfaceHashtable.h"
#include "nsIObserver.h"
#include "nsISchedulingContext.h"
class nsIUUIDGenerator;
namespace mozilla {
namespace net {
class SchedulingContextService final : public nsISchedulingContextService
, public nsIObserver
{
public:
NS_DECL_ISUPPORTS
NS_DECL_NSISCHEDULINGCONTEXTSERVICE
NS_DECL_NSIOBSERVER
SchedulingContextService();
nsresult Init();
void Shutdown();
static nsresult Create(nsISupports *outer, const nsIID& iid, void **result);
private:
virtual ~SchedulingContextService();
static SchedulingContextService *sSelf;
nsInterfaceHashtable<nsIDHashKey, nsISchedulingContext> mTable;
nsCOMPtr<nsIUUIDGenerator> mUUIDGen;
};
} // ::mozilla::net
} // ::mozilla
#endif // mozilla__net__SchedulingContextService_h

View File

@ -92,6 +92,7 @@ XPIDL_SOURCES += [
'nsIRequestObserverProxy.idl',
'nsIResponseHeadProvider.idl',
'nsIResumableChannel.idl',
'nsISchedulingContext.idl',
'nsISecCheckWrapChannel.idl',
'nsISecretDecoderRing.idl',
'nsISecureBrowserUI.idl',
@ -243,6 +244,7 @@ UNIFIED_SOURCES += [
'Predictor.cpp',
'ProxyAutoConfig.cpp',
'RedirectChannelRegistrar.cpp',
'SchedulingContextService.cpp',
'StreamingProtocolService.cpp',
'Tickler.cpp',
'TLSServerSocket.cpp',

View File

@ -8,14 +8,14 @@
interface nsISimpleEnumerator;
interface nsIRequestObserver;
interface nsIInterfaceRequestor;
interface nsILoadGroupConnectionInfo;
interface nsISchedulingContext;
typedef unsigned long nsLoadFlags;
/**
* A load group maintains a collection of nsIRequest objects.
*/
[scriptable, uuid(afb57ac2-bce5-4ee3-bb34-385089a9ba5c)]
[scriptable, uuid(ff6a41f9-0bbf-44ca-9c71-f76c1da2b114)]
interface nsILoadGroup : nsIRequest
{
/**
@ -76,10 +76,10 @@ interface nsILoadGroup : nsIRequest
attribute nsIInterfaceRequestor notificationCallbacks;
/**
* Connection information for managing things like js/css
* connection blocking, and per-tab connection grouping
* Context for managing things like js/css connection blocking,
* and per-tab connection grouping.
*/
readonly attribute nsILoadGroupConnectionInfo connectionInfo;
readonly attribute nsID schedulingContextID;
/**
* The set of load flags that will be added to all new requests added to
@ -94,48 +94,3 @@ interface nsILoadGroup : nsIRequest
*/
attribute nsLoadFlags defaultLoadFlags;
};
%{C++
// Forward-declare mozilla::net::SpdyPushCache
namespace mozilla {
namespace net {
class SpdyPushCache;
}
}
%}
[ptr] native SpdyPushCachePtr(mozilla::net::SpdyPushCache);
/**
* Used to maintain state about the connections of a load group and
* how they interact with blocking items like HEAD css/js loads.
*/
[uuid(fdc9659c-b597-4ac0-9c9e-14b04dbb682f)]
interface nsILoadGroupConnectionInfo : nsISupports
{
/**
* Number of active blocking transactions associated with this load group
*/
readonly attribute unsigned long blockingTransactionCount;
/**
* Increase the number of active blocking transactions associated
* with this load group by one.
*/
void addBlockingTransaction();
/**
* Decrease the number of active blocking transactions associated
* with this load group by one. The return value is the number of remaining
* blockers.
*/
unsigned long removeBlockingTransaction();
/* reading this attribute gives out weak pointers to the push
* cache. The nsILoadGroupConnectionInfo implemenation owns the cache
* and will destroy it when overwritten or when the load group
* ends.
*/
[noscript] attribute SpdyPushCachePtr spdyPushCache;
};

View File

@ -0,0 +1,90 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 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 "nsISupports.idl"
%{C++
// Forward-declare mozilla::net::SpdyPushCache
namespace mozilla {
namespace net {
class SpdyPushCache;
}
}
%}
[ptr] native SpdyPushCachePtr(mozilla::net::SpdyPushCache);
/**
* The nsISchedulingContext is used to maintain state about connections
* that are in some way associated with each other (often by being part
* of the same load group) and how they interact with blocking items like
* HEAD css/js loads.
*
* This used to be known as nsILoadGroupConnectionInfo.
*/
[scriptable, uuid(658e3e6e-8633-4b1a-8d66-fa9f72293e63)]
interface nsISchedulingContext : nsISupports
{
/**
* A unique identifier for this scheduling context
*/
[noscript] readonly attribute nsID ID;
/**
* Number of active blocking transactions associated with this context
*/
readonly attribute unsigned long blockingTransactionCount;
/**
* Increase the number of active blocking transactions associated
* with this context by one.
*/
void addBlockingTransaction();
/**
* Decrease the number of active blocking transactions associated
* with this context by one. The return value is the number of remaining
* blockers.
*/
unsigned long removeBlockingTransaction();
/**
* This gives out a weak pointer to the push cache.
* The nsISchedulingContext implementation owns the cache
* and will destroy it when overwritten or when the context
* ends.
*/
[noscript] attribute SpdyPushCachePtr spdyPushCache;
};
/**
* The nsISchedulingContextService is how anyone gets access to a scheduling
* context when they haven't been explicitly given a strong reference to an
* existing one. It is responsible for creating and handing out strong
* references to nsISchedulingContexts, but only keeps weak references itself.
* The shared scheduling context will go away once no one else is keeping a
* reference to it. If you ask for a scheduling context that has no one else
* holding a reference to it, you'll get a brand new scheduling context. Anyone
* who asks for the same scheduling context while you're holding a reference
* will get a reference to the same scheduling context you have.
*/
[uuid(7fcbf4da-d828-4acc-b144-e5435198f727)]
interface nsISchedulingContextService : nsISupports
{
/**
* Get an existing scheduling context from its ID
*/
nsISchedulingContext getSchedulingContext(in nsIDRef id);
/**
* Create a new scheduling context identifier
*/
nsID newSchedulingContextID();
/**
* Remove an existing scheduling context from its ID
*/
void removeSchedulingContext(in nsIDRef id);
};

View File

@ -14,16 +14,16 @@
#include "mozilla/Logging.h"
#include "nsString.h"
#include "nsTArray.h"
#include "mozilla/Atomics.h"
#include "mozilla/Telemetry.h"
#include "nsAutoPtr.h"
#include "mozilla/net/PSpdyPush.h"
#include "nsITimedChannel.h"
#include "nsIInterfaceRequestor.h"
#include "nsIRequestObserver.h"
#include "nsISchedulingContext.h"
#include "CacheObserver.h"
#include "MainThreadUtils.h"
#include "mozilla/net/NeckoChild.h"
using namespace mozilla;
using namespace mozilla::net;
@ -43,69 +43,6 @@ static PRLogModuleInfo* gLoadGroupLog = nullptr;
#undef LOG
#define LOG(args) MOZ_LOG(gLoadGroupLog, mozilla::LogLevel::Debug, args)
////////////////////////////////////////////////////////////////////////////////
// nsLoadGroupConnectionInfo
class nsLoadGroupConnectionInfo final : public nsILoadGroupConnectionInfo
{
~nsLoadGroupConnectionInfo() {}
public:
NS_DECL_THREADSAFE_ISUPPORTS
NS_DECL_NSILOADGROUPCONNECTIONINFO
nsLoadGroupConnectionInfo();
private:
Atomic<uint32_t> mBlockingTransactionCount;
nsAutoPtr<mozilla::net::SpdyPushCache> mSpdyCache;
};
NS_IMPL_ISUPPORTS(nsLoadGroupConnectionInfo, nsILoadGroupConnectionInfo)
nsLoadGroupConnectionInfo::nsLoadGroupConnectionInfo()
: mBlockingTransactionCount(0)
{
}
NS_IMETHODIMP
nsLoadGroupConnectionInfo::GetBlockingTransactionCount(uint32_t *aBlockingTransactionCount)
{
NS_ENSURE_ARG_POINTER(aBlockingTransactionCount);
*aBlockingTransactionCount = mBlockingTransactionCount;
return NS_OK;
}
NS_IMETHODIMP
nsLoadGroupConnectionInfo::AddBlockingTransaction()
{
mBlockingTransactionCount++;
return NS_OK;
}
NS_IMETHODIMP
nsLoadGroupConnectionInfo::RemoveBlockingTransaction(uint32_t *_retval)
{
NS_ENSURE_ARG_POINTER(_retval);
mBlockingTransactionCount--;
*_retval = mBlockingTransactionCount;
return NS_OK;
}
/* [noscript] attribute SpdyPushCachePtr spdyPushCache; */
NS_IMETHODIMP
nsLoadGroupConnectionInfo::GetSpdyPushCache(mozilla::net::SpdyPushCache **aSpdyPushCache)
{
*aSpdyPushCache = mSpdyCache.get();
return NS_OK;
}
NS_IMETHODIMP
nsLoadGroupConnectionInfo::SetSpdyPushCache(mozilla::net::SpdyPushCache *aSpdyPushCache)
{
mSpdyCache = aSpdyPushCache;
return NS_OK;
}
////////////////////////////////////////////////////////////////////////////////
class RequestMapEntry : public PLDHashEntryHdr
@ -170,7 +107,6 @@ nsLoadGroup::nsLoadGroup(nsISupports* outer)
: mForegroundCount(0)
, mLoadFlags(LOAD_NORMAL)
, mDefaultLoadFlags(0)
, mConnectionInfo(new nsLoadGroupConnectionInfo())
, mRequests(&sRequestHashOps, sizeof(RequestMapEntry))
, mStatus(NS_OK)
, mPriority(PRIORITY_NORMAL)
@ -196,6 +132,23 @@ nsLoadGroup::~nsLoadGroup()
mDefaultLoadRequest = 0;
if (mSchedulingContext) {
nsID scid;
mSchedulingContext->GetID(&scid);
if (IsNeckoChild() && gNeckoChild) {
char scid_str[NSID_LENGTH];
scid.ToProvidedString(scid_str);
nsCString scid_nscs;
scid_nscs.AssignASCII(scid_str);
gNeckoChild->SendRemoveSchedulingContext(scid_nscs);
} else {
mSchedulingContextService->RemoveSchedulingContext(scid);
}
}
LOG(("LOADGROUP [%x]: Destroyed.\n", this));
}
@ -758,12 +711,12 @@ nsLoadGroup::SetNotificationCallbacks(nsIInterfaceRequestor *aCallbacks)
}
NS_IMETHODIMP
nsLoadGroup::GetConnectionInfo(nsILoadGroupConnectionInfo **aCI)
nsLoadGroup::GetSchedulingContextID(nsID *aSCID)
{
NS_ENSURE_ARG_POINTER(aCI);
*aCI = mConnectionInfo;
NS_IF_ADDREF(*aCI);
return NS_OK;
if (!mSchedulingContext) {
return NS_ERROR_NOT_AVAILABLE;
}
return mSchedulingContext->GetID(aSCID);
}
////////////////////////////////////////////////////////////////////////////////
@ -1113,4 +1066,18 @@ nsresult nsLoadGroup::MergeDefaultLoadFlags(nsIRequest *aRequest,
return rv;
}
nsresult nsLoadGroup::Init()
{
mSchedulingContextService = do_GetService("@mozilla.org/network/scheduling-context-service;1");
if (mSchedulingContextService) {
nsID schedulingContextID;
if (NS_SUCCEEDED(mSchedulingContextService->NewSchedulingContextID(&schedulingContextID))) {
mSchedulingContextService->GetSchedulingContext(schedulingContextID,
getter_AddRefs(mSchedulingContext));
}
}
return NS_OK;
}
#undef LOG

View File

@ -17,7 +17,8 @@
#include "pldhash.h"
#include "mozilla/TimeStamp.h"
class nsILoadGroupConnectionInfo;
class nsISchedulingContext;
class nsISchedulingContextService;
class nsITimedChannel;
class nsLoadGroup : public nsILoadGroup,
@ -52,6 +53,8 @@ public:
explicit nsLoadGroup(nsISupports* outer);
virtual ~nsLoadGroup();
nsresult Init();
protected:
nsresult MergeLoadFlags(nsIRequest *aRequest, nsLoadFlags& flags);
nsresult MergeDefaultLoadFlags(nsIRequest *aRequest, nsLoadFlags& flags);
@ -68,7 +71,8 @@ protected:
nsCOMPtr<nsILoadGroup> mLoadGroup; // load groups can contain load groups
nsCOMPtr<nsIInterfaceRequestor> mCallbacks;
nsCOMPtr<nsILoadGroupConnectionInfo> mConnectionInfo;
nsCOMPtr<nsISchedulingContext> mSchedulingContext;
nsCOMPtr<nsISchedulingContextService> mSchedulingContextService;
nsCOMPtr<nsIRequest> mDefaultLoadRequest;
PLDHashTable mRequests;

View File

@ -480,6 +480,17 @@
{ 0x92, 0x05, 0xc3, 0x09, 0xce, 0xb2, 0xd6, 0x41 } \
}
// service implementing nsISchedulingContextService
#define NS_SCHEDULINGCONTEXTSERVICE_CONTRACTID \
"@mozilla.org/network/scheduling-context-service;1"
#define NS_SCHEDULINGCONTEXTSERVICE_CID \
{ /* d5499fa7-7ba8-49ff-9e30-1858b99ace69 */ \
0xd5499fa7, \
0x7ba8, \
0x49ff, \
{0x93, 0x30, 0x18, 0x58, 0xb9, 0x9a, 0xce, 0x69} \
}
/******************************************************************************
* netwerk/cache/ classes
*/

View File

@ -112,7 +112,7 @@ NS_GENERIC_FACTORY_CONSTRUCTOR(nsSafeFileOutputStream)
NS_GENERIC_FACTORY_CONSTRUCTOR(nsFileStream)
NS_GENERIC_AGGREGATED_CONSTRUCTOR(nsLoadGroup)
NS_GENERIC_AGGREGATED_CONSTRUCTOR_INIT(nsLoadGroup, Init)
#include "ArrayBufferInputStream.h"
NS_GENERIC_FACTORY_CONSTRUCTOR(ArrayBufferInputStream)
@ -131,7 +131,6 @@ NS_GENERIC_FACTORY_CONSTRUCTOR(RedirectChannelRegistrar)
typedef mozilla::net::CacheStorageService CacheStorageService;
NS_GENERIC_FACTORY_CONSTRUCTOR(CacheStorageService)
///////////////////////////////////////////////////////////////////////////////
#include "mozilla/net/CaptivePortalService.h"
@ -141,6 +140,10 @@ namespace net {
} // namespace net
} // namespace mozilla
#include "SchedulingContextService.h"
typedef mozilla::net::SchedulingContextService SchedulingContextService;
NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(SchedulingContextService, Init)
///////////////////////////////////////////////////////////////////////////////
extern nsresult
@ -828,6 +831,7 @@ NS_DEFINE_NAMED_CID(NS_REDIRECTCHANNELREGISTRAR_CID);
NS_DEFINE_NAMED_CID(NS_CACHE_STORAGE_SERVICE_CID);
NS_DEFINE_NAMED_CID(NS_NETWORKPREDICTOR_CID);
NS_DEFINE_NAMED_CID(NS_CAPTIVEPORTAL_CID);
NS_DEFINE_NAMED_CID(NS_SCHEDULINGCONTEXTSERVICE_CID);
static const mozilla::Module::CIDEntry kNeckoCIDs[] = {
{ &kNS_IOSERVICE_CID, false, nullptr, nsIOServiceConstructor },
@ -977,6 +981,7 @@ static const mozilla::Module::CIDEntry kNeckoCIDs[] = {
{ &kNS_CACHE_STORAGE_SERVICE_CID, false, nullptr, CacheStorageServiceConstructor },
{ &kNS_NETWORKPREDICTOR_CID, false, nullptr, mozilla::net::Predictor::Create },
{ &kNS_CAPTIVEPORTAL_CID, false, nullptr, mozilla::net::CaptivePortalServiceConstructor },
{ &kNS_SCHEDULINGCONTEXTSERVICE_CID, false, nullptr, SchedulingContextServiceConstructor },
{ nullptr }
};
@ -1131,6 +1136,7 @@ static const mozilla::Module::ContractIDEntry kNeckoContracts[] = {
{ NS_CACHE_STORAGE_SERVICE_CONTRACTID2, &kNS_CACHE_STORAGE_SERVICE_CID },
{ NS_NETWORKPREDICTOR_CONTRACTID, &kNS_NETWORKPREDICTOR_CID },
{ NS_CAPTIVEPORTAL_CONTRACTID, &kNS_CAPTIVEPORTAL_CID },
{ NS_SCHEDULINGCONTEXTSERVICE_CONTRACTID, &kNS_SCHEDULINGCONTEXTSERVICE_CID },
{ nullptr }
};

View File

@ -92,6 +92,7 @@ struct HttpChannelOpenArgs
OptionalLoadInfoArgs loadInfo;
OptionalHttpResponseHead synthesizedResponseHead;
uint32_t cacheKey;
nsCString schedulingContextID;
};
struct HttpChannelConnectArgs

View File

@ -48,6 +48,8 @@ NeckoChild::NeckoChild()
NeckoChild::~NeckoChild()
{
//Send__delete__(gNeckoChild);
gNeckoChild = nullptr;
}
void NeckoChild::InitNeckoChild()
@ -63,21 +65,6 @@ void NeckoChild::InitNeckoChild()
}
}
// Note: not actually called; has some lifespan as child process, so
// automatically destroyed at exit.
void NeckoChild::DestroyNeckoChild()
{
MOZ_ASSERT(IsNeckoChild(), "DestroyNeckoChild called by non-child!");
static bool alreadyDestroyed = false;
MOZ_ASSERT(!alreadyDestroyed, "DestroyNeckoChild already called!");
if (!alreadyDestroyed) {
Send__delete__(gNeckoChild);
gNeckoChild = nullptr;
alreadyDestroyed = true;
}
}
PHttpChannelChild*
NeckoChild::AllocPHttpChannelChild(const PBrowserOrId& browser,
const SerializedLoadContext& loadContext,

View File

@ -23,7 +23,6 @@ public:
virtual ~NeckoChild();
static void InitNeckoChild();
static void DestroyNeckoChild();
protected:
virtual PHttpChannelChild*

View File

@ -970,5 +970,21 @@ NeckoParent::OfflineNotification(nsISupports *aSubject)
return NS_OK;
}
bool
NeckoParent::RecvRemoveSchedulingContext(const nsCString& scid)
{
nsCOMPtr<nsISchedulingContextService> scsvc =
do_GetService("@mozilla.org/network/scheduling-context-service;1");
if (!scsvc) {
return true;
}
nsID id;
id.Parse(scid.BeginReading());
scsvc->RemoveSchedulingContext(id);
return true;
}
} // namespace net
} // namespace mozilla

View File

@ -224,6 +224,8 @@ protected:
const IPC::SerializedLoadContext& aLoadContext) override;
virtual bool RecvPredReset() override;
virtual bool RecvRemoveSchedulingContext(const nsCString& scid) override;
private:
nsCString mCoreAppsBasePath;
nsCString mWebAppsBasePath;

View File

@ -108,6 +108,8 @@ parent:
nsString password, nsString domain);
OnAuthCancelled(uint64_t callbackId, bool userCancel);
RemoveSchedulingContext(nsCString scid);
child:
/*
* Bring up the http auth prompt for a nested remote mozbrowser.

View File

@ -77,7 +77,7 @@ Http2PushedStream::Http2PushedStream(Http2PushTransactionBuffer *aTransaction,
mStreamID = aID;
MOZ_ASSERT(!(aID & 1)); // must be even to be a pushed stream
mBufferedPush->SetPushStream(this);
mLoadGroupCI = aAssociatedStream->LoadGroupConnectionInfo();
mSchedulingContext = aAssociatedStream->SchedulingContext();
mLastRead = TimeStamp::Now();
SetPriority(aAssociatedStream->Priority() + 1);
}

View File

@ -16,6 +16,7 @@
#include "mozilla/TimeStamp.h"
#include "nsHttpRequestHead.h"
#include "nsILoadGroup.h"
#include "nsISchedulingContext.h"
#include "nsString.h"
#include "PSpdyPush.h"
@ -45,7 +46,7 @@ public:
nsresult ReadSegments(nsAHttpSegmentReader *, uint32_t, uint32_t *) override;
nsresult WriteSegments(nsAHttpSegmentWriter *, uint32_t, uint32_t *) override;
nsILoadGroupConnectionInfo *LoadGroupConnectionInfo() override { return mLoadGroupCI; };
nsISchedulingContext *SchedulingContext() override { return mSchedulingContext; };
void ConnectPushedStream(Http2Stream *consumer);
bool TryOnPush();
@ -68,7 +69,7 @@ private:
Http2Stream *mConsumerStream; // paired request stream that consumes from
// real http/2 one.. null until a match is made.
nsCOMPtr<nsILoadGroupConnectionInfo> mLoadGroupCI;
nsCOMPtr<nsISchedulingContext> mSchedulingContext;
nsAHttpTransaction *mAssociatedTransaction;

View File

@ -25,7 +25,7 @@
#include "nsHttp.h"
#include "nsHttpHandler.h"
#include "nsHttpConnection.h"
#include "nsILoadGroup.h"
#include "nsISchedulingContext.h"
#include "nsISSLSocketControl.h"
#include "nsISSLStatus.h"
#include "nsISSLStatusProvider.h"
@ -1047,10 +1047,10 @@ Http2Session::CleanupStream(Http2Stream *aStream, nsresult aResult,
Http2PushedStream *pushStream = static_cast<Http2PushedStream *>(aStream);
nsAutoCString hashKey;
pushStream->GetHashKey(hashKey);
nsILoadGroupConnectionInfo *loadGroupCI = aStream->LoadGroupConnectionInfo();
if (loadGroupCI) {
nsISchedulingContext *schedulingContext = aStream->SchedulingContext();
if (schedulingContext) {
SpdyPushCache *cache = nullptr;
loadGroupCI->GetSpdyPushCache(&cache);
schedulingContext->GetSpdyPushCache(&cache);
if (cache) {
Http2PushedStream *trash = cache->RemovePushedStreamHttp2(hashKey);
LOG3(("Http2Session::CleanupStream %p aStream=%p pushStream=%p trash=%p",
@ -1608,12 +1608,12 @@ Http2Session::RecvPushPromise(Http2Session *self)
LOG3(("Http2Session::RecvPushPromise %p lookup associated ID failed.\n", self));
self->GenerateRstStream(PROTOCOL_ERROR, promisedID);
} else {
nsILoadGroupConnectionInfo *loadGroupCI = associatedStream->LoadGroupConnectionInfo();
if (loadGroupCI) {
loadGroupCI->GetSpdyPushCache(&cache);
nsISchedulingContext *schedulingContext = associatedStream->SchedulingContext();
if (schedulingContext) {
schedulingContext->GetSpdyPushCache(&cache);
if (!cache) {
cache = new SpdyPushCache();
if (!cache || NS_FAILED(loadGroupCI->SetSpdyPushCache(cache))) {
if (!cache || NS_FAILED(schedulingContext->SetSpdyPushCache(cache))) {
delete cache;
cache = nullptr;
}
@ -1621,7 +1621,7 @@ Http2Session::RecvPushPromise(Http2Session *self)
}
if (!cache) {
// this is unexpected, but we can handle it just by refusing the push
LOG3(("Http2Session::RecvPushPromise Push Recevied without loadgroup cache\n"));
LOG3(("Http2Session::RecvPushPromise Push Recevied without push cache\n"));
self->GenerateRstStream(REFUSED_STREAM_ERROR, promisedID);
} else {
resetStream = false;

View File

@ -363,10 +363,10 @@ Http2Stream::ParseHttpRequestHeaders(const char *buf,
// check the push cache for GET
if (head->IsGet()) {
// from :scheme, :authority, :path
nsILoadGroupConnectionInfo *loadGroupCI = mTransaction->LoadGroupConnectionInfo();
nsISchedulingContext *schedulingContext = mTransaction->SchedulingContext();
SpdyPushCache *cache = nullptr;
if (loadGroupCI) {
loadGroupCI->GetSpdyPushCache(&cache);
if (schedulingContext) {
schedulingContext->GetSpdyPushCache(&cache);
}
Http2PushedStream *pushedStream = nullptr;
@ -393,8 +393,8 @@ Http2Stream::ParseHttpRequestHeaders(const char *buf,
}
LOG3(("Pushed Stream Lookup "
"session=%p key=%s loadgroupci=%p cache=%p hit=%p\n",
mSession, hashkey.get(), loadGroupCI, cache, pushedStream));
"session=%p key=%s schedulingcontext=%p cache=%p hit=%p\n",
mSession, hashkey.get(), schedulingContext, cache, pushedStream));
if (pushedStream) {
LOG3(("Pushed Stream Match located id=0x%X key=%s\n",

View File

@ -70,9 +70,9 @@ public:
bool HasRegisteredID() { return mStreamID != 0; }
nsAHttpTransaction *Transaction() { return mTransaction; }
virtual nsILoadGroupConnectionInfo *LoadGroupConnectionInfo()
virtual nsISchedulingContext *SchedulingContext()
{
return mTransaction ? mTransaction->LoadGroupConnectionInfo() : nullptr;
return mTransaction ? mTransaction->SchedulingContext() : nullptr;
}
void Close(nsresult reason);

View File

@ -40,6 +40,7 @@
#include "mozIThirdPartyUtil.h"
#include "nsStreamUtils.h"
#include "nsContentSecurityManager.h"
#include "nsILoadGroupChild.h"
#include <algorithm>
@ -99,6 +100,7 @@ HttpBaseChannel::HttpBaseChannel()
#endif
mSelfAddr.raw.family = PR_AF_UNSPEC;
mPeerAddr.raw.family = PR_AF_UNSPEC;
mSchedulingContextID.Clear();
}
HttpBaseChannel::~HttpBaseChannel()
@ -1541,6 +1543,21 @@ HttpBaseChannel::RedirectTo(nsIURI *newURI)
return NS_OK;
}
NS_IMETHODIMP
HttpBaseChannel::GetSchedulingContextID(nsID *aSCID)
{
NS_ENSURE_ARG_POINTER(aSCID);
*aSCID = mSchedulingContextID;
return NS_OK;
}
NS_IMETHODIMP
HttpBaseChannel::SetSchedulingContextID(const nsID aSCID)
{
mSchedulingContextID = aSCID;
return NS_OK;
}
//-----------------------------------------------------------------------------
// HttpBaseChannel::nsIHttpChannelInternal
//-----------------------------------------------------------------------------
@ -2726,6 +2743,35 @@ HttpBaseChannel::GetPerformance()
//------------------------------------------------------------------------------
bool
HttpBaseChannel::EnsureSchedulingContextID()
{
nsID nullID;
nullID.Clear();
if (!mSchedulingContextID.Equals(nullID)) {
// Already have a scheduling context ID, no need to do the rest of this work
return true;
}
// Find the loadgroup at the end of the chain in order
// to make sure all channels derived from the load group
// use the same connection scope.
nsCOMPtr<nsILoadGroupChild> childLoadGroup = do_QueryInterface(mLoadGroup);
if (!childLoadGroup) {
return false;
}
nsCOMPtr<nsILoadGroup> rootLoadGroup;
childLoadGroup->GetRootLoadGroup(getter_AddRefs(rootLoadGroup));
if (!rootLoadGroup) {
return false;
}
// Set the load group connection scope on the transaction
rootLoadGroup->GetSchedulingContextID(&mSchedulingContextID);
return true;
}
} // namespace net
} // namespace mozilla

View File

@ -156,6 +156,8 @@ public:
NS_IMETHOD GetResponseStatusText(nsACString& aValue) override;
NS_IMETHOD GetRequestSucceeded(bool *aValue) override;
NS_IMETHOD RedirectTo(nsIURI *newURI) override;
NS_IMETHOD GetSchedulingContextID(nsID *aSCID) override;
NS_IMETHOD SetSchedulingContextID(const nsID aSCID) override;
// nsIHttpChannelInternal
NS_IMETHOD GetDocumentURI(nsIURI **aDocumentURI) override;
@ -431,6 +433,9 @@ protected:
// The network interface id that's associated with this channel.
nsCString mNetworkInterfaceId;
nsID mSchedulingContextID;
bool EnsureSchedulingContextID();
};
// Share some code while working around C++'s absurd inability to handle casting

View File

@ -1693,6 +1693,11 @@ HttpChannelChild::ContinueAsyncOpen()
nsresult rv = mozilla::ipc::LoadInfoToLoadInfoArgs(mLoadInfo, &openArgs.loadInfo());
NS_ENSURE_SUCCESS(rv, rv);
EnsureSchedulingContextID();
char scid[NSID_LENGTH];
mSchedulingContextID.ToProvidedString(scid);
openArgs.schedulingContextID().AssignASCII(scid);
// The socket transport in the chrome process now holds a logical ref to us
// until OnStopRequest, or we do a redirect, or we hit an IPDL error.
AddIPDLReference();

View File

@ -120,7 +120,8 @@ HttpChannelParent::Init(const HttpChannelCreationArgs& aArgs)
a.thirdPartyFlags(), a.resumeAt(), a.startPos(),
a.entityID(), a.chooseApplicationCache(),
a.appCacheClientID(), a.allowSpdy(), a.allowAltSvc(), a.fds(),
a.loadInfo(), a.synthesizedResponseHead(), a.cacheKey());
a.loadInfo(), a.synthesizedResponseHead(), a.cacheKey(),
a.schedulingContextID());
}
case HttpChannelCreationArgs::THttpChannelConnectArgs:
{
@ -276,7 +277,8 @@ HttpChannelParent::DoAsyncOpen( const URIParams& aURI,
const OptionalFileDescriptorSet& aFds,
const OptionalLoadInfoArgs& aLoadInfoArgs,
const OptionalHttpResponseHead& aSynthesizedResponseHead,
const uint32_t& aCacheKey)
const uint32_t& aCacheKey,
const nsCString& aSchedulingContextID)
{
nsCOMPtr<nsIURI> uri = DeserializeURI(aURI);
if (!uri) {
@ -461,6 +463,10 @@ HttpChannelParent::DoAsyncOpen( const URIParams& aURI,
}
}
nsID schedulingContextID;
schedulingContextID.Parse(aSchedulingContextID.BeginReading());
mChannel->SetSchedulingContextID(schedulingContextID);
rv = mChannel->AsyncOpen(mParentListener, nullptr);
if (NS_FAILED(rv))
return SendFailedAsyncOpen(rv);

View File

@ -118,7 +118,8 @@ protected:
const OptionalFileDescriptorSet& aFds,
const OptionalLoadInfoArgs& aLoadInfoArgs,
const OptionalHttpResponseHead& aSynthesizedResponseHead,
const uint32_t& aCacheKey);
const uint32_t& aCacheKey,
const nsCString& aSchedulingContextID);
virtual bool RecvSetPriority(const uint16_t& priority) override;
virtual bool RecvSetClassOfService(const uint32_t& cos) override;

View File

@ -206,6 +206,18 @@ NullHttpChannel::RedirectTo(nsIURI *aNewURI)
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
NullHttpChannel::GetSchedulingContextID(nsID *_retval)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
NullHttpChannel::SetSchedulingContextID(const nsID scID)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
//-----------------------------------------------------------------------------
// NullHttpChannel::nsIChannel
//-----------------------------------------------------------------------------

View File

@ -40,7 +40,7 @@ SpdyPushedStream31::SpdyPushedStream31(SpdyPush31TransactionBuffer *aTransaction
LOG3(("SpdyPushedStream31 ctor this=%p id=0x%X\n", this, aID));
mStreamID = aID;
mBufferedPush->SetPushStream(this);
mLoadGroupCI = aAssociatedStream->LoadGroupConnectionInfo();
mSchedulingContext = aAssociatedStream->SchedulingContext();
mLastRead = TimeStamp::Now();
}

View File

@ -11,7 +11,7 @@
#include "mozilla/Attributes.h"
#include "mozilla/TimeStamp.h"
#include "nsHttpRequestHead.h"
#include "nsILoadGroup.h"
#include "nsISchedulingContext.h"
#include "nsString.h"
#include "PSpdyPush.h"
#include "SpdySession31.h"
@ -40,7 +40,7 @@ public:
nsresult ReadSegments(nsAHttpSegmentReader *, uint32_t, uint32_t *);
nsresult WriteSegments(nsAHttpSegmentWriter *, uint32_t, uint32_t *);
nsILoadGroupConnectionInfo *LoadGroupConnectionInfo() { return mLoadGroupCI; };
nsISchedulingContext *SchedulingContext() { return mSchedulingContext; };
void ConnectPushedStream(SpdyStream31 *consumer);
bool DeferCleanupOnSuccess() { return mDeferCleanupOnSuccess; }
@ -58,7 +58,7 @@ private:
SpdyStream31 *mConsumerStream; // paired request stream that consumes from
// real spdy one.. null until a match is made.
nsCOMPtr<nsILoadGroupConnectionInfo> mLoadGroupCI;
nsCOMPtr<nsISchedulingContext> mSchedulingContext;
SpdyPush31TransactionBuffer *mBufferedPush;
TimeStamp mLastRead;

View File

@ -18,7 +18,7 @@
#include "nsHttp.h"
#include "nsHttpHandler.h"
#include "nsHttpConnection.h"
#include "nsILoadGroup.h"
#include "nsISchedulingContext.h"
#include "nsISupportsPriority.h"
#include "prprf.h"
#include "prnetdb.h"
@ -1081,12 +1081,12 @@ SpdySession31::HandleSynStream(SpdySession31 *self)
self->GenerateRstStream(RST_INVALID_STREAM, streamID);
} else {
nsILoadGroupConnectionInfo *loadGroupCI = associatedStream->LoadGroupConnectionInfo();
if (loadGroupCI) {
loadGroupCI->GetSpdyPushCache(&cache);
nsISchedulingContext *schedulingContext = associatedStream->SchedulingContext();
if (schedulingContext) {
schedulingContext->GetSpdyPushCache(&cache);
if (!cache) {
cache = new SpdyPushCache();
if (!cache || NS_FAILED(loadGroupCI->SetSpdyPushCache(cache))) {
if (!cache || NS_FAILED(schedulingContext->SetSpdyPushCache(cache))) {
delete cache;
cache = nullptr;
}
@ -1094,7 +1094,7 @@ SpdySession31::HandleSynStream(SpdySession31 *self)
}
if (!cache) {
// this is unexpected, but we can handle it just be refusing the push
LOG3(("SpdySession31::HandleSynStream Push Recevied without loadgroup cache\n"));
LOG3(("SpdySession31::HandleSynStream Push Recevied without push cache\n"));
self->GenerateRstStream(RST_REFUSED_STREAM, streamID);
}
else {

View File

@ -316,10 +316,10 @@ SpdyStream31::ParseHttpRequestHeaders(const char *buf,
// check the push cache for GET
if (mTransaction->RequestHead()->IsGet()) {
// from :scheme, :host, :path
nsILoadGroupConnectionInfo *loadGroupCI = mTransaction->LoadGroupConnectionInfo();
nsISchedulingContext *schedulingContext = mTransaction->SchedulingContext();
SpdyPushCache *cache = nullptr;
if (loadGroupCI)
loadGroupCI->GetSpdyPushCache(&cache);
if (schedulingContext)
schedulingContext->GetSpdyPushCache(&cache);
SpdyPushedStream31 *pushedStream = nullptr;
// we remove the pushedstream from the push cache so that

View File

@ -42,9 +42,9 @@ public:
bool HasRegisteredID() { return mStreamID != 0; }
nsAHttpTransaction *Transaction() { return mTransaction; }
virtual nsILoadGroupConnectionInfo *LoadGroupConnectionInfo()
virtual nsISchedulingContext *SchedulingContext()
{
return mTransaction ? mTransaction->LoadGroupConnectionInfo() : nullptr;
return mTransaction ? mTransaction->SchedulingContext() : nullptr;
}
void Close(nsresult reason);

View File

@ -11,7 +11,7 @@
class nsIInterfaceRequestor;
class nsITransport;
class nsILoadGroupConnectionInfo;
class nsISchedulingContext;
namespace mozilla { namespace net {
@ -144,8 +144,8 @@ public:
// other types
virtual SpdyConnectTransaction *QuerySpdyConnectTransaction() { return nullptr; }
// return the load group connection information associated with the transaction
virtual nsILoadGroupConnectionInfo *LoadGroupConnectionInfo() { return nullptr; }
// return the scheduling context associated with the transaction
virtual nsISchedulingContext *SchedulingContext() { return nullptr; }
// return the connection information associated with the transaction
virtual nsHttpConnectionInfo *ConnectionInfo() = 0;

View File

@ -684,25 +684,30 @@ nsHttpChannel::ContinueHandleAsyncFallback(nsresult rv)
}
void
nsHttpChannel::SetupTransactionLoadGroupInfo()
nsHttpChannel::SetupTransactionSchedulingContext()
{
// Find the loadgroup at the end of the chain in order
// to make sure all channels derived from the load group
// use the same connection scope.
nsCOMPtr<nsILoadGroupChild> childLoadGroup = do_QueryInterface(mLoadGroup);
if (!childLoadGroup)
if (!EnsureSchedulingContextID()) {
return;
}
nsCOMPtr<nsILoadGroup> rootLoadGroup;
childLoadGroup->GetRootLoadGroup(getter_AddRefs(rootLoadGroup));
if (!rootLoadGroup)
nsISchedulingContextService *scsvc =
gHttpHandler->GetSchedulingContextService();
if (!scsvc) {
return;
}
// Set the load group connection scope on the transaction
nsCOMPtr<nsILoadGroupConnectionInfo> ci;
rootLoadGroup->GetConnectionInfo(getter_AddRefs(ci));
if (ci)
mTransaction->SetLoadGroupConnectionInfo(ci);
nsCOMPtr<nsISchedulingContext> sc;
char scid[NSID_LENGTH];
mSchedulingContextID.ToProvidedString(scid);
fprintf(stderr, "NWGH: nsHttpChannel %p getting scheduling context %s\n", this, scid);
nsresult rv = scsvc->GetSchedulingContext(mSchedulingContextID,
getter_AddRefs(sc));
if (NS_FAILED(rv)) {
return;
}
mTransaction->SetSchedulingContext(sc);
}
static bool
@ -919,7 +924,7 @@ nsHttpChannel::SetupTransaction()
}
mTransaction->SetClassOfService(mClassOfService);
SetupTransactionLoadGroupInfo();
SetupTransactionSchedulingContext();
rv = nsInputStreamPump::Create(getter_AddRefs(mTransactionPump),
responseStream);

View File

@ -248,7 +248,7 @@ private:
nsresult Connect();
void SpeculativeConnect();
nsresult SetupTransaction();
void SetupTransactionLoadGroupInfo();
void SetupTransactionSchedulingContext();
nsresult CallOnStartRequest();
nsresult ProcessResponse();
nsresult ContinueProcessResponse(nsresult);

View File

@ -29,6 +29,7 @@
#include "nsIDNSRecord.h"
#include "nsITransport.h"
#include "nsInterfaceRequestorAgg.h"
#include "nsISchedulingContext.h"
#include "nsISocketTransportService.h"
#include <algorithm>
#include "mozilla/ChaosMode.h"
@ -1781,20 +1782,20 @@ nsHttpConnectionMgr::TryDispatchTransaction(nsConnectionEntry *ent,
}
}
// If this is not a blocking transaction and the loadgroup for it is
// If this is not a blocking transaction and the scheduling context for it is
// currently processing one or more blocking transactions then we
// need to just leave it in the queue until those are complete unless it is
// explicitly marked as unblocked.
if (!(caps & NS_HTTP_LOAD_AS_BLOCKING)) {
if (!(caps & NS_HTTP_LOAD_UNBLOCKED)) {
nsILoadGroupConnectionInfo *loadGroupCI = trans->LoadGroupConnectionInfo();
if (loadGroupCI) {
nsISchedulingContext *schedulingContext = trans->SchedulingContext();
if (schedulingContext) {
uint32_t blockers = 0;
if (NS_SUCCEEDED(loadGroupCI->GetBlockingTransactionCount(&blockers)) &&
if (NS_SUCCEEDED(schedulingContext->GetBlockingTransactionCount(&blockers)) &&
blockers) {
// need to wait for blockers to clear
LOG((" blocked by load group: [lgci=%p trans=%p blockers=%d]\n",
loadGroupCI, trans, blockers));
LOG((" blocked by scheduling context: [sc=%p trans=%p blockers=%d]\n",
schedulingContext, trans, blockers));
return NS_ERROR_NOT_AVAILABLE;
}
}

View File

@ -326,6 +326,9 @@ nsHttpHandler::Init()
rv = InitConnectionMgr();
if (NS_FAILED(rv)) return rv;
mSchedulingContextService =
do_GetService("@mozilla.org/network/scheduling-context-service;1");
#ifdef ANDROID
mProductSub.AssignLiteral(MOZILLA_UAVERSION);
#else

View File

@ -24,6 +24,7 @@ class nsIPrefBranch;
class nsICancelable;
class nsICookieService;
class nsIIOService;
class nsISchedulingContextService;
class nsISiteSecurityService;
class nsIStreamConverterService;
class nsITimer;
@ -336,6 +337,11 @@ public:
void SetCacheSkippedUntil(TimeStamp arg) { mCacheSkippedUntil = arg; }
void ClearCacheSkippedUntil() { mCacheSkippedUntil = TimeStamp(); }
nsISchedulingContextService *GetSchedulingContextService()
{
return mSchedulingContextService.get();
}
private:
virtual ~nsHttpHandler();
@ -543,6 +549,8 @@ private:
// incorrect content lengths or malformed chunked encodings
FrameCheckLevel mEnforceH1Framing;
nsCOMPtr<nsISchedulingContextService> mSchedulingContextService;
private:
// For Rate Pacing Certain Network Events. Only assign this pointer on
// socket thread.

View File

@ -35,6 +35,7 @@
#include "nsIInputStream.h"
#include "nsITransport.h"
#include "nsIOService.h"
#include "nsISchedulingContext.h"
#include <algorithm>
#ifdef MOZ_WIDGET_GONK
@ -1848,10 +1849,10 @@ nsHttpTransaction::CancelPipeline(uint32_t reason)
void
nsHttpTransaction::SetLoadGroupConnectionInfo(nsILoadGroupConnectionInfo *aLoadGroupCI)
nsHttpTransaction::SetSchedulingContext(nsISchedulingContext *aSchedulingContext)
{
LOG(("nsHttpTransaction %p SetLoadGroupConnectionInfo %p\n", this, aLoadGroupCI));
mLoadGroupCI = aLoadGroupCI;
LOG(("nsHttpTransaction %p SetSchedulingContext %p\n", this, aSchedulingContext));
mSchedulingContext = aSchedulingContext;
}
// Called when the transaction marked for blocking is associated with a connection
@ -1866,32 +1867,32 @@ nsHttpTransaction::DispatchedAsBlocking()
LOG(("nsHttpTransaction %p dispatched as blocking\n", this));
if (!mLoadGroupCI)
if (!mSchedulingContext)
return;
LOG(("nsHttpTransaction adding blocking transaction %p from "
"loadgroup %p\n", this, mLoadGroupCI.get()));
"scheduling context %p\n", this, mSchedulingContext.get()));
mLoadGroupCI->AddBlockingTransaction();
mSchedulingContext->AddBlockingTransaction();
mDispatchedAsBlocking = true;
}
void
nsHttpTransaction::RemoveDispatchedAsBlocking()
{
if (!mLoadGroupCI || !mDispatchedAsBlocking)
if (!mSchedulingContext || !mDispatchedAsBlocking)
return;
uint32_t blockers = 0;
nsresult rv = mLoadGroupCI->RemoveBlockingTransaction(&blockers);
nsresult rv = mSchedulingContext->RemoveBlockingTransaction(&blockers);
LOG(("nsHttpTransaction removing blocking transaction %p from "
"loadgroup %p. %d blockers remain.\n", this,
mLoadGroupCI.get(), blockers));
"scheduling context %p. %d blockers remain.\n", this,
mSchedulingContext.get(), blockers));
if (NS_SUCCEEDED(rv) && !blockers) {
LOG(("nsHttpTransaction %p triggering release of blocked channels "
" with loadgroupci=%p\n", this, mLoadGroupCI.get()));
" with scheduling context=%p\n", this, mSchedulingContext.get()));
gHttpHandler->ConnMgr()->ProcessPendingQ();
}
@ -1902,9 +1903,9 @@ void
nsHttpTransaction::ReleaseBlockingTransaction()
{
RemoveDispatchedAsBlocking();
LOG(("nsHttpTransaction %p loadgroupci set to null "
"in ReleaseBlockingTransaction() - was %p\n", this, mLoadGroupCI.get()));
mLoadGroupCI = nullptr;
LOG(("nsHttpTransaction %p scheduling context set to null "
"in ReleaseBlockingTransaction() - was %p\n", this, mSchedulingContext.get()));
mSchedulingContext = nullptr;
}
void

View File

@ -12,7 +12,6 @@
#include "EventTokenBucket.h"
#include "nsCOMPtr.h"
#include "nsThreadUtils.h"
#include "nsILoadGroup.h"
#include "nsIInterfaceRequestor.h"
#include "TimingStruct.h"
#include "Http2Push.h"
@ -29,6 +28,7 @@ class nsIHttpActivityObserver;
class nsIEventTarget;
class nsIInputStream;
class nsIOutputStream;
class nsISchedulingContext;
namespace mozilla { namespace net {
@ -124,9 +124,9 @@ public:
const TimeStamp GetPendingTime() { return mPendingTime; }
bool UsesPipelining() const { return mCaps & NS_HTTP_ALLOW_PIPELINING; }
// overload of nsAHttpTransaction::LoadGroupConnectionInfo()
nsILoadGroupConnectionInfo *LoadGroupConnectionInfo() override { return mLoadGroupCI.get(); }
void SetLoadGroupConnectionInfo(nsILoadGroupConnectionInfo *aLoadGroupCI);
// overload of nsAHttpTransaction::SchedulingContext()
nsISchedulingContext *SchedulingContext() override { return mSchedulingContext.get(); }
void SetSchedulingContext(nsISchedulingContext *aSchedulingContext);
void DispatchedAsBlocking();
void RemoveDispatchedAsBlocking();
@ -218,7 +218,7 @@ private:
nsCOMPtr<nsISupports> mSecurityInfo;
nsCOMPtr<nsIAsyncInputStream> mPipeIn;
nsCOMPtr<nsIAsyncOutputStream> mPipeOut;
nsCOMPtr<nsILoadGroupConnectionInfo> mLoadGroupCI;
nsCOMPtr<nsISchedulingContext> mSchedulingContext;
nsCOMPtr<nsISupports> mChannel;
nsCOMPtr<nsIHttpActivityObserver> mActivityDistributor;

View File

@ -14,7 +14,7 @@ interface nsIHttpHeaderVisitor;
* the inspection of the resulting HTTP response status and headers when they
* become available.
*/
[builtinclass, scriptable, uuid(1656b777-3045-4b74-b6c3-a2677c0ae082)]
[builtinclass, scriptable, uuid(fdc70825-8ae1-4f81-bd9e-f1fd3f6307ad)]
interface nsIHttpChannel : nsIChannel
{
/**************************************************************************
@ -321,4 +321,9 @@ interface nsIHttpChannel : nsIChannel
* has been opened.
*/
void redirectTo(in nsIURI aNewURI);
/**
* Identifies the scheduling context for this load.
*/
[noscript] attribute nsID schedulingContextID;
};

View File

@ -846,3 +846,16 @@ nsViewSourceChannel::RedirectTo(nsIURI *uri)
mHttpChannel->RedirectTo(uri);
}
NS_IMETHODIMP
nsViewSourceChannel::GetSchedulingContextID(nsID *_retval)
{
return !mHttpChannel ? NS_ERROR_NULL_POINTER :
mHttpChannel->GetSchedulingContextID(_retval);
}
NS_IMETHODIMP
nsViewSourceChannel::SetSchedulingContextID(const nsID scid)
{
return !mHttpChannel ? NS_ERROR_NULL_POINTER :
mHttpChannel->SetSchedulingContextID(scid);
}

View File

@ -781,8 +781,9 @@ var tests = [ test_http2_post_big
, test_http2_patch
, test_http2_pushapi_1
, test_http2_continuations
// Add new tests above here - best to add new tests before h1
// streams get too involved
// These next two must always come in this order
// best to add new tests before h1 streams get too involved
, test_http2_h11required_stream
, test_http2_h11required_session
, test_http2_retry_rst

View File

@ -8,6 +8,16 @@
#include "prprf.h"
#include "nsMemory.h"
void nsID::Clear()
{
m0 = 0;
m1 = 0;
m2 = 0;
for (int i = 0; i < 8; ++i) {
m3[i] = 0;
}
}
/**
* Multiplies the_int_var with 16 (0x10) and adds the value of the
* hexadecimal digit the_char. If it fails it returns false from

View File

@ -35,6 +35,11 @@ struct nsID
*/
//@{
/**
* Ensures everything is zeroed out.
*/
void Clear();
/**
* Equivalency method. Compares this nsID with another.
* @return <b>true</b> if they are the same, <b>false</b> if not.