зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1613873 - P4: Use nsInputStreamPump off main thread completely r=dragana
Differential Revision: https://phabricator.services.mozilla.com/D62919 --HG-- extra : moz-landing-system : lando
This commit is contained in:
Родитель
69329b4fc3
Коммит
e2cd8195a0
|
@ -49,6 +49,7 @@ nsInputStreamPump::nsInputStreamPump()
|
||||||
mCloseWhenDone(false),
|
mCloseWhenDone(false),
|
||||||
mRetargeting(false),
|
mRetargeting(false),
|
||||||
mAsyncStreamIsBuffered(false),
|
mAsyncStreamIsBuffered(false),
|
||||||
|
mOffMainThread(!NS_IsMainThread()),
|
||||||
mMutex("nsInputStreamPump") {}
|
mMutex("nsInputStreamPump") {}
|
||||||
|
|
||||||
nsresult nsInputStreamPump::Create(nsInputStreamPump** result,
|
nsresult nsInputStreamPump::Create(nsInputStreamPump** result,
|
||||||
|
@ -112,8 +113,9 @@ nsresult nsInputStreamPump::EnsureWaiting() {
|
||||||
// on only one thread at a time.
|
// on only one thread at a time.
|
||||||
MOZ_ASSERT(mAsyncStream);
|
MOZ_ASSERT(mAsyncStream);
|
||||||
if (!mWaitingForInputStreamReady && !mProcessingCallbacks) {
|
if (!mWaitingForInputStreamReady && !mProcessingCallbacks) {
|
||||||
// Ensure OnStateStop is called on the main thread.
|
// Ensure OnStateStop is called on the main thread only when this pump is
|
||||||
if (mState == STATE_STOP) {
|
// created on main thread.
|
||||||
|
if (mState == STATE_STOP && !mOffMainThread) {
|
||||||
nsCOMPtr<nsIEventTarget> mainThread =
|
nsCOMPtr<nsIEventTarget> mainThread =
|
||||||
mLabeledMainThreadTarget ? mLabeledMainThreadTarget
|
mLabeledMainThreadTarget ? mLabeledMainThreadTarget
|
||||||
: do_AddRef(GetMainThreadEventTarget());
|
: do_AddRef(GetMainThreadEventTarget());
|
||||||
|
@ -183,7 +185,13 @@ nsInputStreamPump::GetStatus(nsresult* status) {
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
nsInputStreamPump::Cancel(nsresult status) {
|
nsInputStreamPump::Cancel(nsresult status) {
|
||||||
|
#if DEBUG
|
||||||
|
if (mOffMainThread) {
|
||||||
|
MOZ_ASSERT_IF(mTargetThread, mTargetThread->IsOnCurrentThread());
|
||||||
|
} else {
|
||||||
MOZ_ASSERT(NS_IsMainThread());
|
MOZ_ASSERT(NS_IsMainThread());
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
RecursiveMutexAutoLock lock(mMutex);
|
RecursiveMutexAutoLock lock(mMutex);
|
||||||
|
|
||||||
|
@ -292,6 +300,12 @@ nsInputStreamPump::Init(nsIInputStream* stream, uint32_t segsize,
|
||||||
mSegCount = segcount;
|
mSegCount = segcount;
|
||||||
mCloseWhenDone = closeWhenDone;
|
mCloseWhenDone = closeWhenDone;
|
||||||
mLabeledMainThreadTarget = mainThreadTarget;
|
mLabeledMainThreadTarget = mainThreadTarget;
|
||||||
|
if (mOffMainThread && mLabeledMainThreadTarget) {
|
||||||
|
MOZ_ASSERT(
|
||||||
|
false,
|
||||||
|
"Init stream pump off main thread with a main thread event target.");
|
||||||
|
return NS_ERROR_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
@ -302,7 +316,7 @@ nsInputStreamPump::AsyncRead(nsIStreamListener* listener, nsISupports* ctxt) {
|
||||||
|
|
||||||
NS_ENSURE_TRUE(mState == STATE_IDLE, NS_ERROR_IN_PROGRESS);
|
NS_ENSURE_TRUE(mState == STATE_IDLE, NS_ERROR_IN_PROGRESS);
|
||||||
NS_ENSURE_ARG_POINTER(listener);
|
NS_ENSURE_ARG_POINTER(listener);
|
||||||
MOZ_ASSERT(NS_IsMainThread(),
|
MOZ_ASSERT(NS_IsMainThread() || mOffMainThread,
|
||||||
"nsInputStreamPump should be read from the "
|
"nsInputStreamPump should be read from the "
|
||||||
"main thread only.");
|
"main thread only.");
|
||||||
|
|
||||||
|
@ -441,7 +455,7 @@ nsInputStreamPump::OnInputStreamReady(nsIAsyncInputStream* stream) {
|
||||||
|
|
||||||
// Set mRetargeting so EnsureWaiting will be called. It ensures that
|
// Set mRetargeting so EnsureWaiting will be called. It ensures that
|
||||||
// OnStateStop is called on the main thread.
|
// OnStateStop is called on the main thread.
|
||||||
if (nextState == STATE_STOP && !NS_IsMainThread()) {
|
if (nextState == STATE_STOP && !NS_IsMainThread() && !mOffMainThread) {
|
||||||
mRetargeting = true;
|
mRetargeting = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -631,7 +645,7 @@ nsresult nsInputStreamPump::CallOnStateStop() {
|
||||||
uint32_t nsInputStreamPump::OnStateStop() {
|
uint32_t nsInputStreamPump::OnStateStop() {
|
||||||
mMutex.AssertCurrentThreadIn();
|
mMutex.AssertCurrentThreadIn();
|
||||||
|
|
||||||
if (!NS_IsMainThread()) {
|
if (!NS_IsMainThread() && !mOffMainThread) {
|
||||||
// This method can be called on a different thread if nsInputStreamPump
|
// This method can be called on a different thread if nsInputStreamPump
|
||||||
// is used off the main-thread.
|
// is used off the main-thread.
|
||||||
nsresult rv = mLabeledMainThreadTarget->Dispatch(
|
nsresult rv = mLabeledMainThreadTarget->Dispatch(
|
||||||
|
@ -726,6 +740,12 @@ nsInputStreamPump::RetargetDeliveryTo(nsIEventTarget* aNewTarget) {
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (mOffMainThread) {
|
||||||
|
// Don't support retargeting if this pump is already used off the main
|
||||||
|
// thread.
|
||||||
|
return NS_ERROR_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
// Ensure that |mListener| and any subsequent listeners can be retargeted
|
// Ensure that |mListener| and any subsequent listeners can be retargeted
|
||||||
// to another thread.
|
// to another thread.
|
||||||
nsresult rv = NS_OK;
|
nsresult rv = NS_OK;
|
||||||
|
|
|
@ -98,6 +98,9 @@ class nsInputStreamPump final : public nsIInputStreamPump,
|
||||||
bool mCloseWhenDone;
|
bool mCloseWhenDone;
|
||||||
bool mRetargeting;
|
bool mRetargeting;
|
||||||
bool mAsyncStreamIsBuffered;
|
bool mAsyncStreamIsBuffered;
|
||||||
|
// Indicate whether nsInputStreamPump is used completely off main thread.
|
||||||
|
// If true, OnStateStop() is executed off main thread.
|
||||||
|
bool mOffMainThread;
|
||||||
// Protects state/member var accesses across multiple threads.
|
// Protects state/member var accesses across multiple threads.
|
||||||
mozilla::RecursiveMutex mMutex;
|
mozilla::RecursiveMutex mMutex;
|
||||||
};
|
};
|
||||||
|
|
Загрузка…
Ссылка в новой задаче