Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(431)

Side by Side Diff: chrome/browser/profiles/profile_destroyer.cc

Issue 653633004: Shutdown Service Workers before the profile is destroyed (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 6 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/profiles/profile_destroyer.h" 5 #include "chrome/browser/profiles/profile_destroyer.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/debug/trace_event.h" 8 #include "base/debug/trace_event.h"
9 #include "base/memory/scoped_ptr.h" 9 #include "base/memory/scoped_ptr.h"
10 #include "base/message_loop/message_loop.h" 10 #include "base/message_loop/message_loop.h"
11 #include "chrome/browser/profiles/profile.h" 11 #include "chrome/browser/profiles/profile.h"
12 #include "content/public/browser/render_process_host.h" 12 #include "content/public/browser/render_process_host.h"
13 #include "content/public/browser/service_worker_context.h"
14 #include "content/public/browser/storage_partition.h"
13 15
14 namespace { 16 namespace {
15 17
16 #if defined(OS_ANDROID) 18 #if defined(OS_ANDROID)
17 // Set the render host waiting time to 5s on Android, that's the same 19 // Set the render host waiting time to 5s on Android, that's the same
18 // as an "Application Not Responding" timeout. 20 // as an "Application Not Responding" timeout.
19 const int64 kTimerDelaySeconds = 5; 21 const int64 kTimerDelaySeconds = 5;
20 #else 22 #else
21 const int64 kTimerDelaySeconds = 1; 23 const int64 kTimerDelaySeconds = 1;
22 #endif 24 #endif
23 25
24 } // namespace 26 } // namespace
25 27
26 ProfileDestroyer::DestroyerSet* ProfileDestroyer::pending_destroyers_ = NULL; 28 ProfileDestroyer::DestroyerSet* ProfileDestroyer::pending_destroyers_ = NULL;
27 29
30 static void ShutdownServiceWorkerContext(content::StoragePartition* partition) {
31 partition->GetServiceWorkerContext()->Terminate();
32 }
33
28 // static 34 // static
29 void ProfileDestroyer::DestroyProfileWhenAppropriate(Profile* const profile) { 35 void ProfileDestroyer::DestroyProfileWhenAppropriate(Profile* const profile) {
30 TRACE_EVENT0("shutdown", "ProfileDestroyer::DestroyProfileWhenAppropriate"); 36 TRACE_EVENT0("shutdown", "ProfileDestroyer::DestroyProfileWhenAppropriate");
31 37
32 DCHECK(profile); 38 DCHECK(profile);
33 profile->MaybeSendDestroyedNotification(); 39 profile->MaybeSendDestroyedNotification();
34 40
41 // Service Workers must shutdown before the profile is destroyed, since they
42 // keep render process hosts alive and code assumes that render process hosts
43 // die before the profile dies.
44 content::BrowserContext::ForEachStoragePartition(
45 profile, base::Bind(ShutdownServiceWorkerContext));
falken 2014/10/21 09:36:36 I'm not sure all codepaths that destroy a Profile
michaeln 2014/10/21 23:24:13 Profile::MaybeSendDestroyedNotification() could ca
falken 2014/10/22 01:27:12 That sounds promising and more bulletproof than ho
46
35 HostSet hosts; 47 HostSet hosts;
36 // Testing profiles can simply be deleted directly. Some tests don't setup 48 // Testing profiles can simply be deleted directly. Some tests don't setup
37 // RenderProcessHost correctly and don't necessary run on the UI thread 49 // RenderProcessHost correctly and don't necessary run on the UI thread
38 // anyway, so we can't use the AllHostIterator. 50 // anyway, so we can't use the AllHostIterator.
39 if (profile->AsTestingProfile() == NULL) { 51 if (profile->AsTestingProfile() == NULL) {
40 GetHostsForProfile(profile, &hosts); 52 GetHostsForProfile(profile, &hosts);
41 if (!profile->IsOffTheRecord() && profile->HasOffTheRecordProfile()) 53 if (!profile->IsOffTheRecord() && profile->HasOffTheRecordProfile())
42 GetHostsForProfile(profile->GetOffTheRecordProfile(), &hosts); 54 GetHostsForProfile(profile->GetOffTheRecordProfile(), &hosts);
43 } 55 }
44 // Generally, !hosts.empty() means that there is a leak in a render process 56 // Generally, !hosts.empty() means that there is a leak in a render process
45 // host that MUST BE FIXED!!! 57 // host that MUST BE FIXED!!!
46 // 58 //
47 // However, off-the-record profiles are destroyed before their 59 // However, off-the-record profiles are destroyed before their
48 // RenderProcessHosts in order to erase private data quickly, and 60 // RenderProcessHosts in order to erase private data quickly, and
falken 2014/10/21 09:36:35 This comment is a bit sketchy, it seems to contrad
49 // RenderProcessHostImpl::Release() avoids destroying RenderProcessHosts in 61 // RenderProcessHostImpl::Release() avoids destroying RenderProcessHosts in
50 // --single-process mode to avoid race conditions. 62 // --single-process mode to avoid race conditions.
51 DCHECK(hosts.empty() || profile->IsOffTheRecord() || 63 DCHECK(hosts.empty() || profile->IsOffTheRecord() ||
52 content::RenderProcessHost::run_renderer_in_process()) << \ 64 content::RenderProcessHost::run_renderer_in_process()) << \
53 "Profile still has " << hosts.size() << " hosts"; 65 "Profile still has " << hosts.size() << " hosts";
54 // Note that we still test for !profile->IsOffTheRecord here even though we 66 // Note that we still test for !profile->IsOffTheRecord here even though we
55 // DCHECK'd above because we want to protect Release builds against this even 67 // DCHECK'd above because we want to protect Release builds against this even
56 // we need to identify if there are leaks when we run Debug builds. 68 // we need to identify if there are leaks when we run Debug builds.
57 if (hosts.empty() || !profile->IsOffTheRecord()) { 69 if (hosts.empty() || !profile->IsOffTheRecord()) {
58 if (profile->IsOffTheRecord()) 70 if (profile->IsOffTheRecord())
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after
173 content::RenderProcessHost::AllHostsIterator()); 185 content::RenderProcessHost::AllHostsIterator());
174 !iter.IsAtEnd(); iter.Advance()) { 186 !iter.IsAtEnd(); iter.Advance()) {
175 content::RenderProcessHost* render_process_host = iter.GetCurrentValue(); 187 content::RenderProcessHost* render_process_host = iter.GetCurrentValue();
176 if (render_process_host && 188 if (render_process_host &&
177 render_process_host->GetBrowserContext() == profile) { 189 render_process_host->GetBrowserContext() == profile) {
178 hosts->insert(render_process_host); 190 hosts->insert(render_process_host);
179 } 191 }
180 } 192 }
181 return !hosts->empty(); 193 return !hosts->empty();
182 } 194 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698