Bug 1590762 - Part 2: Bump the id for channel registration to uint64_t. r=mattwoodrow,necko-reviewers,valentin

This patch also makes the identifier for channels global, in the sense
that the generated identifier is generated outside of and passed to
the nsIRedirectChannelRegistrar.

Differential Revision: https://phabricator.services.mozilla.com/D79820
This commit is contained in:
Andreas Farre
2020-06-23 13:18:56 +00:00
parent d698a74044
commit b272f4b334
27 changed files with 74 additions and 64 deletions

View File

@@ -1585,7 +1585,7 @@ nsresult BrowsingContext::LoadURI(nsDocShellLoadState* aLoadState,
if (ContentParent* cp = Canonical()->GetContentParent()) {
// Attempt to initiate this load immediately in the parent, if it succeeds
// it'll return a unique identifier so that we can find it later.
uint32_t loadIdentifier = 0;
uint64_t loadIdentifier = 0;
if (Canonical()->AttemptLoadURIInParent(aLoadState, &loadIdentifier)) {
aLoadState->SetLoadIdentifier(loadIdentifier);
}

View File

@@ -813,7 +813,7 @@ MediaController* CanonicalBrowsingContext::GetMediaController() {
}
bool CanonicalBrowsingContext::AttemptLoadURIInParent(
nsDocShellLoadState* aLoadState, uint32_t* aLoadIdentifier) {
nsDocShellLoadState* aLoadState, uint64_t* aLoadIdentifier) {
// We currently only support starting loads directly from the
// CanonicalBrowsingContext for top-level BCs.
if (!IsTopContent() || !GetContentParent() ||

View File

@@ -151,7 +151,7 @@ class CanonicalBrowsingContext final : public BrowsingContext {
MediaController* GetMediaController();
bool AttemptLoadURIInParent(nsDocShellLoadState* aLoadState,
uint32_t* aLoadIdentifier);
uint64_t* aLoadIdentifier);
// Get or create a secure browser UI for this BrowsingContext
nsISecureBrowserUI* GetSecureBrowserUI();

View File

@@ -238,8 +238,8 @@ class nsDocShellLoadState final {
return mCancelContentJSEpoch;
}
void SetLoadIdentifier(uint32_t aIdent) { mLoadIdentifier = aIdent; }
uint32_t GetLoadIdentifier() const { return mLoadIdentifier; }
void SetLoadIdentifier(uint64_t aIdent) { mLoadIdentifier = aIdent; }
uint64_t GetLoadIdentifier() const { return mLoadIdentifier; }
// When loading a document through nsDocShell::LoadURI(), a special set of
// flags needs to be set based on other values in nsDocShellLoadState. This
@@ -415,7 +415,7 @@ class nsDocShellLoadState final {
// created in the parent process for this loads. DocumentChannels
// created in the content process can use this to find and attach
// to the in progress load.
uint32_t mLoadIdentifier;
uint64_t mLoadIdentifier;
};
#endif /* nsDocShellLoadState_h__ */

View File

@@ -9709,6 +9709,14 @@ uint64_t nsContentUtils::GenerateWindowId() {
return GenerateProcessSpecificId(++gNextWindowId);
}
// Next process-local load.
static Atomic<uint64_t> gNextLoadIdentifier(0);
/* static */
uint64_t nsContentUtils::GenerateLoadIdentifier() {
return GenerateProcessSpecificId(++gNextLoadIdentifier);
}
/* static */
bool nsContentUtils::GetUserIsInteracting() {
return UserInteractionObserver::sUserActive;

View File

@@ -3149,6 +3149,12 @@ class nsContentUtils {
*/
static uint64_t GenerateWindowId();
/**
* Generate an ID for a load which is unique across processes and will never
* be recycled.
*/
static uint64_t GenerateLoadIdentifier();
/**
* Determine whether or not the user is currently interacting with the web
* browser. This method is safe to call from off of the main thread.

View File

@@ -4090,7 +4090,7 @@ mozilla::ipc::IPCResult ContentParent::RecvLoadURIExternal(
}
mozilla::ipc::IPCResult ContentParent::RecvExtProtocolChannelConnectParent(
const uint32_t& registrarId) {
const uint64_t& registrarId) {
nsresult rv;
// First get the real channel created before redirect on the parent.

View File

@@ -1036,7 +1036,7 @@ class ContentParent final
nsIURI* uri, nsIPrincipal* triggeringPrincipal,
const MaybeDiscarded<BrowsingContext>& aContext);
mozilla::ipc::IPCResult RecvExtProtocolChannelConnectParent(
const uint32_t& registrarId);
const uint64_t& registrarId);
mozilla::ipc::IPCResult RecvSyncMessage(
const nsString& aMsg, const ClonedMessageData& aData,

View File

@@ -277,7 +277,7 @@ struct DocShellLoadStateInit
// bool mIsSrcDocLoad; // useless without sourcedocshell
// nsIChannel pendingRedirectedChannel; // sent through other mechanism
uint32_t LoadIdentifier;
uint64_t LoadIdentifier;
};
struct TimedChannelInfo

View File

@@ -978,7 +978,7 @@ parent:
async SetURITitle(nsIURI uri, nsString title);
async LoadURIExternal(nsIURI uri, nsIPrincipal triggeringPrincipal, MaybeDiscardedBrowsingContext browsingContext);
async ExtProtocolChannelConnectParent(uint32_t registrarId);
async ExtProtocolChannelConnectParent(uint64_t registrarId);
// PrefService message
sync GetGfxVars() returns (GfxVarUpdate[] vars);

View File

@@ -16,7 +16,6 @@ NS_IMPL_ISUPPORTS(RedirectChannelRegistrar, nsIRedirectChannelRegistrar)
RedirectChannelRegistrar::RedirectChannelRegistrar()
: mRealChannels(32),
mParentChannels(32),
mId(1),
mLock("RedirectChannelRegistrar") {
MOZ_ASSERT(!gSingleton);
}
@@ -38,23 +37,16 @@ void RedirectChannelRegistrar::Shutdown() {
}
NS_IMETHODIMP
RedirectChannelRegistrar::RegisterChannel(nsIChannel* channel,
uint32_t* _retval) {
RedirectChannelRegistrar::RegisterChannel(nsIChannel* channel, uint64_t id) {
MutexAutoLock lock(mLock);
mRealChannels.Put(mId, channel);
*_retval = mId;
++mId;
// Ensure we always provide positive ids
if (!mId) mId = 1;
mRealChannels.Put(id, channel);
return NS_OK;
}
NS_IMETHODIMP
RedirectChannelRegistrar::GetRegisteredChannel(uint32_t id,
RedirectChannelRegistrar::GetRegisteredChannel(uint64_t id,
nsIChannel** _retval) {
MutexAutoLock lock(mLock);
@@ -64,7 +56,7 @@ RedirectChannelRegistrar::GetRegisteredChannel(uint32_t id,
}
NS_IMETHODIMP
RedirectChannelRegistrar::LinkChannels(uint32_t id, nsIParentChannel* channel,
RedirectChannelRegistrar::LinkChannels(uint64_t id, nsIParentChannel* channel,
nsIChannel** _retval) {
MutexAutoLock lock(mLock);
@@ -75,7 +67,7 @@ RedirectChannelRegistrar::LinkChannels(uint32_t id, nsIParentChannel* channel,
}
NS_IMETHODIMP
RedirectChannelRegistrar::GetParentChannel(uint32_t id,
RedirectChannelRegistrar::GetParentChannel(uint64_t id,
nsIParentChannel** _retval) {
MutexAutoLock lock(mLock);
@@ -85,7 +77,7 @@ RedirectChannelRegistrar::GetParentChannel(uint32_t id,
}
NS_IMETHODIMP
RedirectChannelRegistrar::DeregisterChannels(uint32_t id) {
RedirectChannelRegistrar::DeregisterChannels(uint64_t id) {
MutexAutoLock lock(mLock);
mRealChannels.Remove(id);

View File

@@ -33,13 +33,12 @@ class RedirectChannelRegistrar final : public nsIRedirectChannelRegistrar {
static void Shutdown();
protected:
typedef nsInterfaceHashtable<nsUint32HashKey, nsIChannel> ChannelHashtable;
typedef nsInterfaceHashtable<nsUint32HashKey, nsIParentChannel>
ParentChannelHashtable;
using ChannelHashtable = nsInterfaceHashtable<nsUint64HashKey, nsIChannel>;
using ParentChannelHashtable =
nsInterfaceHashtable<nsUint64HashKey, nsIParentChannel>;
ChannelHashtable mRealChannels;
ParentChannelHashtable mParentChannels;
uint32_t mId;
Mutex mLock;
static StaticRefPtr<RedirectChannelRegistrar> gSingleton;

View File

@@ -14,10 +14,10 @@ namespace net {
NS_IMPL_ISUPPORTS(SimpleChannelParent, nsIParentChannel, nsIStreamListener)
bool SimpleChannelParent::Init(const uint32_t& channelId) {
bool SimpleChannelParent::Init(const uint64_t& aChannelId) {
nsCOMPtr<nsIChannel> channel;
MOZ_ALWAYS_SUCCEEDS(
NS_LinkRedirectChannels(channelId, this, getter_AddRefs(channel)));
NS_LinkRedirectChannels(aChannelId, this, getter_AddRefs(channel)));
return true;
}

View File

@@ -26,7 +26,7 @@ class SimpleChannelParent : public nsIParentChannel,
NS_DECL_NSIREQUESTOBSERVER
NS_DECL_NSISTREAMLISTENER; // semicolon for clang-format bug 1629756
[[nodiscard]] bool Init(const uint32_t& aArgs);
[[nodiscard]] bool Init(const uint64_t& aChannelId);
private:
~SimpleChannelParent() = default;

View File

@@ -19,13 +19,13 @@ interface nsIParentChannel;
interface nsIRedirectChannelRegistrar : nsISupports
{
/**
* Register the redirect target channel and obtain a unique ID for that
* channel.
* Register the redirect target channel. The passed id needs to be a
* unique ID for that channel (see `nsContentUtils::GenerateLoadIdentifier`).
*
* Primarily used in ParentChannelListener::AsyncOnChannelRedirect to get
* a channel id sent to the HttpChannelChild being redirected.
*/
uint32_t registerChannel(in nsIChannel channel);
void registerChannel(in nsIChannel channel, in uint64_t id);
/**
* First, search for the channel registered under the id. If found return
@@ -38,7 +38,7 @@ interface nsIRedirectChannelRegistrar : nsISupports
* in reaction to nsIChildChannel.connectParent(id) called from the child
* process.
*/
nsIChannel linkChannels(in uint32_t id, in nsIParentChannel channel);
nsIChannel linkChannels(in uint64_t id, in nsIParentChannel channel);
/**
* Returns back the channel previously registered under the ID with
@@ -47,7 +47,7 @@ interface nsIRedirectChannelRegistrar : nsISupports
* Primarilly used in chrome IPC side of protocols when attaching a redirect
* target channel to an existing 'real' channel implementation.
*/
nsIChannel getRegisteredChannel(in uint32_t id);
nsIChannel getRegisteredChannel(in uint64_t id);
/**
* Returns the stream listener that shall be attached to the redirect target
@@ -58,7 +58,7 @@ interface nsIRedirectChannelRegistrar : nsISupports
* to grab the created parent side of the channel and forward notifications
* to it.
*/
nsIParentChannel getParentChannel(in uint32_t id);
nsIParentChannel getParentChannel(in uint64_t id);
/**
* To not force all channel implementations to support weak reference
@@ -68,5 +68,5 @@ interface nsIRedirectChannelRegistrar : nsISupports
*
* Primarilly used in ParentChannelListener::OnRedirectResult callback.
*/
void deregisterChannels(in uint32_t id);
void deregisterChannels(in uint64_t id);
};

View File

@@ -2527,7 +2527,7 @@ bool NS_IsHSTSUpgradeRedirect(nsIChannel* aOldChannel, nsIChannel* aNewChannel,
return NS_SUCCEEDED(upgradedURI->Equals(newURI, &res)) && res;
}
nsresult NS_LinkRedirectChannels(uint32_t channelId,
nsresult NS_LinkRedirectChannels(uint64_t channelId,
nsIParentChannel* parentChannel,
nsIChannel** _result) {
nsCOMPtr<nsIRedirectChannelRegistrar> registrar =

View File

@@ -771,7 +771,7 @@ bool NS_IsInternalSameURIRedirect(nsIChannel* aOldChannel,
bool NS_IsHSTSUpgradeRedirect(nsIChannel* aOldChannel, nsIChannel* aNewChannel,
uint32_t aFlags);
nsresult NS_LinkRedirectChannels(uint32_t channelId,
nsresult NS_LinkRedirectChannels(uint64_t channelId,
nsIParentChannel* parentChannel,
nsIChannel** _result);

View File

@@ -540,8 +540,7 @@ auto DocumentLoadListener::Open(
/* static */
bool DocumentLoadListener::OpenFromParent(
dom::CanonicalBrowsingContext* aBrowsingContext,
nsDocShellLoadState* aLoadState, uint64_t aOuterWindowId,
uint32_t* aOutIdent) {
nsDocShellLoadState* aLoadState, uint64_t aOuterWindowId, uint64_t* aOutIdent) {
LOG(("DocumentLoadListener::OpenFromParent"));
// We currently only support passing nullptr for aLoadInfo for
@@ -616,16 +615,18 @@ bool DocumentLoadListener::OpenFromParent(
// allocate an identifier for this load.
nsCOMPtr<nsIRedirectChannelRegistrar> registrar =
RedirectChannelRegistrar::GetOrCreate();
rv = registrar->RegisterChannel(nullptr, aOutIdent);
uint64_t loadIdentifier = aLoadState->GetLoadIdentifier();
*aOutIdent = loadIdentifier;
rv = registrar->RegisterChannel(nullptr, loadIdentifier);
MOZ_ASSERT(NS_SUCCEEDED(rv));
// Register listener (as an nsIParentChannel) under our new identifier.
rv = registrar->LinkChannels(*aOutIdent, listener, nullptr);
rv = registrar->LinkChannels(loadIdentifier, listener, nullptr);
MOZ_ASSERT(NS_SUCCEEDED(rv));
}
return !!promise;
}
void DocumentLoadListener::CleanupParentLoadAttempt(uint32_t aLoadIdent) {
void DocumentLoadListener::CleanupParentLoadAttempt(uint64_t aLoadIdent) {
nsCOMPtr<nsIRedirectChannelRegistrar> registrar =
RedirectChannelRegistrar::GetOrCreate();
@@ -643,7 +644,7 @@ void DocumentLoadListener::CleanupParentLoadAttempt(uint32_t aLoadIdent) {
}
auto DocumentLoadListener::ClaimParentLoad(DocumentLoadListener** aListener,
uint32_t aLoadIdent)
uint64_t aLoadIdent)
-> RefPtr<OpenPromise> {
nsCOMPtr<nsIRedirectChannelRegistrar> registrar =
RedirectChannelRegistrar::GetOrCreate();
@@ -1369,8 +1370,9 @@ DocumentLoadListener::RedirectToRealChannel(
nsCOMPtr<nsIRedirectChannelRegistrar> registrar =
RedirectChannelRegistrar::GetOrCreate();
MOZ_ASSERT(registrar);
mRedirectChannelId = nsContentUtils::GenerateLoadIdentifier();
MOZ_ALWAYS_SUCCEEDS(
registrar->RegisterChannel(mChannel, &mRedirectChannelId));
registrar->RegisterChannel(mChannel, mRedirectChannelId));
if (aDestinationProcess) {
dom::ContentParent* cp =

View File

@@ -137,16 +137,16 @@ class DocumentLoadListener : public nsIInterfaceRequestor,
// and clean up.
static bool OpenFromParent(dom::CanonicalBrowsingContext* aBrowsingContext,
nsDocShellLoadState* aLoadState,
uint64_t aOuterWindowId, uint32_t* aOutIdent);
uint64_t aOuterWindowId, uint64_t* aOutIdent);
// Ensures that a load identifier allocated by OpenFromParent has
// been deregistered if it hasn't already been claimed.
// This also cancels the load.
static void CleanupParentLoadAttempt(uint32_t aLoadIdent);
static void CleanupParentLoadAttempt(uint64_t aLoadIdent);
// Looks up aLoadIdent to find the associated, cleans up the registration
static RefPtr<OpenPromise> ClaimParentLoad(DocumentLoadListener** aListener,
uint32_t aLoadIdent);
uint64_t aLoadIdent);
// Called by the DocumentChannelParent if actor got destroyed or the parent
// channel got deleted.
@@ -415,7 +415,7 @@ class DocumentLoadListener : public nsIInterfaceRequestor,
// Corresponding redirect channel registrar Id for the final channel that
// we want to use when redirecting the child, or doing a process switch.
// 0 means redirection is not started.
uint32_t mRedirectChannelId = 0;
uint64_t mRedirectChannelId = 0;
// Set to true once we initiate the redirect to a real channel (either
// via a process switch or a same-process redirect, and Suspend the
// underlying channel.

View File

@@ -14,10 +14,10 @@ namespace net {
NS_IMPL_ISUPPORTS(DataChannelParent, nsIParentChannel, nsIStreamListener)
bool DataChannelParent::Init(const uint32_t& channelId) {
bool DataChannelParent::Init(const uint64_t& aChannelId) {
nsCOMPtr<nsIChannel> channel;
MOZ_ALWAYS_SUCCEEDS(
NS_LinkRedirectChannels(channelId, this, getter_AddRefs(channel)));
NS_LinkRedirectChannels(aChannelId, this, getter_AddRefs(channel)));
return true;
}

View File

@@ -26,7 +26,7 @@ class DataChannelParent : public nsIParentChannel, public PDataChannelParent {
NS_DECL_NSISTREAMLISTENER
[[nodiscard]] bool
Init(const uint32_t& aArgs);
Init(const uint64_t& aChannelId);
private:
~DataChannelParent() = default;

View File

@@ -14,10 +14,10 @@ namespace net {
NS_IMPL_ISUPPORTS(FileChannelParent, nsIParentChannel, nsIStreamListener)
bool FileChannelParent::Init(const uint32_t& channelId) {
bool FileChannelParent::Init(const uint64_t& aChannelId) {
nsCOMPtr<nsIChannel> channel;
MOZ_ALWAYS_SUCCEEDS(
NS_LinkRedirectChannels(channelId, this, getter_AddRefs(channel)));
NS_LinkRedirectChannels(aChannelId, this, getter_AddRefs(channel)));
return true;
}

View File

@@ -26,7 +26,7 @@ class FileChannelParent : public nsIParentChannel, public PFileChannelParent {
NS_DECL_NSISTREAMLISTENER
[[nodiscard]] bool
Init(const uint32_t& aArgs);
Init(const uint64_t& aChannelId);
private:
~FileChannelParent() = default;

View File

@@ -165,10 +165,11 @@ bool FTPChannelParent::DoAsyncOpen(const URIParams& aURI,
return true;
}
bool FTPChannelParent::ConnectChannel(const uint32_t& channelId) {
bool FTPChannelParent::ConnectChannel(const uint64_t& channelId) {
nsresult rv;
LOG(("Looking for a registered channel [this=%p, id=%d]", this, channelId));
LOG(("Looking for a registered channel [this=%p, id=%" PRIx64 "]", this,
channelId));
nsCOMPtr<nsIChannel> channel;
rv = NS_LinkRedirectChannels(channelId, this, getter_AddRefs(channel));

View File

@@ -82,7 +82,7 @@ class FTPChannelParent final : public PFTPChannelParent,
// used to connect redirected-to channel in parent with just created
// ChildChannel. Used during HTTP->FTP redirects.
bool ConnectChannel(const uint32_t& channelId);
bool ConnectChannel(const uint64_t& channelId);
void DivertOnDataAvailable(const nsCString& data, const uint64_t& offset,
const uint32_t& count);

View File

@@ -1994,10 +1994,12 @@ HttpChannelParent::StartRedirect(nsIChannel* newChannel, uint32_t redirectFlags,
RedirectChannelRegistrar::GetOrCreate();
MOZ_ASSERT(registrar);
rv = registrar->RegisterChannel(newChannel, &mRedirectChannelId);
mRedirectChannelId = nsContentUtils::GenerateLoadIdentifier();
rv = registrar->RegisterChannel(newChannel, mRedirectChannelId);
NS_ENSURE_SUCCESS(rv, rv);
LOG(("Registered %p channel under id=%d", newChannel, mRedirectChannelId));
LOG(("Registered %p channel under id=%" PRIx64, newChannel,
mRedirectChannelId));
if (mIPCClosed) {
return NS_BINDING_ABORTED;
@@ -2588,7 +2590,7 @@ HttpChannelParent::OnRedirectResult(bool succeeded) {
getter_AddRefs(redirectChannel));
if (NS_FAILED(rv) || !redirectChannel) {
// Redirect might get canceled before we got AsyncOnChannelRedirect
LOG(("Registered parent channel not found under id=%d",
LOG(("Registered parent channel not found under id=%" PRIx64,
mRedirectChannelId));
nsCOMPtr<nsIChannel> newChannel;

View File

@@ -309,7 +309,7 @@ class HttpChannelParent final : public nsIInterfaceRequestor,
// Corresponding redirect channel registrar Id. 0 means redirection is not
// started.
uint32_t mRedirectChannelId = 0;
uint64_t mRedirectChannelId = 0;
PBOverrideStatus mPBOverride;