mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-08 02:14:43 +00:00
Bug 1127618 - make push caches work in e10s. r=mcmanus r=froydnj IGNORE IDL
--HG-- extra : rebase_source : 24dd37c6eaec83a1776d77632b97106e8abb8015
This commit is contained in:
parent
d61d6f4984
commit
16407ea724
203
netwerk/base/SchedulingContextService.cpp
Normal file
203
netwerk/base/SchedulingContextService.cpp
Normal 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
|
46
netwerk/base/SchedulingContextService.h
Normal file
46
netwerk/base/SchedulingContextService.h
Normal 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
|
@ -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',
|
||||
|
@ -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;
|
||||
};
|
||||
|
90
netwerk/base/nsISchedulingContext.idl
Normal file
90
netwerk/base/nsISchedulingContext.idl
Normal 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);
|
||||
};
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
*/
|
||||
|
@ -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 }
|
||||
};
|
||||
|
||||
|
@ -92,6 +92,7 @@ struct HttpChannelOpenArgs
|
||||
OptionalLoadInfoArgs loadInfo;
|
||||
OptionalHttpResponseHead synthesizedResponseHead;
|
||||
uint32_t cacheKey;
|
||||
nsCString schedulingContextID;
|
||||
};
|
||||
|
||||
struct HttpChannelConnectArgs
|
||||
|
@ -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,
|
||||
|
@ -23,7 +23,6 @@ public:
|
||||
virtual ~NeckoChild();
|
||||
|
||||
static void InitNeckoChild();
|
||||
static void DestroyNeckoChild();
|
||||
|
||||
protected:
|
||||
virtual PHttpChannelChild*
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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.
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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",
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
@ -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();
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
//-----------------------------------------------------------------------------
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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 {
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -248,7 +248,7 @@ private:
|
||||
nsresult Connect();
|
||||
void SpeculativeConnect();
|
||||
nsresult SetupTransaction();
|
||||
void SetupTransactionLoadGroupInfo();
|
||||
void SetupTransactionSchedulingContext();
|
||||
nsresult CallOnStartRequest();
|
||||
nsresult ProcessResponse();
|
||||
nsresult ContinueProcessResponse(nsresult);
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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.
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
};
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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.
|
||||
|
Loading…
Reference in New Issue
Block a user