Chromium Code Reviews| Index: content/browser/download/mhtml_generation_manager.cc |
| diff --git a/content/browser/download/mhtml_generation_manager.cc b/content/browser/download/mhtml_generation_manager.cc |
| index 60feca041a6491796bd906c67325edb11d6016e3..a5b14d8cc86cf0558bf5b735a35abfd44097d7f9 100644 |
| --- a/content/browser/download/mhtml_generation_manager.cc |
| +++ b/content/browser/download/mhtml_generation_manager.cc |
| @@ -75,6 +75,9 @@ class MHTMLGenerationManager::Job : public RenderProcessHostObserver { |
| int exit_code) override; |
| void RenderProcessHostDestroyed(RenderProcessHost* host) override; |
| + bool is_finished() const { return is_finished_; } |
| + void MarkAsFinished() { is_finished_ = true; } |
| + |
| private: |
| static int64_t CloseFileOnFileThread(base::File file); |
| void AddFrame(RenderFrameHost* render_frame_host); |
| @@ -119,6 +122,11 @@ class MHTMLGenerationManager::Job : public RenderProcessHostObserver { |
| // The callback to call once generation is complete. |
| const GenerateMHTMLCallback callback_; |
| + // Whether the job is finished (set to true only for the short duration of |
| + // time between MHTMLGenerationManager::JobFinished is called and the job is |
| + // destroyed by MHTMLGenerationManager::OnFileClosed). |
| + bool is_finished_; |
| + |
| // RAII helper for registering this Job as a RenderProcessHost observer. |
| ScopedObserver<RenderProcessHost, MHTMLGenerationManager::Job> |
| observed_renderer_process_host_; |
| @@ -136,6 +144,7 @@ MHTMLGenerationManager::Job::Job(int job_id, |
| mhtml_boundary_marker_(net::GenerateMimeMultipartBoundary()), |
| salt_(base::GenerateGUID()), |
| callback_(callback), |
| + is_finished_(false), |
| observed_renderer_process_host_(this) { |
| DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| web_contents->ForEachFrame(base::Bind( |
| @@ -388,10 +397,16 @@ void MHTMLGenerationManager::JobFinished(Job* job, JobStatus job_status) { |
| DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| DCHECK(job); |
| - job->CloseFile( |
| - base::Bind(&MHTMLGenerationManager::OnFileClosed, |
| - base::Unretained(this), // Safe b/c |this| is a singleton. |
| - job->id(), job_status)); |
| + // Make sure we gracefully handle the case when JobFinished is called twice |
| + // (i.e. once from OnSerializeAsMHTMLResponse and while the file is being |
| + // closed also called a second time from RenderProcessExited). |
| + if (!job->is_finished()) { // Is this the first time JobFinished is called? |
| + job->MarkAsFinished(); |
|
dewittj
2016/07/20 16:37:48
May want to clear |job|'s |observed_renderer_proce
Randy Smith (Not in Mondays)
2016/07/20 16:46:58
This is a good point, but wouldn't this solve this
Łukasz Anforowicz
2016/07/20 21:10:07
Done. Good point.
Randy Smith (Not in Mondays)
2016/07/20 22:47:49
Sure, that sounds good. Thanks for thinking the i
|
| + job->CloseFile( |
| + base::Bind(&MHTMLGenerationManager::OnFileClosed, |
| + base::Unretained(this), // Safe b/c |this| is a singleton. |
| + job->id(), job_status)); |
| + } |
| } |
| void MHTMLGenerationManager::OnFileClosed(int job_id, |