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 "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
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue