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