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
	
	 Andrew Creskey
						Andrew Creskey