Bug 1758524 (WIP) - Implement http priority flag r=necko-reviewers,dragana

Differential Revision: https://phabricator.services.mozilla.com/D142694
This commit is contained in:
edguloien 2022-04-28 15:40:33 +00:00
Родитель 8247453c26
Коммит 7172c05d39
38 изменённых файлов: 331 добавлений и 115 удалений

Просмотреть файл

@ -27,6 +27,8 @@ using struct mozilla::void_t from "mozilla/ipc/IPCCore.h";
using struct mozilla::dom::LoadingSessionHistoryInfo using struct mozilla::dom::LoadingSessionHistoryInfo
from "mozilla/dom/SessionHistoryEntry.h"; from "mozilla/dom/SessionHistoryEntry.h";
using mozilla::net::ClassOfServiceStruct from "nsIClassOfService.h";
using hal::ScreenOrientation from "mozilla/HalIPCUtils.h"; using hal::ScreenOrientation from "mozilla/HalIPCUtils.h";
using LayoutDeviceIntRect from "Units.h"; using LayoutDeviceIntRect from "Units.h";
using DesktopIntRect from "Units.h"; using DesktopIntRect from "Units.h";
@ -334,7 +336,7 @@ struct TimedChannelInfo
struct ReplacementChannelConfigInit struct ReplacementChannelConfigInit
{ {
uint32_t redirectFlags; uint32_t redirectFlags;
uint32_t classOfService; ClassOfServiceStruct classOfService;
bool? privateBrowsing; bool? privateBrowsing;
nsCString? method; nsCString? method;
nsIReferrerInfo referrerInfo; nsIReferrerInfo referrerInfo;

Просмотреть файл

@ -14,13 +14,21 @@
* information in different ways. * information in different ways.
*/ */
// convenience class for passing around the class of service
%{C++
#include "../../../netwerk/protocol/http/ClassOfService.h"
%}
native ClassOfServiceStruct(mozilla::net::ClassOfServiceStruct);
[scriptable, uuid(1ccb58ec-5e07-4cf9-a30d-ac5490d23b41)] [scriptable, uuid(1ccb58ec-5e07-4cf9-a30d-ac5490d23b41)]
interface nsIClassOfService : nsISupports interface nsIClassOfService : nsISupports
{ {
attribute unsigned long classFlags; attribute unsigned long classFlags;
attribute bool incremental;
void clearClassFlags(in unsigned long flags); void clearClassFlags(in unsigned long flags);
void addClassFlags(in unsigned long flags); void addClassFlags(in unsigned long flags);
void setClassOfService(in ClassOfServiceStruct s);
// All these flags have a (de)prioritization effect. // All these flags have a (de)prioritization effect.
@ -29,7 +37,7 @@ interface nsIClassOfService : nsISupports
// belonging to a single top level window (RequestContextService). Requests // belonging to a single top level window (RequestContextService). Requests
// marked with the Leader flag are blocking (preventing from being sent to the // marked with the Leader flag are blocking (preventing from being sent to the
// server) all other resource loads except those marked with the Unblocked // server) all other resource loads except those marked with the Unblocked
// flag. Other classes run in parallel - neither being blocked nor blocking. // flag. Other classes run in parallel - neither being blocked no ;r blocking.
// The Leader flag is used only for <head> blocking resources (sync and // The Leader flag is used only for <head> blocking resources (sync and
// defer javascript resources and stylesheets.) Purpose is to deliver these // defer javascript resources and stylesheets.) Purpose is to deliver these
// first-paint and domcontentloaded blocking resources as soon as possbile. // first-paint and domcontentloaded blocking resources as soon as possbile.

Просмотреть файл

@ -21,6 +21,7 @@ include "mozilla/dom/ReferrerInfoUtils.h";
include "mozilla/ipc/URIUtils.h"; include "mozilla/ipc/URIUtils.h";
include "mozilla/net/CacheInfoIPCTypes.h"; include "mozilla/net/CacheInfoIPCTypes.h";
include "mozilla/AntiTrackingIPCUtils.h"; include "mozilla/AntiTrackingIPCUtils.h";
include "nsIClassOfService.h";
using mozilla::OriginAttributes from "mozilla/ipc/BackgroundUtils.h"; using mozilla::OriginAttributes from "mozilla/ipc/BackgroundUtils.h";
using RequestHeaderTuples from "mozilla/net/PHttpChannelParams.h"; using RequestHeaderTuples from "mozilla/net/PHttpChannelParams.h";
@ -289,7 +290,7 @@ struct HttpChannelOpenArgs
IPCStream? uploadStream; IPCStream? uploadStream;
bool uploadStreamHasHeaders; bool uploadStreamHasHeaders;
int16_t priority; int16_t priority;
uint32_t classOfService; ClassOfServiceStruct classOfService;
uint8_t redirectionLimit; uint8_t redirectionLimit;
bool allowSTS; bool allowSTS;
uint32_t thirdPartyFlags; uint32_t thirdPartyFlags;

Просмотреть файл

@ -0,0 +1,69 @@
#ifndef __ClassOfService_h__
#define __ClassOfService_h__
#include "ipc/IPCMessageUtils.h"
// namespace IPC {}
namespace mozilla {
namespace net {
class ClassOfServiceStruct {
public:
ClassOfServiceStruct() : mClassFlags(0), mIncremental(false) {}
ClassOfServiceStruct(unsigned long flags, bool incremental)
: mClassFlags(flags), mIncremental(incremental) {}
// class flags (priority)
unsigned long Flags() const { return mClassFlags; }
void SetFlags(unsigned long flags) { mClassFlags = flags; }
// incremental flags
bool Incremental() const { return mIncremental; }
void SetIncremental(bool incremental) { mIncremental = incremental; }
private:
unsigned long mClassFlags;
bool mIncremental;
friend IPC::ParamTraits<mozilla::net::ClassOfServiceStruct>;
friend bool operator==(const ClassOfServiceStruct& lhs,
const ClassOfServiceStruct& rhs);
friend bool operator!=(const ClassOfServiceStruct& lhs,
const ClassOfServiceStruct& rhs);
};
inline bool operator==(const ClassOfServiceStruct& lhs,
const ClassOfServiceStruct& rhs) {
return lhs.mClassFlags == rhs.mClassFlags &&
lhs.mIncremental == rhs.mIncremental;
}
inline bool operator!=(const ClassOfServiceStruct& lhs,
const ClassOfServiceStruct& rhs) {
return !(lhs == rhs);
}
} // namespace net
} // namespace mozilla
namespace IPC {
template <>
struct ParamTraits<mozilla::net::ClassOfServiceStruct> {
typedef mozilla::net::ClassOfServiceStruct paramType;
static void Write(MessageWriter* aWriter, const paramType& aParam) {
WriteParam(aWriter, aParam.mClassFlags);
WriteParam(aWriter, aParam.mIncremental);
}
static bool Read(MessageReader* aReader, paramType* aResult) {
if (!ReadParam(aReader, &aResult->mClassFlags) ||
!ReadParam(aReader, &aResult->mIncremental))
return false;
return true;
}
};
} // namespace IPC
#endif

Просмотреть файл

@ -1250,7 +1250,7 @@ void Http2Stream::SetPriorityDependency(uint32_t newPriority,
static uint32_t GetPriorityDependencyFromTransaction(nsHttpTransaction* trans) { static uint32_t GetPriorityDependencyFromTransaction(nsHttpTransaction* trans) {
MOZ_ASSERT(trans); MOZ_ASSERT(trans);
uint32_t classFlags = trans->ClassOfService(); uint32_t classFlags = trans->ClassOfService().Flags();
if (classFlags & nsIClassOfService::UrgentStart) { if (classFlags & nsIClassOfService::UrgentStart) {
return Http2Session::kUrgentStartGroupID; return Http2Session::kUrgentStartGroupID;

Просмотреть файл

@ -750,7 +750,7 @@ bool Http3Session::AddStream(nsAHttpTransaction* aHttpTransaction,
// reset the read timers to wash away any idle time // reset the read timers to wash away any idle time
mLastWriteTime = PR_IntervalNow(); mLastWriteTime = PR_IntervalNow();
uint32_t cos = 0; ClassOfServiceStruct cos;
if (trans) { if (trans) {
cos = trans->ClassOfService(); cos = trans->ClassOfService();
} }

Просмотреть файл

@ -24,7 +24,8 @@ namespace mozilla {
namespace net { namespace net {
Http3Stream::Http3Stream(nsAHttpTransaction* httpTransaction, Http3Stream::Http3Stream(nsAHttpTransaction* httpTransaction,
Http3Session* session, uint32_t aCos, uint64_t bcId) Http3Session* session, const ClassOfServiceStruct& cos,
uint64_t bcId)
: mSession(session), : mSession(session),
mTransaction(httpTransaction), mTransaction(httpTransaction),
mCurrentTopBrowsingContextId(bcId) { mCurrentTopBrowsingContextId(bcId) {
@ -36,7 +37,8 @@ Http3Stream::Http3Stream(nsAHttpTransaction* httpTransaction,
mTransactionTabId = trans->TopBrowsingContextId(); mTransactionTabId = trans->TopBrowsingContextId();
} }
SetPriority(aCos); SetPriority(cos.Flags());
SetIncremental(cos.Incremental());
} }
void Http3Stream::Close(nsresult aResult) { void Http3Stream::Close(nsresult aResult) {
@ -96,6 +98,10 @@ void Http3Stream::SetPriority(uint32_t aCos) {
} }
} }
void Http3Stream::SetIncremental(bool incremental) {
mPriorityIncremental = incremental;
}
nsresult Http3Stream::TryActivating() { nsresult Http3Stream::TryActivating() {
MOZ_ASSERT(OnSocketThread(), "not on socket thread"); MOZ_ASSERT(OnSocketThread(), "not on socket thread");
LOG(("Http3Stream::TryActivating [this=%p]", this)); LOG(("Http3Stream::TryActivating [this=%p]", this));

Просмотреть файл

@ -9,6 +9,7 @@
#include "nsAHttpTransaction.h" #include "nsAHttpTransaction.h"
#include "ARefBase.h" #include "ARefBase.h"
#include "mozilla/WeakPtr.h" #include "mozilla/WeakPtr.h"
#include "nsIClassOfService.h"
namespace mozilla { namespace mozilla {
namespace net { namespace net {
@ -25,7 +26,8 @@ class Http3Stream final : public nsAHttpSegmentReader,
// for RefPtr // for RefPtr
NS_INLINE_DECL_REFCOUNTING(Http3Stream, override) NS_INLINE_DECL_REFCOUNTING(Http3Stream, override)
Http3Stream(nsAHttpTransaction*, Http3Session*, uint32_t, uint64_t); Http3Stream(nsAHttpTransaction*, Http3Session*, const ClassOfServiceStruct&,
uint64_t);
bool HasStreamId() const { return mStreamId != UINT64_MAX; } bool HasStreamId() const { return mStreamId != UINT64_MAX; }
uint64_t StreamId() const { return mStreamId; } uint64_t StreamId() const { return mStreamId; }
@ -70,6 +72,7 @@ class Http3Stream final : public nsAHttpSegmentReader,
nsresult StartRequest(); nsresult StartRequest();
void SetPriority(uint32_t aCos); void SetPriority(uint32_t aCos);
void SetIncremental(bool incremental);
/** /**
* SendStreamState: * SendStreamState:

Просмотреть файл

@ -197,7 +197,7 @@ HttpBaseChannel::HttpBaseChannel()
mFlashPluginState(nsIHttpChannel::FlashPluginUnknown), mFlashPluginState(nsIHttpChannel::FlashPluginUnknown),
mLoadFlags(LOAD_NORMAL), mLoadFlags(LOAD_NORMAL),
mCaps(0), mCaps(0),
mClassOfService(0), mClassOfService(0, false),
mTlsFlags(0), mTlsFlags(0),
mSuspendCount(0), mSuspendCount(0),
mInitialRwin(0), mInitialRwin(0),
@ -4191,7 +4191,7 @@ HttpBaseChannel::CloneReplacementChannelConfig(bool aPreserveMethod,
ReplacementReason aReason) { ReplacementReason aReason) {
nsCOMPtr<nsIClassOfService> cos(do_QueryInterface(newChannel)); nsCOMPtr<nsIClassOfService> cos(do_QueryInterface(newChannel));
if (cos) { if (cos) {
cos->SetClassFlags(config.classOfService); cos->SetClassOfService(config.classOfService);
} }
// Try to preserve the privacy bit if it has been overridden // Try to preserve the privacy bit if it has been overridden

Просмотреть файл

@ -352,7 +352,12 @@ class HttpBaseChannel : public nsHashPropertyBag,
// nsIClassOfService // nsIClassOfService
NS_IMETHOD GetClassFlags(uint32_t* outFlags) override { NS_IMETHOD GetClassFlags(uint32_t* outFlags) override {
*outFlags = mClassOfService; *outFlags = mClassOfService.Flags();
return NS_OK;
}
NS_IMETHOD GetIncremental(bool* outIncremental) override {
*outIncremental = mClassOfService.Incremental();
return NS_OK; return NS_OK;
} }
@ -499,7 +504,7 @@ class HttpBaseChannel : public nsHashPropertyBag,
const dom::ReplacementChannelConfigInit& aInit); const dom::ReplacementChannelConfigInit& aInit);
uint32_t redirectFlags = 0; uint32_t redirectFlags = 0;
uint32_t classOfService = 0; ClassOfServiceStruct classOfService = {0, false};
Maybe<bool> privateBrowsing = Nothing(); Maybe<bool> privateBrowsing = Nothing();
Maybe<nsCString> method; Maybe<nsCString> method;
nsCOMPtr<nsIReferrerInfo> referrerInfo; nsCOMPtr<nsIReferrerInfo> referrerInfo;
@ -770,7 +775,8 @@ class HttpBaseChannel : public nsHashPropertyBag,
uint32_t mLoadFlags; uint32_t mLoadFlags;
uint32_t mCaps; uint32_t mCaps;
uint32_t mClassOfService;
ClassOfServiceStruct mClassOfService;
// clang-format off // clang-format off
MOZ_ATOMIC_BITFIELDS(mAtomicBitfields1, 32, ( MOZ_ATOMIC_BITFIELDS(mAtomicBitfields1, 32, (

Просмотреть файл

@ -2564,7 +2564,6 @@ HttpChannelChild::ResumeAt(uint64_t startPos, const nsACString& entityID) {
NS_IMETHODIMP NS_IMETHODIMP
HttpChannelChild::SetPriority(int32_t aPriority) { HttpChannelChild::SetPriority(int32_t aPriority) {
LOG(("HttpChannelChild::SetPriority %p p=%d", this, aPriority)); LOG(("HttpChannelChild::SetPriority %p p=%d", this, aPriority));
int16_t newValue = clamped<int32_t>(aPriority, INT16_MIN, INT16_MAX); int16_t newValue = clamped<int32_t>(aPriority, INT16_MIN, INT16_MAX);
if (mPriority == newValue) return NS_OK; if (mPriority == newValue) return NS_OK;
mPriority = newValue; mPriority = newValue;
@ -2577,13 +2576,14 @@ HttpChannelChild::SetPriority(int32_t aPriority) {
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
NS_IMETHODIMP NS_IMETHODIMP
HttpChannelChild::SetClassFlags(uint32_t inFlags) { HttpChannelChild::SetClassFlags(uint32_t inFlags) {
if (mClassOfService == inFlags) { if (mClassOfService.Flags() == inFlags) {
return NS_OK; return NS_OK;
} }
mClassOfService = inFlags; mClassOfService.SetFlags(inFlags);
LOG(("HttpChannelChild %p ClassOfService=%u", this, mClassOfService)); LOG(("HttpChannelChild %p ClassOfService flags=%lu inc=%d", this,
mClassOfService.Flags(), mClassOfService.Incremental()));
if (RemoteChannelExists()) { if (RemoteChannelExists()) {
SendSetClassOfService(mClassOfService); SendSetClassOfService(mClassOfService);
@ -2593,9 +2593,10 @@ HttpChannelChild::SetClassFlags(uint32_t inFlags) {
NS_IMETHODIMP NS_IMETHODIMP
HttpChannelChild::AddClassFlags(uint32_t inFlags) { HttpChannelChild::AddClassFlags(uint32_t inFlags) {
mClassOfService |= inFlags; mClassOfService.SetFlags(inFlags | mClassOfService.Flags());
LOG(("HttpChannelChild %p ClassOfService=%u", this, mClassOfService)); LOG(("HttpChannelChild %p ClassOfService flags=%lu inc=%d", this,
mClassOfService.Flags(), mClassOfService.Incremental()));
if (RemoteChannelExists()) { if (RemoteChannelExists()) {
SendSetClassOfService(mClassOfService); SendSetClassOfService(mClassOfService);
@ -2605,9 +2606,10 @@ HttpChannelChild::AddClassFlags(uint32_t inFlags) {
NS_IMETHODIMP NS_IMETHODIMP
HttpChannelChild::ClearClassFlags(uint32_t inFlags) { HttpChannelChild::ClearClassFlags(uint32_t inFlags) {
mClassOfService &= ~inFlags; mClassOfService.SetFlags(~inFlags & mClassOfService.Flags());
LOG(("HttpChannelChild %p ClassOfService=%u", this, mClassOfService)); LOG(("HttpChannelChild %p ClassOfService=%lu", this,
mClassOfService.Flags()));
if (RemoteChannelExists()) { if (RemoteChannelExists()) {
SendSetClassOfService(mClassOfService); SendSetClassOfService(mClassOfService);
@ -2615,6 +2617,27 @@ HttpChannelChild::ClearClassFlags(uint32_t inFlags) {
return NS_OK; return NS_OK;
} }
NS_IMETHODIMP
HttpChannelChild::SetClassOfService(ClassOfServiceStruct inCos) {
mClassOfService = inCos;
LOG(("HttpChannelChild %p ClassOfService flags=%lu inc=%d", this,
mClassOfService.Flags(), mClassOfService.Incremental()));
if (RemoteChannelExists()) {
SendSetClassOfService(mClassOfService);
}
return NS_OK;
}
NS_IMETHODIMP
HttpChannelChild::SetIncremental(bool inIncremental) {
mClassOfService.SetIncremental(inIncremental);
LOG(("HttpChannelChild %p ClassOfService flags=%lu inc=%d", this,
mClassOfService.Flags(), mClassOfService.Incremental()));
if (RemoteChannelExists()) {
SendSetClassOfService(mClassOfService);
}
return NS_OK;
}
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// HttpChannelChild::nsIProxiedChannel // HttpChannelChild::nsIProxiedChannel
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------

Просмотреть файл

@ -104,6 +104,8 @@ class HttpChannelChild final : public PHttpChannelChild,
NS_IMETHOD SetClassFlags(uint32_t inFlags) override; NS_IMETHOD SetClassFlags(uint32_t inFlags) override;
NS_IMETHOD AddClassFlags(uint32_t inFlags) override; NS_IMETHOD AddClassFlags(uint32_t inFlags) override;
NS_IMETHOD ClearClassFlags(uint32_t inFlags) override; NS_IMETHOD ClearClassFlags(uint32_t inFlags) override;
NS_IMETHOD SetClassOfService(ClassOfServiceStruct inCos) override;
NS_IMETHOD SetIncremental(bool inIncremental) override;
// nsIResumableChannel // nsIResumableChannel
NS_IMETHOD ResumeAt(uint64_t startPos, const nsACString& entityID) override; NS_IMETHOD ResumeAt(uint64_t startPos, const nsACString& entityID) override;

Просмотреть файл

@ -361,7 +361,7 @@ bool HttpChannelParent::DoAsyncOpen(
const Maybe<URIParams>& aTopWindowURI, const uint32_t& aLoadFlags, const Maybe<URIParams>& aTopWindowURI, const uint32_t& aLoadFlags,
const RequestHeaderTuples& requestHeaders, const nsCString& requestMethod, const RequestHeaderTuples& requestHeaders, const nsCString& requestMethod,
const Maybe<IPCStream>& uploadStream, const bool& uploadStreamHasHeaders, const Maybe<IPCStream>& uploadStream, const bool& uploadStreamHasHeaders,
const int16_t& priority, const uint32_t& classOfService, const int16_t& priority, const ClassOfServiceStruct& classOfService,
const uint8_t& redirectionLimit, const bool& allowSTS, const uint8_t& redirectionLimit, const bool& allowSTS,
const uint32_t& thirdPartyFlags, const bool& doResumeAt, const uint32_t& thirdPartyFlags, const bool& doResumeAt,
const uint64_t& startPos, const nsCString& entityID, const bool& allowSpdy, const uint64_t& startPos, const nsCString& entityID, const bool& allowSpdy,
@ -536,8 +536,8 @@ bool HttpChannelParent::DoAsyncOpen(
if (priority != nsISupportsPriority::PRIORITY_NORMAL) { if (priority != nsISupportsPriority::PRIORITY_NORMAL) {
httpChannel->SetPriority(priority); httpChannel->SetPriority(priority);
} }
if (classOfService) { if (classOfService.Flags() || classOfService.Incremental()) {
httpChannel->SetClassFlags(classOfService); httpChannel->SetClassOfService(classOfService);
} }
httpChannel->SetRedirectionLimit(redirectionLimit); httpChannel->SetRedirectionLimit(redirectionLimit);
httpChannel->SetAllowSTS(allowSTS); httpChannel->SetAllowSTS(allowSTS);
@ -692,9 +692,9 @@ mozilla::ipc::IPCResult HttpChannelParent::RecvSetPriority(
} }
mozilla::ipc::IPCResult HttpChannelParent::RecvSetClassOfService( mozilla::ipc::IPCResult HttpChannelParent::RecvSetClassOfService(
const uint32_t& cos) { const ClassOfServiceStruct& cos) {
if (mChannel) { if (mChannel) {
mChannel->SetClassFlags(cos); mChannel->SetClassOfService(cos);
} }
return IPC_OK(); return IPC_OK();
} }

Просмотреть файл

@ -138,7 +138,7 @@ class HttpChannelParent final : public nsIInterfaceRequestor,
const Maybe<URIParams>& topWindowUri, const uint32_t& loadFlags, const Maybe<URIParams>& topWindowUri, const uint32_t& loadFlags,
const RequestHeaderTuples& requestHeaders, const nsCString& requestMethod, const RequestHeaderTuples& requestHeaders, const nsCString& requestMethod,
const Maybe<IPCStream>& uploadStream, const bool& uploadStreamHasHeaders, const Maybe<IPCStream>& uploadStream, const bool& uploadStreamHasHeaders,
const int16_t& priority, const uint32_t& classOfService, const int16_t& priority, const ClassOfServiceStruct& classOfService,
const uint8_t& redirectionLimit, const bool& allowSTS, const uint8_t& redirectionLimit, const bool& allowSTS,
const uint32_t& thirdPartyFlags, const bool& doResumeAt, const uint32_t& thirdPartyFlags, const bool& doResumeAt,
const uint64_t& startPos, const nsCString& entityID, const uint64_t& startPos, const nsCString& entityID,
@ -168,7 +168,7 @@ class HttpChannelParent final : public nsIInterfaceRequestor,
virtual mozilla::ipc::IPCResult RecvSetPriority( virtual mozilla::ipc::IPCResult RecvSetPriority(
const int16_t& priority) override; const int16_t& priority) override;
virtual mozilla::ipc::IPCResult RecvSetClassOfService( virtual mozilla::ipc::IPCResult RecvSetClassOfService(
const uint32_t& cos) override; const ClassOfServiceStruct& cos) override;
virtual mozilla::ipc::IPCResult RecvSuspend() override; virtual mozilla::ipc::IPCResult RecvSuspend() override;
virtual mozilla::ipc::IPCResult RecvResume() override; virtual mozilla::ipc::IPCResult RecvResume() override;
virtual mozilla::ipc::IPCResult RecvCancel( virtual mozilla::ipc::IPCResult RecvCancel(

Просмотреть файл

@ -89,7 +89,8 @@ mozilla::ipc::IPCResult HttpConnectionMgrChild::RecvRescheduleTransaction(
mozilla::ipc::IPCResult mozilla::ipc::IPCResult
HttpConnectionMgrChild::RecvUpdateClassOfServiceOnTransaction( HttpConnectionMgrChild::RecvUpdateClassOfServiceOnTransaction(
PHttpTransactionChild* aTrans, const uint32_t& aClassOfService) { PHttpTransactionChild* aTrans,
const ClassOfServiceStruct& aClassOfService) {
mConnMgr->UpdateClassOfServiceOnTransaction(ToRealHttpTransaction(aTrans), mConnMgr->UpdateClassOfServiceOnTransaction(ToRealHttpTransaction(aTrans),
aClassOfService); aClassOfService);
return IPC_OK(); return IPC_OK();

Просмотреть файл

@ -33,7 +33,8 @@ class HttpConnectionMgrChild final : public PHttpConnectionMgrChild {
mozilla::ipc::IPCResult RecvRescheduleTransaction( mozilla::ipc::IPCResult RecvRescheduleTransaction(
PHttpTransactionChild* aTrans, const int32_t& aPriority); PHttpTransactionChild* aTrans, const int32_t& aPriority);
mozilla::ipc::IPCResult RecvUpdateClassOfServiceOnTransaction( mozilla::ipc::IPCResult RecvUpdateClassOfServiceOnTransaction(
PHttpTransactionChild* aTrans, const uint32_t& aClassOfService); PHttpTransactionChild* aTrans,
const ClassOfServiceStruct& aClassOfService);
mozilla::ipc::IPCResult RecvCancelTransaction(PHttpTransactionChild* aTrans, mozilla::ipc::IPCResult RecvCancelTransaction(PHttpTransactionChild* aTrans,
const nsresult& aReason); const nsresult& aReason);
mozilla::ipc::IPCResult RecvSpeculativeConnect( mozilla::ipc::IPCResult RecvSpeculativeConnect(

Просмотреть файл

@ -183,7 +183,7 @@ nsresult HttpConnectionMgrParent::RescheduleTransaction(
} }
void HttpConnectionMgrParent::UpdateClassOfServiceOnTransaction( void HttpConnectionMgrParent::UpdateClassOfServiceOnTransaction(
HttpTransactionShell* aTrans, uint32_t aClassOfService) { HttpTransactionShell* aTrans, const ClassOfServiceStruct& aClassOfService) {
MOZ_ASSERT(gIOService->SocketProcessReady()); MOZ_ASSERT(gIOService->SocketProcessReady());
if (!CanSend()) { if (!CanSend()) {

Просмотреть файл

@ -10,6 +10,7 @@
class nsIEventTarget; class nsIEventTarget;
class nsIHttpUpgradeListener; class nsIHttpUpgradeListener;
class nsIInterfaceRequestor; class nsIInterfaceRequestor;
struct ClassOfServiceStruct;
namespace mozilla { namespace mozilla {
namespace net { namespace net {
@ -113,8 +114,8 @@ class HttpConnectionMgrShell : public nsISupports {
[[nodiscard]] virtual nsresult RescheduleTransaction(HttpTransactionShell*, [[nodiscard]] virtual nsresult RescheduleTransaction(HttpTransactionShell*,
int32_t priority) = 0; int32_t priority) = 0;
void virtual UpdateClassOfServiceOnTransaction(HttpTransactionShell*, void virtual UpdateClassOfServiceOnTransaction(
uint32_t classOfService) = 0; HttpTransactionShell*, const ClassOfServiceStruct& classOfService) = 0;
// cancels a transaction w/ the given reason. // cancels a transaction w/ the given reason.
[[nodiscard]] virtual nsresult CancelTransaction(HttpTransactionShell*, [[nodiscard]] virtual nsresult CancelTransaction(HttpTransactionShell*,
@ -204,7 +205,8 @@ NS_DEFINE_STATIC_IID_ACCESSOR(HttpConnectionMgrShell,
virtual nsresult RescheduleTransaction(HttpTransactionShell*, \ virtual nsresult RescheduleTransaction(HttpTransactionShell*, \
int32_t priority) override; \ int32_t priority) override; \
void virtual UpdateClassOfServiceOnTransaction( \ void virtual UpdateClassOfServiceOnTransaction( \
HttpTransactionShell*, uint32_t classOfService) override; \ HttpTransactionShell*, const ClassOfServiceStruct& classOfService) \
override; \
virtual nsresult CancelTransaction(HttpTransactionShell*, nsresult reason) \ virtual nsresult CancelTransaction(HttpTransactionShell*, nsresult reason) \
override; \ override; \
virtual nsresult ReclaimConnection(HttpConnectionBase* conn) override; \ virtual nsresult ReclaimConnection(HttpConnectionBase* conn) override; \

Просмотреть файл

@ -70,8 +70,8 @@ nsresult HttpTransactionChild::InitInternal(
nsHttpRequestHead* requestHead, nsIInputStream* requestBody, nsHttpRequestHead* requestHead, nsIInputStream* requestBody,
uint64_t requestContentLength, bool requestBodyHasHeaders, uint64_t requestContentLength, bool requestBodyHasHeaders,
uint64_t topLevelOuterContentWindowId, uint8_t httpTrafficCategory, uint64_t topLevelOuterContentWindowId, uint8_t httpTrafficCategory,
uint64_t requestContextID, uint32_t classOfService, uint32_t initialRwin, uint64_t requestContextID, ClassOfServiceStruct classOfService,
bool responseTimeoutEnabled, uint64_t channelId, uint32_t initialRwin, bool responseTimeoutEnabled, uint64_t channelId,
bool aHasTransactionObserver, bool aHasTransactionObserver,
const Maybe<H2PushedStreamArg>& aPushedStreamArg) { const Maybe<H2PushedStreamArg>& aPushedStreamArg) {
LOG(("HttpTransactionChild::InitInternal [this=%p caps=%x]\n", this, caps)); LOG(("HttpTransactionChild::InitInternal [this=%p caps=%x]\n", this, caps));
@ -173,7 +173,7 @@ mozilla::ipc::IPCResult HttpTransactionChild::RecvInit(
const uint64_t& aReqContentLength, const bool& aReqBodyIncludesHeaders, const uint64_t& aReqContentLength, const bool& aReqBodyIncludesHeaders,
const uint64_t& aTopLevelOuterContentWindowId, const uint64_t& aTopLevelOuterContentWindowId,
const uint8_t& aHttpTrafficCategory, const uint64_t& aRequestContextID, const uint8_t& aHttpTrafficCategory, const uint64_t& aRequestContextID,
const uint32_t& aClassOfService, const uint32_t& aInitialRwin, const ClassOfServiceStruct& aClassOfService, const uint32_t& aInitialRwin,
const bool& aResponseTimeoutEnabled, const uint64_t& aChannelId, const bool& aResponseTimeoutEnabled, const uint64_t& aChannelId,
const bool& aHasTransactionObserver, const bool& aHasTransactionObserver,
const Maybe<H2PushedStreamArg>& aPushedStreamArg, const Maybe<H2PushedStreamArg>& aPushedStreamArg,

Просмотреть файл

@ -56,7 +56,7 @@ class HttpTransactionChild final : public PHttpTransactionChild,
const bool& aReqBodyIncludesHeaders, const bool& aReqBodyIncludesHeaders,
const uint64_t& aTopLevelOuterContentWindowId, const uint64_t& aTopLevelOuterContentWindowId,
const uint8_t& aHttpTrafficCategory, const uint64_t& aRequestContextID, const uint8_t& aHttpTrafficCategory, const uint64_t& aRequestContextID,
const uint32_t& aClassOfService, const uint32_t& aInitialRwin, const ClassOfServiceStruct& aClassOfService, const uint32_t& aInitialRwin,
const bool& aResponseTimeoutEnabled, const uint64_t& aChannelId, const bool& aResponseTimeoutEnabled, const uint64_t& aChannelId,
const bool& aHasTransactionObserver, const bool& aHasTransactionObserver,
const Maybe<H2PushedStreamArg>& aPushedStreamArg, const Maybe<H2PushedStreamArg>& aPushedStreamArg,
@ -88,8 +88,8 @@ class HttpTransactionChild final : public PHttpTransactionChild,
nsIInputStream* requestBody, // use the trick in bug 1277681 nsIInputStream* requestBody, // use the trick in bug 1277681
uint64_t requestContentLength, bool requestBodyHasHeaders, uint64_t requestContentLength, bool requestBodyHasHeaders,
uint64_t topLevelOuterContentWindowId, uint8_t httpTrafficCategory, uint64_t topLevelOuterContentWindowId, uint8_t httpTrafficCategory,
uint64_t requestContextID, uint32_t classOfService, uint32_t initialRwin, uint64_t requestContextID, ClassOfServiceStruct classOfService,
bool responseTimeoutEnabled, uint64_t channelId, uint32_t initialRwin, bool responseTimeoutEnabled, uint64_t channelId,
bool aHasTransactionObserver, bool aHasTransactionObserver,
const Maybe<H2PushedStreamArg>& aPushedStreamArg); const Maybe<H2PushedStreamArg>& aPushedStreamArg);

Просмотреть файл

@ -88,7 +88,7 @@ nsresult HttpTransactionParent::Init(
bool requestBodyHasHeaders, nsIEventTarget* target, bool requestBodyHasHeaders, nsIEventTarget* target,
nsIInterfaceRequestor* callbacks, nsITransportEventSink* eventsink, nsIInterfaceRequestor* callbacks, nsITransportEventSink* eventsink,
uint64_t topLevelOuterContentWindowId, HttpTrafficCategory trafficCategory, uint64_t topLevelOuterContentWindowId, HttpTrafficCategory trafficCategory,
nsIRequestContext* requestContext, uint32_t classOfService, nsIRequestContext* requestContext, ClassOfServiceStruct classOfService,
uint32_t initialRwin, bool responseTimeoutEnabled, uint64_t channelId, uint32_t initialRwin, bool responseTimeoutEnabled, uint64_t channelId,
TransactionObserverFunc&& transactionObserver, TransactionObserverFunc&& transactionObserver,
OnPushCallback&& aOnPushCallback, OnPushCallback&& aOnPushCallback,

Просмотреть файл

@ -7,6 +7,7 @@
#include <functional> #include <functional>
#include "nsISupports.h" #include "nsISupports.h"
#include "nsIClassOfService.h"
#include "TimingStruct.h" #include "TimingStruct.h"
#include "nsInputStreamPump.h" #include "nsInputStreamPump.h"
#include "nsIEarlyHintObserver.h" #include "nsIEarlyHintObserver.h"
@ -81,7 +82,7 @@ class HttpTransactionShell : public nsISupports {
nsIEventTarget* consumerTarget, nsIInterfaceRequestor* callbacks, nsIEventTarget* consumerTarget, nsIInterfaceRequestor* callbacks,
nsITransportEventSink* eventsink, uint64_t topBrowsingContextId, nsITransportEventSink* eventsink, uint64_t topBrowsingContextId,
HttpTrafficCategory trafficCategory, nsIRequestContext* requestContext, HttpTrafficCategory trafficCategory, nsIRequestContext* requestContext,
uint32_t classOfService, uint32_t initialRwin, ClassOfServiceStruct classOfService, uint32_t initialRwin,
bool responseTimeoutEnabled, uint64_t channelId, bool responseTimeoutEnabled, uint64_t channelId,
TransactionObserverFunc&& transactionObserver, TransactionObserverFunc&& transactionObserver,
OnPushCallback&& aOnPushCallback, OnPushCallback&& aOnPushCallback,
@ -173,7 +174,7 @@ NS_DEFINE_STATIC_IID_ACCESSOR(HttpTransactionShell, HTTPTRANSACTIONSHELL_IID)
nsIEventTarget* consumerTarget, nsIInterfaceRequestor* callbacks, \ nsIEventTarget* consumerTarget, nsIInterfaceRequestor* callbacks, \
nsITransportEventSink* eventsink, uint64_t topBrowsingContextId, \ nsITransportEventSink* eventsink, uint64_t topBrowsingContextId, \
HttpTrafficCategory trafficCategory, nsIRequestContext* requestContext, \ HttpTrafficCategory trafficCategory, nsIRequestContext* requestContext, \
uint32_t classOfService, uint32_t initialRwin, \ ClassOfServiceStruct classOfService, uint32_t initialRwin, \
bool responseTimeoutEnabled, uint64_t channelId, \ bool responseTimeoutEnabled, uint64_t channelId, \
TransactionObserverFunc&& transactionObserver, \ TransactionObserverFunc&& transactionObserver, \
OnPushCallback&& aOnPushCallback, \ OnPushCallback&& aOnPushCallback, \

Просмотреть файл

@ -616,19 +616,31 @@ InterceptedHttpChannel::SetPriority(int32_t aPriority) {
NS_IMETHODIMP NS_IMETHODIMP
InterceptedHttpChannel::SetClassFlags(uint32_t aClassFlags) { InterceptedHttpChannel::SetClassFlags(uint32_t aClassFlags) {
mClassOfService = aClassFlags; mClassOfService.SetFlags(aClassFlags);
return NS_OK; return NS_OK;
} }
NS_IMETHODIMP NS_IMETHODIMP
InterceptedHttpChannel::ClearClassFlags(uint32_t aClassFlags) { InterceptedHttpChannel::ClearClassFlags(uint32_t aClassFlags) {
mClassOfService &= ~aClassFlags; mClassOfService.SetFlags(~aClassFlags & mClassOfService.Flags());
return NS_OK; return NS_OK;
} }
NS_IMETHODIMP NS_IMETHODIMP
InterceptedHttpChannel::AddClassFlags(uint32_t aClassFlags) { InterceptedHttpChannel::AddClassFlags(uint32_t aClassFlags) {
mClassOfService |= aClassFlags; mClassOfService.SetFlags(aClassFlags | mClassOfService.Flags());
return NS_OK;
}
NS_IMETHODIMP
InterceptedHttpChannel::SetClassOfService(ClassOfServiceStruct cos) {
mClassOfService = cos;
return NS_OK;
}
NS_IMETHODIMP
InterceptedHttpChannel::SetIncremental(bool incremental) {
mClassOfService.SetIncremental(incremental);
return NS_OK; return NS_OK;
} }

Просмотреть файл

@ -268,6 +268,12 @@ class InterceptedHttpChannel final
NS_IMETHOD NS_IMETHOD
AddClassFlags(uint32_t flags) override; AddClassFlags(uint32_t flags) override;
NS_IMETHOD
SetClassOfService(ClassOfServiceStruct cos) override;
NS_IMETHOD
SetIncremental(bool incremental) override;
NS_IMETHOD NS_IMETHOD
ResumeAt(uint64_t startPos, const nsACString& entityID) override; ResumeAt(uint64_t startPos, const nsACString& entityID) override;

Просмотреть файл

@ -18,6 +18,7 @@ include "mozilla/dom/ReferrerInfoUtils.h";
include "mozilla/net/NeckoMessageUtils.h"; include "mozilla/net/NeckoMessageUtils.h";
using mozilla::OriginAttributes from "mozilla/ipc/BackgroundUtils.h"; using mozilla::OriginAttributes from "mozilla/ipc/BackgroundUtils.h";
using struct ClassOfServiceStruct from "nsIClassOfService.h";
namespace mozilla { namespace mozilla {
namespace net { namespace net {
@ -32,7 +33,7 @@ parent:
// Note: channels are opened during construction, so no open method here: // Note: channels are opened during construction, so no open method here:
// see PNecko.ipdl // see PNecko.ipdl
async SetClassOfService(uint32_t cos); async SetClassOfService(ClassOfServiceStruct cos);
async Suspend(); async Suspend();
async Resume(); async Resume();

Просмотреть файл

@ -10,6 +10,7 @@ include protocol PSocketProcess;
include protocol PHttpTransaction; include protocol PHttpTransaction;
include NeckoChannelParams; include NeckoChannelParams;
using mozilla::net::ClassOfServiceStruct from "nsIClassOfService.h";
namespace mozilla { namespace mozilla {
namespace net { namespace net {
@ -28,7 +29,7 @@ child:
PHttpTransaction aTransWithStickyConn); PHttpTransaction aTransWithStickyConn);
async RescheduleTransaction(PHttpTransaction aTrans, int32_t aPriority); async RescheduleTransaction(PHttpTransaction aTrans, int32_t aPriority);
async UpdateClassOfServiceOnTransaction(PHttpTransaction aTrans, async UpdateClassOfServiceOnTransaction(PHttpTransaction aTrans,
uint32_t aClassOfService); ClassOfServiceStruct aClassOfService);
async CancelTransaction(PHttpTransaction aTrans, nsresult aReason); async CancelTransaction(PHttpTransaction aTrans, nsresult aReason);
async SpeculativeConnect(HttpConnectionInfoCloneArgs aConnInfo, async SpeculativeConnect(HttpConnectionInfoCloneArgs aConnInfo,
SpeculativeConnectionOverriderArgs? aOverriderArgs, SpeculativeConnectionOverriderArgs? aOverriderArgs,

Просмотреть файл

@ -17,6 +17,7 @@ include "mozilla/net/NeckoMessageUtils.h";
using class mozilla::net::nsHttpRequestHead from "nsHttpRequestHead.h"; using class mozilla::net::nsHttpRequestHead from "nsHttpRequestHead.h";
using class nsHttpHeaderArray from "nsHttpHeaderArray.h"; using class nsHttpHeaderArray from "nsHttpHeaderArray.h";
using mozilla::net::NetAddr from "mozilla/net/DNS.h"; using mozilla::net::NetAddr from "mozilla/net/DNS.h";
using mozilla::net::ClassOfServiceStruct from "nsIClassOfService.h";
namespace mozilla { namespace mozilla {
namespace net { namespace net {
@ -83,7 +84,7 @@ child:
uint64_t topLevelOuterContentWindowId, uint64_t topLevelOuterContentWindowId,
uint8_t httpTrafficCategory, uint8_t httpTrafficCategory,
uint64_t requestContextID, uint64_t requestContextID,
uint32_t classOfService, ClassOfServiceStruct classOfService,
uint32_t initialRwin, uint32_t initialRwin,
bool responseTimeoutEnabled, bool responseTimeoutEnabled,
uint64_t channelId, uint64_t channelId,

Просмотреть файл

@ -442,13 +442,13 @@ nsresult TRRServiceChannel::BeginConnect() {
} }
if (gHttpHandler->CriticalRequestPrioritization()) { if (gHttpHandler->CriticalRequestPrioritization()) {
if (mClassOfService & nsIClassOfService::Leader) { if (mClassOfService.Flags() & nsIClassOfService::Leader) {
mCaps |= NS_HTTP_LOAD_AS_BLOCKING; mCaps |= NS_HTTP_LOAD_AS_BLOCKING;
} }
if (mClassOfService & nsIClassOfService::Unblocked) { if (mClassOfService.Flags() & nsIClassOfService::Unblocked) {
mCaps |= NS_HTTP_LOAD_UNBLOCKED; mCaps |= NS_HTTP_LOAD_UNBLOCKED;
} }
if (mClassOfService & nsIClassOfService::UrgentStart && if (mClassOfService.Flags() & nsIClassOfService::UrgentStart &&
gHttpHandler->IsUrgentStartEnabled()) { gHttpHandler->IsUrgentStartEnabled()) {
mCaps |= NS_HTTP_URGENT_START; mCaps |= NS_HTTP_URGENT_START;
SetPriority(nsISupportsPriority::PRIORITY_HIGHEST); SetPriority(nsISupportsPriority::PRIORITY_HIGHEST);
@ -528,8 +528,10 @@ nsresult TRRServiceChannel::Connect() {
} }
nsresult TRRServiceChannel::SetupTransaction() { nsresult TRRServiceChannel::SetupTransaction() {
LOG(("TRRServiceChannel::SetupTransaction [this=%p, cos=%u, prio=%d]\n", this, LOG((
mClassOfService, mPriority)); "TRRServiceChannel::SetupTransaction "
"[this=%p, cos=%lu, inc=%d, prio=%d]\n",
this, mClassOfService.Flags(), mClassOfService.Incremental(), mPriority));
NS_ENSURE_TRUE(!mTransaction, NS_ERROR_ALREADY_INITIALIZED); NS_ENSURE_TRUE(!mTransaction, NS_ERROR_ALREADY_INITIALIZED);
@ -1275,8 +1277,8 @@ TRRServiceChannel::SetPriority(int32_t value) {
} }
void TRRServiceChannel::OnClassOfServiceUpdated() { void TRRServiceChannel::OnClassOfServiceUpdated() {
LOG(("TRRServiceChannel::OnClassOfServiceUpdated this=%p, cos=%u", this, LOG(("TRRServiceChannel::OnClassOfServiceUpdated this=%p, cos=%lu inc=%d",
mClassOfService)); this, mClassOfService.Flags(), mClassOfService.Incremental()));
if (mTransaction) { if (mTransaction) {
gHttpHandler->UpdateClassOfServiceOnTransaction(mTransaction, gHttpHandler->UpdateClassOfServiceOnTransaction(mTransaction,
@ -1286,8 +1288,28 @@ void TRRServiceChannel::OnClassOfServiceUpdated() {
NS_IMETHODIMP NS_IMETHODIMP
TRRServiceChannel::SetClassFlags(uint32_t inFlags) { TRRServiceChannel::SetClassFlags(uint32_t inFlags) {
uint32_t previous = mClassOfService; uint32_t previous = mClassOfService.Flags();
mClassOfService = inFlags; mClassOfService.SetFlags(inFlags);
if (previous != mClassOfService.Flags()) {
OnClassOfServiceUpdated();
}
return NS_OK;
}
NS_IMETHODIMP
TRRServiceChannel::SetIncremental(bool inFlag) {
bool previous = mClassOfService.Incremental();
mClassOfService.SetIncremental(inFlag);
if (previous != mClassOfService.Incremental()) {
OnClassOfServiceUpdated();
}
return NS_OK;
}
NS_IMETHODIMP
TRRServiceChannel::SetClassOfService(ClassOfServiceStruct cos) {
ClassOfServiceStruct previous = mClassOfService;
mClassOfService = cos;
if (previous != mClassOfService) { if (previous != mClassOfService) {
OnClassOfServiceUpdated(); OnClassOfServiceUpdated();
} }
@ -1296,9 +1318,9 @@ TRRServiceChannel::SetClassFlags(uint32_t inFlags) {
NS_IMETHODIMP NS_IMETHODIMP
TRRServiceChannel::AddClassFlags(uint32_t inFlags) { TRRServiceChannel::AddClassFlags(uint32_t inFlags) {
uint32_t previous = mClassOfService; uint32_t previous = mClassOfService.Flags();
mClassOfService |= inFlags; mClassOfService.SetFlags(inFlags | mClassOfService.Flags());
if (previous != mClassOfService) { if (previous != mClassOfService.Flags()) {
OnClassOfServiceUpdated(); OnClassOfServiceUpdated();
} }
return NS_OK; return NS_OK;
@ -1306,9 +1328,9 @@ TRRServiceChannel::AddClassFlags(uint32_t inFlags) {
NS_IMETHODIMP NS_IMETHODIMP
TRRServiceChannel::ClearClassFlags(uint32_t inFlags) { TRRServiceChannel::ClearClassFlags(uint32_t inFlags) {
uint32_t previous = mClassOfService; uint32_t previous = mClassOfService.Flags();
mClassOfService &= ~inFlags; mClassOfService.SetFlags(~inFlags & mClassOfService.Flags());
if (previous != mClassOfService) { if (previous != mClassOfService.Flags()) {
OnClassOfServiceUpdated(); OnClassOfServiceUpdated();
} }
return NS_OK; return NS_OK;

Просмотреть файл

@ -82,6 +82,8 @@ class TRRServiceChannel : public HttpBaseChannel,
NS_IMETHOD SetClassFlags(uint32_t inFlags) override; NS_IMETHOD SetClassFlags(uint32_t inFlags) override;
NS_IMETHOD AddClassFlags(uint32_t inFlags) override; NS_IMETHOD AddClassFlags(uint32_t inFlags) override;
NS_IMETHOD ClearClassFlags(uint32_t inFlags) override; NS_IMETHOD ClearClassFlags(uint32_t inFlags) override;
NS_IMETHOD SetIncremental(bool inFlag) override;
NS_IMETHOD SetClassOfService(ClassOfServiceStruct cos) override;
// nsIResumableChannel // nsIResumableChannel
NS_IMETHOD ResumeAt(uint64_t startPos, const nsACString& entityID) override; NS_IMETHOD ResumeAt(uint64_t startPos, const nsACString& entityID) override;
NS_IMETHOD SetEarlyHintObserver(nsIEarlyHintObserver* aObserver) override { NS_IMETHOD SetEarlyHintObserver(nsIEarlyHintObserver* aObserver) override {

Просмотреть файл

@ -717,8 +717,9 @@ nsresult nsHttpChannel::Connect() {
} }
bool isTrackingResource = IsThirdPartyTrackingResource(); bool isTrackingResource = IsThirdPartyTrackingResource();
LOG(("nsHttpChannel %p tracking resource=%d, cos=%u", this, LOG(("nsHttpChannel %p tracking resource=%d, cos=%lu, inc=%d", this,
isTrackingResource, mClassOfService)); isTrackingResource, mClassOfService.Flags(),
mClassOfService.Incremental()));
if (isTrackingResource) { if (isTrackingResource) {
AddClassFlags(nsIClassOfService::Tail); AddClassFlags(nsIClassOfService::Tail);
@ -1076,8 +1077,9 @@ void nsHttpChannel::HandleAsyncNotModified() {
} }
nsresult nsHttpChannel::SetupTransaction() { nsresult nsHttpChannel::SetupTransaction() {
LOG(("nsHttpChannel::SetupTransaction [this=%p, cos=%u, prio=%d]\n", this, LOG(("nsHttpChannel::SetupTransaction [this=%p, cos=%lu, inc=%d prio=%d]\n",
mClassOfService, mPriority)); this, mClassOfService.Flags(), mClassOfService.Incremental(),
mPriority));
NS_ENSURE_TRUE(!mTransaction, NS_ERROR_ALREADY_INITIALIZED); NS_ENSURE_TRUE(!mTransaction, NS_ERROR_ALREADY_INITIALIZED);
@ -1368,7 +1370,7 @@ HttpTrafficCategory nsHttpChannel::CreateTrafficCategory() {
HttpTrafficAnalyzer::ClassOfService cos; HttpTrafficAnalyzer::ClassOfService cos;
{ {
if ((mClassOfService & nsIClassOfService::Leader) && if ((mClassOfService.Flags() & nsIClassOfService::Leader) &&
mLoadInfo->GetExternalContentPolicyType() == mLoadInfo->GetExternalContentPolicyType() ==
ExtContentPolicy::TYPE_SCRIPT) { ExtContentPolicy::TYPE_SCRIPT) {
cos = HttpTrafficAnalyzer::ClassOfService::eLeader; cos = HttpTrafficAnalyzer::ClassOfService::eLeader;
@ -3485,7 +3487,7 @@ nsresult nsHttpChannel::OpenCacheEntryInternal(bool isHttps) {
} }
NS_ENSURE_SUCCESS(rv, rv); NS_ENSURE_SUCCESS(rv, rv);
if ((mClassOfService & nsIClassOfService::Leader) || if ((mClassOfService.Flags() & nsIClassOfService::Leader) ||
(mLoadFlags & LOAD_INITIAL_DOCUMENT_URI)) { (mLoadFlags & LOAD_INITIAL_DOCUMENT_URI)) {
cacheEntryOpenFlags |= nsICacheStorage::OPEN_PRIORITY; cacheEntryOpenFlags |= nsICacheStorage::OPEN_PRIORITY;
} }
@ -6178,13 +6180,13 @@ nsresult nsHttpChannel::BeginConnect() {
} }
if (gHttpHandler->CriticalRequestPrioritization()) { if (gHttpHandler->CriticalRequestPrioritization()) {
if (mClassOfService & nsIClassOfService::Leader) { if (mClassOfService.Flags() & nsIClassOfService::Leader) {
mCaps |= NS_HTTP_LOAD_AS_BLOCKING; mCaps |= NS_HTTP_LOAD_AS_BLOCKING;
} }
if (mClassOfService & nsIClassOfService::Unblocked) { if (mClassOfService.Flags() & nsIClassOfService::Unblocked) {
mCaps |= NS_HTTP_LOAD_UNBLOCKED; mCaps |= NS_HTTP_LOAD_UNBLOCKED;
} }
if (mClassOfService & nsIClassOfService::UrgentStart && if (mClassOfService.Flags() & nsIClassOfService::UrgentStart &&
gHttpHandler->IsUrgentStartEnabled()) { gHttpHandler->IsUrgentStartEnabled()) {
mCaps |= NS_HTTP_URGENT_START; mCaps |= NS_HTTP_URGENT_START;
SetPriority(nsISupportsPriority::PRIORITY_HIGHEST); SetPriority(nsISupportsPriority::PRIORITY_HIGHEST);
@ -6462,8 +6464,8 @@ nsHttpChannel::SetPriority(int32_t value) {
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void nsHttpChannel::OnClassOfServiceUpdated() { void nsHttpChannel::OnClassOfServiceUpdated() {
LOG(("nsHttpChannel::OnClassOfServiceUpdated this=%p, cos=%u", this, LOG(("nsHttpChannel::OnClassOfServiceUpdated this=%p, cos=%lu, inc=%d", this,
mClassOfService)); mClassOfService.Flags(), mClassOfService.Incremental()));
if (mTransaction) { if (mTransaction) {
gHttpHandler->UpdateClassOfServiceOnTransaction(mTransaction, gHttpHandler->UpdateClassOfServiceOnTransaction(mTransaction,
@ -6478,9 +6480,9 @@ void nsHttpChannel::OnClassOfServiceUpdated() {
NS_IMETHODIMP NS_IMETHODIMP
nsHttpChannel::SetClassFlags(uint32_t inFlags) { nsHttpChannel::SetClassFlags(uint32_t inFlags) {
uint32_t previous = mClassOfService; uint32_t previous = mClassOfService.Flags();
mClassOfService = inFlags; mClassOfService.SetFlags(inFlags);
if (previous != mClassOfService) { if (previous != mClassOfService.Flags()) {
OnClassOfServiceUpdated(); OnClassOfServiceUpdated();
} }
return NS_OK; return NS_OK;
@ -6488,9 +6490,9 @@ nsHttpChannel::SetClassFlags(uint32_t inFlags) {
NS_IMETHODIMP NS_IMETHODIMP
nsHttpChannel::AddClassFlags(uint32_t inFlags) { nsHttpChannel::AddClassFlags(uint32_t inFlags) {
uint32_t previous = mClassOfService; uint32_t previous = mClassOfService.Flags();
mClassOfService |= inFlags; mClassOfService.SetFlags(inFlags | mClassOfService.Flags());
if (previous != mClassOfService) { if (previous != mClassOfService.Flags()) {
OnClassOfServiceUpdated(); OnClassOfServiceUpdated();
} }
return NS_OK; return NS_OK;
@ -6498,14 +6500,34 @@ nsHttpChannel::AddClassFlags(uint32_t inFlags) {
NS_IMETHODIMP NS_IMETHODIMP
nsHttpChannel::ClearClassFlags(uint32_t inFlags) { nsHttpChannel::ClearClassFlags(uint32_t inFlags) {
uint32_t previous = mClassOfService; uint32_t previous = mClassOfService.Flags();
mClassOfService &= ~inFlags; mClassOfService.SetFlags(~inFlags & mClassOfService.Flags());
if (previous != mClassOfService.Flags()) {
OnClassOfServiceUpdated();
}
return NS_OK;
}
NS_IMETHODIMP
nsHttpChannel::SetClassOfService(ClassOfServiceStruct cos) {
ClassOfServiceStruct previous = mClassOfService;
mClassOfService = cos;
if (previous != mClassOfService) { if (previous != mClassOfService) {
OnClassOfServiceUpdated(); OnClassOfServiceUpdated();
} }
return NS_OK; return NS_OK;
} }
NS_IMETHODIMP
nsHttpChannel::SetIncremental(bool incremental) {
bool previous = mClassOfService.Incremental();
mClassOfService.SetIncremental(incremental);
if (previous != mClassOfService.Incremental()) {
OnClassOfServiceUpdated();
}
return NS_OK;
}
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// nsHttpChannel::nsIProtocolProxyCallback // nsHttpChannel::nsIProtocolProxyCallback
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -9161,18 +9183,18 @@ nsHttpChannel::TimerCallback::Notify(nsITimer* aTimer) {
} }
bool nsHttpChannel::EligibleForTailing() { bool nsHttpChannel::EligibleForTailing() {
if (!(mClassOfService & nsIClassOfService::Tail)) { if (!(mClassOfService.Flags() & nsIClassOfService::Tail)) {
return false; return false;
} }
if (mClassOfService & if (mClassOfService.Flags() &
(nsIClassOfService::UrgentStart | nsIClassOfService::Leader | (nsIClassOfService::UrgentStart | nsIClassOfService::Leader |
nsIClassOfService::TailForbidden)) { nsIClassOfService::TailForbidden)) {
return false; return false;
} }
if (mClassOfService & nsIClassOfService::Unblocked && if (mClassOfService.Flags() & nsIClassOfService::Unblocked &&
!(mClassOfService & nsIClassOfService::TailAllowed)) { !(mClassOfService.Flags() & nsIClassOfService::TailAllowed)) {
return false; return false;
} }

Просмотреть файл

@ -159,6 +159,8 @@ class nsHttpChannel final : public HttpBaseChannel,
NS_IMETHOD SetClassFlags(uint32_t inFlags) override; NS_IMETHOD SetClassFlags(uint32_t inFlags) override;
NS_IMETHOD AddClassFlags(uint32_t inFlags) override; NS_IMETHOD AddClassFlags(uint32_t inFlags) override;
NS_IMETHOD ClearClassFlags(uint32_t inFlags) override; NS_IMETHOD ClearClassFlags(uint32_t inFlags) override;
NS_IMETHOD SetClassOfService(ClassOfServiceStruct cos) override;
NS_IMETHOD SetIncremental(bool incremental) override;
// nsIResumableChannel // nsIResumableChannel
NS_IMETHOD ResumeAt(uint64_t startPos, const nsACString& entityID) override; NS_IMETHOD ResumeAt(uint64_t startPos, const nsACString& entityID) override;

Просмотреть файл

@ -453,7 +453,7 @@ nsresult nsHttpConnection::Activate(nsAHttpTransaction* trans, uint32_t caps,
nsHttpTransaction* hTrans = trans->QueryHttpTransaction(); nsHttpTransaction* hTrans = trans->QueryHttpTransaction();
if (hTrans) { if (hTrans) {
hTrans->BootstrapTimings(mBootstrappedTimings); hTrans->BootstrapTimings(mBootstrappedTimings);
SetUrgentStartPreferred(hTrans->ClassOfService() & SetUrgentStartPreferred(hTrans->ClassOfService().Flags() &
nsIClassOfService::UrgentStart); nsIClassOfService::UrgentStart);
} }
} }

Просмотреть файл

@ -349,14 +349,29 @@ nsresult nsHttpConnectionMgr::RescheduleTransaction(HttpTransactionShell* trans,
} }
void nsHttpConnectionMgr::UpdateClassOfServiceOnTransaction( void nsHttpConnectionMgr::UpdateClassOfServiceOnTransaction(
HttpTransactionShell* trans, uint32_t classOfService) { HttpTransactionShell* trans, const ClassOfServiceStruct& classOfService) {
LOG( LOG(
("nsHttpConnectionMgr::UpdateClassOfServiceOnTransaction [trans=%p " ("nsHttpConnectionMgr::UpdateClassOfServiceOnTransaction [trans=%p "
"classOfService=%" PRIu32 "]\n", "classOfService flags=%" PRIu32 " inc=%d]\n",
trans, static_cast<uint32_t>(classOfService))); trans, static_cast<uint32_t>(classOfService.Flags()),
Unused << PostEvent( classOfService.Incremental()));
&nsHttpConnectionMgr::OnMsgUpdateClassOfServiceOnTransaction,
static_cast<int32_t>(classOfService), trans->AsHttpTransaction()); Unused << EnsureSocketThreadTarget();
ReentrantMonitorAutoEnter mon(mReentrantMonitor);
if (!mSocketThreadTarget) {
NS_WARNING("cannot post event if not initialized");
}
RefPtr<nsHttpConnectionMgr> self(this);
Unused << mSocketThreadTarget->Dispatch(NS_NewRunnableFunction(
"nsHttpConnectionMgr::CallUpdateClassOfServiceOnTransaction",
[cos{std::move(classOfService)}, self{std::move(self)},
trans{std::move(trans)}]() {
self->OnMsgUpdateClassOfServiceOnTransaction(
cos, trans->AsHttpTransaction());
}));
} }
nsresult nsHttpConnectionMgr::CancelTransaction(HttpTransactionShell* trans, nsresult nsHttpConnectionMgr::CancelTransaction(HttpTransactionShell* trans,
@ -1256,7 +1271,7 @@ nsresult nsHttpConnectionMgr::MakeNewConnection(
nsresult rv = ent->CreateDnsAndConnectSocket( nsresult rv = ent->CreateDnsAndConnectSocket(
trans, trans->Caps(), false, false, trans, trans->Caps(), false, false,
trans->ClassOfService() & nsIClassOfService::UrgentStart, true, trans->ClassOfService().Flags() & nsIClassOfService::UrgentStart, true,
pendingTransInfo); pendingTransInfo);
if (NS_FAILED(rv)) { if (NS_FAILED(rv)) {
/* hard failure */ /* hard failure */
@ -1440,7 +1455,7 @@ nsresult nsHttpConnectionMgr::TryDispatchTransaction(
// don't respect urgency so that non-urgent transaction will be allowed // don't respect urgency so that non-urgent transaction will be allowed
// to dispatch on an urgent-start-only marked connection to avoid // to dispatch on an urgent-start-only marked connection to avoid
// dispatch deadlocks // dispatch deadlocks
if (!(trans->ClassOfService() & nsIClassOfService::UrgentStart) && if (!(trans->ClassOfService().Flags() & nsIClassOfService::UrgentStart) &&
idleConnsAllUrgent && idleConnsAllUrgent &&
ent->ActiveConnsLength() < MaxPersistConnections(ent)) { ent->ActiveConnsLength() < MaxPersistConnections(ent)) {
rv = TryDispatchTransactionOnIdleConn(ent, pendingTransInfo, false); rv = TryDispatchTransactionOnIdleConn(ent, pendingTransInfo, false);
@ -1478,7 +1493,8 @@ nsresult nsHttpConnectionMgr::TryDispatchTransactionOnIdleConn(
bool onlyUrgent = !!ent->IdleConnectionsLength(); bool onlyUrgent = !!ent->IdleConnectionsLength();
nsHttpTransaction* trans = pendingTransInfo->Transaction(); nsHttpTransaction* trans = pendingTransInfo->Transaction();
bool urgentTrans = trans->ClassOfService() & nsIClassOfService::UrgentStart; bool urgentTrans =
trans->ClassOfService().Flags() & nsIClassOfService::UrgentStart;
LOG( LOG(
("nsHttpConnectionMgr::TryDispatchTransactionOnIdleConn, ent=%p, " ("nsHttpConnectionMgr::TryDispatchTransactionOnIdleConn, ent=%p, "
@ -2051,20 +2067,21 @@ void nsHttpConnectionMgr::OnMsgReschedTransaction(int32_t priority,
} }
void nsHttpConnectionMgr::OnMsgUpdateClassOfServiceOnTransaction( void nsHttpConnectionMgr::OnMsgUpdateClassOfServiceOnTransaction(
int32_t arg, ARefBase* param) { ClassOfServiceStruct cos, ARefBase* param) {
MOZ_ASSERT(OnSocketThread(), "not on socket thread"); MOZ_ASSERT(OnSocketThread(), "not on socket thread");
LOG( LOG(
("nsHttpConnectionMgr::OnMsgUpdateClassOfServiceOnTransaction " ("nsHttpConnectionMgr::OnMsgUpdateClassOfServiceOnTransaction "
"[trans=%p]\n", "[trans=%p]\n",
param)); param));
uint32_t cos = static_cast<uint32_t>(arg);
nsHttpTransaction* trans = static_cast<nsHttpTransaction*>(param); nsHttpTransaction* trans = static_cast<nsHttpTransaction*>(param);
uint32_t previous = trans->ClassOfService(); ClassOfServiceStruct previous = trans->ClassOfService();
trans->SetClassOfService(cos); trans->SetClassOfService(cos);
if ((previous ^ cos) & (NS_HTTP_LOAD_AS_BLOCKING | NS_HTTP_LOAD_UNBLOCKED)) { // incremental change alone will not trigger a reschedule
if ((previous.Flags() ^ cos.Flags()) &
(NS_HTTP_LOAD_AS_BLOCKING | NS_HTTP_LOAD_UNBLOCKED)) {
Unused << RescheduleTransaction(trans, trans->Priority()); Unused << RescheduleTransaction(trans, trans->Priority());
} }
} }

Просмотреть файл

@ -313,7 +313,7 @@ class nsHttpConnectionMgr final : public HttpConnectionMgrShell,
void OnMsgNewTransaction(int32_t, ARefBase*); void OnMsgNewTransaction(int32_t, ARefBase*);
void OnMsgNewTransactionWithStickyConn(int32_t, ARefBase*); void OnMsgNewTransactionWithStickyConn(int32_t, ARefBase*);
void OnMsgReschedTransaction(int32_t, ARefBase*); void OnMsgReschedTransaction(int32_t, ARefBase*);
void OnMsgUpdateClassOfServiceOnTransaction(int32_t, ARefBase*); void OnMsgUpdateClassOfServiceOnTransaction(ClassOfServiceStruct, ARefBase*);
void OnMsgCancelTransaction(int32_t, ARefBase*); void OnMsgCancelTransaction(int32_t, ARefBase*);
void OnMsgCancelTransactions(int32_t, ARefBase*); void OnMsgCancelTransactions(int32_t, ARefBase*);
void OnMsgProcessPendingQ(int32_t, ARefBase*); void OnMsgProcessPendingQ(int32_t, ARefBase*);

Просмотреть файл

@ -2662,7 +2662,7 @@ nsresult nsHttpHandler::RescheduleTransaction(HttpTransactionShell* trans,
} }
void nsHttpHandler::UpdateClassOfServiceOnTransaction( void nsHttpHandler::UpdateClassOfServiceOnTransaction(
HttpTransactionShell* trans, uint32_t classOfService) { HttpTransactionShell* trans, const ClassOfServiceStruct& classOfService) {
mConnMgr->UpdateClassOfServiceOnTransaction(trans, classOfService); mConnMgr->UpdateClassOfServiceOnTransaction(trans, classOfService);
} }

Просмотреть файл

@ -271,8 +271,8 @@ class nsHttpHandler final : public nsIHttpProtocolHandler,
[[nodiscard]] nsresult RescheduleTransaction(HttpTransactionShell* trans, [[nodiscard]] nsresult RescheduleTransaction(HttpTransactionShell* trans,
int32_t priority); int32_t priority);
void UpdateClassOfServiceOnTransaction(HttpTransactionShell* trans, void UpdateClassOfServiceOnTransaction(
uint32_t classOfService); HttpTransactionShell* trans, const ClassOfServiceStruct& classOfService);
// Called to cancel a transaction, which may or may not be assigned to // Called to cancel a transaction, which may or may not be assigned to
// a connection. Callable from any thread. // a connection. Callable from any thread.

Просмотреть файл

@ -112,19 +112,20 @@ void nsHttpTransaction::ResumeReading() {
} }
bool nsHttpTransaction::EligibleForThrottling() const { bool nsHttpTransaction::EligibleForThrottling() const {
return (mClassOfService & return (mClassOfServiceFlags &
(nsIClassOfService::Throttleable | nsIClassOfService::DontThrottle | (nsIClassOfService::Throttleable | nsIClassOfService::DontThrottle |
nsIClassOfService::Leader | nsIClassOfService::Unblocked)) == nsIClassOfService::Leader | nsIClassOfService::Unblocked)) ==
nsIClassOfService::Throttleable; nsIClassOfService::Throttleable;
} }
void nsHttpTransaction::SetClassOfService(uint32_t cos) { void nsHttpTransaction::SetClassOfService(ClassOfServiceStruct cos) {
if (mClosed) { if (mClosed) {
return; return;
} }
bool wasThrottling = EligibleForThrottling(); bool wasThrottling = EligibleForThrottling();
mClassOfService = cos; mClassOfServiceFlags = cos.Flags();
mClassOfServiceIncremental = cos.Incremental();
bool isThrottling = EligibleForThrottling(); bool isThrottling = EligibleForThrottling();
if (mConnection && wasThrottling != isThrottling) { if (mConnection && wasThrottling != isThrottling) {
@ -205,7 +206,7 @@ nsresult nsHttpTransaction::Init(
bool requestBodyHasHeaders, nsIEventTarget* target, bool requestBodyHasHeaders, nsIEventTarget* target,
nsIInterfaceRequestor* callbacks, nsITransportEventSink* eventsink, nsIInterfaceRequestor* callbacks, nsITransportEventSink* eventsink,
uint64_t topBrowsingContextId, HttpTrafficCategory trafficCategory, uint64_t topBrowsingContextId, HttpTrafficCategory trafficCategory,
nsIRequestContext* requestContext, uint32_t classOfService, nsIRequestContext* requestContext, ClassOfServiceStruct classOfService,
uint32_t initialRwin, bool responseTimeoutEnabled, uint64_t channelId, uint32_t initialRwin, bool responseTimeoutEnabled, uint64_t channelId,
TransactionObserverFunc&& transactionObserver, TransactionObserverFunc&& transactionObserver,
OnPushCallback&& aOnPushCallback, OnPushCallback&& aOnPushCallback,
@ -831,7 +832,7 @@ nsresult nsHttpTransaction::WritePipeSegment(nsIOutputStream* stream,
} }
bool nsHttpTransaction::ShouldThrottle() { bool nsHttpTransaction::ShouldThrottle() {
if (mClassOfService & nsIClassOfService::DontThrottle) { if (mClassOfServiceFlags & nsIClassOfService::DontThrottle) {
// We deliberately don't touch the throttling window here since // We deliberately don't touch the throttling window here since
// DontThrottle requests are expected to be long-standing media // DontThrottle requests are expected to be long-standing media
// streams and would just unnecessarily block running downloads. // streams and would just unnecessarily block running downloads.
@ -854,7 +855,7 @@ bool nsHttpTransaction::ShouldThrottle() {
return false; return false;
} }
if (!(mClassOfService & nsIClassOfService::Throttleable) && if (!(mClassOfServiceFlags & nsIClassOfService::Throttleable) &&
gHttpHandler->ConnMgr()->IsConnEntryUnderPressure(mConnInfo)) { gHttpHandler->ConnMgr()->IsConnEntryUnderPressure(mConnInfo)) {
LOG(("nsHttpTransaction::ShouldThrottle entry pressure this=%p", this)); LOG(("nsHttpTransaction::ShouldThrottle entry pressure this=%p", this));
// This is expensive to check (two hashtable lookups) but may help // This is expensive to check (two hashtable lookups) but may help

Просмотреть файл

@ -19,6 +19,7 @@
#include "nsITimer.h" #include "nsITimer.h"
#include "nsIEarlyHintObserver.h" #include "nsIEarlyHintObserver.h"
#include "nsTHashMap.h" #include "nsTHashMap.h"
#include "nsIClassOfService.h"
#include "TimingStruct.h" #include "TimingStruct.h"
#include "Http2Push.h" #include "Http2Push.h"
#include "mozilla/net/DNS.h" #include "mozilla/net/DNS.h"
@ -166,7 +167,7 @@ class nsHttpTransaction final : public nsAHttpTransaction,
void UpdateConnectionInfo(nsHttpConnectionInfo* aConnInfo); void UpdateConnectionInfo(nsHttpConnectionInfo* aConnInfo);
void SetClassOfService(uint32_t cos); void SetClassOfService(ClassOfServiceStruct cos);
virtual nsresult OnHTTPSRRAvailable( virtual nsresult OnHTTPSRRAvailable(
nsIDNSHTTPSSVCRecord* aHTTPSSVCRecord, nsIDNSHTTPSSVCRecord* aHTTPSSVCRecord,
@ -485,10 +486,13 @@ class nsHttpTransaction final : public nsAHttpTransaction,
void CollectTelemetryForUploads(); void CollectTelemetryForUploads();
public: public:
uint32_t ClassOfService() { return mClassOfService; } ClassOfServiceStruct ClassOfService() {
return {mClassOfServiceFlags, mClassOfServiceIncremental};
}
private: private:
Atomic<uint32_t, Relaxed> mClassOfService{0}; Atomic<uint32_t, Relaxed> mClassOfServiceFlags{0};
Atomic<bool, Relaxed> mClassOfServiceIncremental{false};
public: public:
// setting TunnelProvider to non-null means the transaction should only // setting TunnelProvider to non-null means the transaction should only