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, |