forked from mirrors/gecko-dev
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:
parent
782dc636d1
commit
141cda749f
1 changed files with 36 additions and 12 deletions
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Reference in a new issue