зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1658202 - move flushes caused by closing the stream away from the main thread, r=valentin
Depends on D88730 Differential Revision: https://phabricator.services.mozilla.com/D88731
This commit is contained in:
Родитель
dd70279b17
Коммит
58651be5dd
|
@ -889,8 +889,34 @@ NS_IMETHODIMP nsWebBrowserPersist::OnStopRequest(nsIRequest* request,
|
|||
SendErrorStatusChange(true, status, request, data->mFile);
|
||||
}
|
||||
|
||||
// If there is a stream ref and we weren't canceled,
|
||||
// close it away from the main thread.
|
||||
// We don't do this when there's an error/cancelation,
|
||||
// because our consumer may try to delete the file, which will error
|
||||
// if we're still holding on to it, so we have to close it pronto.
|
||||
{
|
||||
MutexAutoLock lock(data->mStreamMutex);
|
||||
if (data->mStream && NS_SUCCEEDED(status) && !mCancel) {
|
||||
if (!mBackgroundQueue) {
|
||||
nsresult rv = NS_CreateBackgroundTaskQueue(
|
||||
"WebBrowserPersist", getter_AddRefs(mBackgroundQueue));
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
// Now steal the stream ref and close it away from the main thread,
|
||||
// keeping the promise around so we don't finish before all files
|
||||
// are flushed and closed.
|
||||
mFileClosePromises.AppendElement(InvokeAsync(
|
||||
mBackgroundQueue, __func__, [stream = std::move(data->mStream)]() {
|
||||
nsresult rv = stream->Close();
|
||||
// We don't care if closing failed; we don't care in the
|
||||
// destructor either...
|
||||
return ClosePromise::CreateAndResolve(rv, __func__);
|
||||
}));
|
||||
}
|
||||
}
|
||||
MutexAutoLock lock(mOutputMapMutex);
|
||||
// This will automatically close the output stream
|
||||
mOutputMap.Remove(keyPtr);
|
||||
} else {
|
||||
// if we didn't find the data in mOutputMap, try mUploadList
|
||||
|
@ -2275,7 +2301,14 @@ void nsWebBrowserPersist::EndDownload(nsresult aResult) {
|
|||
if (NS_SUCCEEDED(mPersistResult) && NS_FAILED(aResult)) {
|
||||
mPersistResult = aResult;
|
||||
}
|
||||
ClosePromise::All(GetCurrentSerialEventTarget(), mFileClosePromises)
|
||||
->Then(GetCurrentSerialEventTarget(), __func__,
|
||||
[self = RefPtr{this}, aResult]() {
|
||||
self->EndDownloadInternal(aResult);
|
||||
});
|
||||
}
|
||||
|
||||
void nsWebBrowserPersist::EndDownloadInternal(nsresult aResult) {
|
||||
// mCompleted needs to be set before issuing the stop notification.
|
||||
// (Bug 1224437)
|
||||
mCompleted = true;
|
||||
|
|
|
@ -31,6 +31,8 @@
|
|||
class nsIStorageStream;
|
||||
class nsIWebBrowserPersistDocument;
|
||||
|
||||
using ClosePromise = mozilla::MozPromise<nsresult, nsresult, true>;
|
||||
|
||||
class nsWebBrowserPersist final : public nsIInterfaceRequestor,
|
||||
public nsIWebBrowserPersist,
|
||||
public nsIStreamListener,
|
||||
|
@ -124,8 +126,9 @@ class nsWebBrowserPersist final : public nsIInterfaceRequestor,
|
|||
|
||||
nsresult FixRedirectedChannelEntry(nsIChannel* aNewChannel);
|
||||
|
||||
void EndDownload(nsresult aResult);
|
||||
void FinishDownload();
|
||||
void EndDownload(nsresult aResult);
|
||||
void EndDownloadInternal(nsresult aResult);
|
||||
void SerializeNextFile();
|
||||
void CalcTotalProgress();
|
||||
|
||||
|
@ -153,6 +156,7 @@ class nsWebBrowserPersist final : public nsIInterfaceRequestor,
|
|||
nsClassHashtable<nsISupportsHashKey, OutputData> mOutputMap;
|
||||
nsClassHashtable<nsISupportsHashKey, UploadData> mUploadList;
|
||||
nsCOMPtr<nsISerialEventTarget> mBackgroundQueue;
|
||||
nsTArray<RefPtr<ClosePromise>> mFileClosePromises;
|
||||
nsClassHashtable<nsCStringHashKey, URIData> mURIMap;
|
||||
nsCOMPtr<nsIWebBrowserPersistURIMap> mFlatURIMap;
|
||||
nsTArray<mozilla::UniquePtr<WalkData>> mWalkStack;
|
||||
|
|
|
@ -122,11 +122,6 @@ DownloadLegacyTransfer.prototype = {
|
|||
// Only cancel if the object executing the download is still running.
|
||||
if (this._cancelable && !this._componentFailed) {
|
||||
this._cancelable.cancel(Cr.NS_ERROR_ABORT);
|
||||
if (this._cancelable instanceof Ci.nsIWebBrowserPersist) {
|
||||
// This component will not send the STATE_STOP notification.
|
||||
download.saver.onTransferFinished(Cr.NS_ERROR_ABORT);
|
||||
this._cancelable = null;
|
||||
}
|
||||
}
|
||||
});
|
||||
})
|
||||
|
|
Загрузка…
Ссылка в новой задаче