Bug 1510262 - nsIncrementalDownload causes a lot of jank with main thread I/O while downloading updates in the background r=necko-reviewers,valentin

Retargeting OnDataAvailable to STS to avoid main thread jank during downloads.

Differential Revision: https://phabricator.services.mozilla.com/D211431
This commit is contained in:
Andrew Creskey 2024-05-23 23:08:53 +00:00
parent 782dc636d1
commit 141cda749f

View file

@ -17,6 +17,8 @@
#include "nsIObserverService.h"
#include "nsIObserver.h"
#include "nsIStreamListener.h"
#include "nsIThreadRetargetableRequest.h"
#include "nsIThreadRetargetableStreamListener.h"
#include "nsIFile.h"
#include "nsIHttpChannel.h"
#include "nsITimer.h"
@ -91,18 +93,19 @@ static void MakeRangeSpec(const int64_t& size, const int64_t& maxSize,
//-----------------------------------------------------------------------------
class nsIncrementalDownload final : public nsIIncrementalDownload,
public nsIStreamListener,
public nsIThreadRetargetableStreamListener,
public nsIObserver,
public nsIInterfaceRequestor,
public nsIChannelEventSink,
public nsSupportsWeakReference,
public nsIAsyncVerifyRedirectCallback {
public:
NS_DECL_ISUPPORTS
NS_DECL_THREADSAFE_ISUPPORTS
NS_DECL_NSISTREAMLISTENER
NS_DECL_NSITHREADRETARGETABLESTREAMLISTENER
NS_DECL_NSIREQUEST
NS_DECL_NSIINCREMENTALDOWNLOAD
NS_DECL_NSIREQUESTOBSERVER
NS_DECL_NSISTREAMLISTENER
NS_DECL_NSIOBSERVER
NS_DECL_NSIINTERFACEREQUESTOR
NS_DECL_NSICHANNELEVENTSINK
@ -303,11 +306,11 @@ nsresult nsIncrementalDownload::ReadCurrentSize() {
}
// nsISupports
NS_IMPL_ISUPPORTS(nsIncrementalDownload, nsIIncrementalDownload, nsIRequest,
nsIStreamListener, nsIRequestObserver, nsIObserver,
nsIInterfaceRequestor, nsIChannelEventSink,
nsISupportsWeakReference, nsIAsyncVerifyRedirectCallback)
nsIStreamListener, nsIThreadRetargetableStreamListener,
nsIRequestObserver, nsIObserver, nsIInterfaceRequestor,
nsIChannelEventSink, nsISupportsWeakReference,
nsIAsyncVerifyRedirectCallback)
// nsIRequest
@ -493,10 +496,10 @@ nsIncrementalDownload::Start(nsIRequestObserver* observer,
// nsIRequestObserver
NS_IMETHODIMP
nsIncrementalDownload::OnStartRequest(nsIRequest* request) {
nsIncrementalDownload::OnStartRequest(nsIRequest* aRequest) {
nsresult rv;
nsCOMPtr<nsIHttpChannel> http = do_QueryInterface(request, &rv);
nsCOMPtr<nsIHttpChannel> http = do_QueryInterface(aRequest, &rv);
if (NS_FAILED(rv)) return rv;
// Ensure that we are receiving a 206 response.
@ -663,9 +666,23 @@ nsIncrementalDownload::OnStartRequest(nsIRequest* request) {
mChunk = mozilla::MakeUniqueFallible<char[]>(mChunkSize);
if (!mChunk) rv = NS_ERROR_OUT_OF_MEMORY;
if (nsCOMPtr<nsIThreadRetargetableRequest> rr = do_QueryInterface(aRequest)) {
nsCOMPtr<nsIEventTarget> sts =
do_GetService(NS_STREAMTRANSPORTSERVICE_CONTRACTID);
RefPtr queue =
TaskQueue::Create(sts.forget(), "nsIncrementalDownload Delivery Queue");
LOG(
("nsIncrementalDownload::OnStartRequest\n"
" Retarget to stream transport service\n"));
rr->RetargetDeliveryTo(queue);
}
return rv;
}
NS_IMETHODIMP
nsIncrementalDownload::CheckListenerChain() { return NS_OK; }
NS_IMETHODIMP
nsIncrementalDownload::OnStopRequest(nsIRequest* request, nsresult status) {
// Not a real error; just a trick to kill off the channel without our
@ -697,7 +714,6 @@ nsIncrementalDownload::OnStopRequest(nsIRequest* request, nsresult status) {
}
// nsIStreamListener
NS_IMETHODIMP
nsIncrementalDownload::OnDataAvailable(nsIRequest* request,
nsIInputStream* input, uint64_t offset,
@ -720,12 +736,20 @@ nsIncrementalDownload::OnDataAvailable(nsIRequest* request,
}
if (PR_Now() > mLastProgressUpdate + UPDATE_PROGRESS_INTERVAL) {
UpdateProgress();
if (NS_IsMainThread()) {
UpdateProgress();
} else {
NS_DispatchToMainThread(
NewRunnableMethod("nsIncrementalDownload::UpdateProgress", this,
&nsIncrementalDownload::UpdateProgress));
}
}
return NS_OK;
}
NS_IMETHODIMP
nsIncrementalDownload::OnDataFinished(nsresult aStatus) { return NS_OK; }
// nsIObserver
NS_IMETHODIMP