Index: trace_event/memory_dump_manager.cc |
diff --git a/trace_event/memory_dump_manager.cc b/trace_event/memory_dump_manager.cc |
index 6c13179f18952106a1d44f59b1cb115e6ba5537e..6d4658462c228b30cddf5737bab6d69b70574581 100644 |
--- a/trace_event/memory_dump_manager.cc |
+++ b/trace_event/memory_dump_manager.cc |
@@ -93,12 +93,12 @@ void MemoryDumpManager::SetInstanceForTesting(MemoryDumpManager* instance) { |
} |
MemoryDumpManager::MemoryDumpManager() |
- : did_unregister_dump_provider_(false), |
- delegate_(nullptr), |
+ : delegate_(nullptr), |
memory_tracing_enabled_(0), |
tracing_process_id_(kInvalidTracingProcessId), |
system_allocator_pool_name_(nullptr), |
- skip_core_dumpers_auto_registration_for_testing_(false) { |
+ skip_core_dumpers_auto_registration_for_testing_(false), |
+ disable_periodic_dumps_for_testing_(false) { |
g_next_guid.GetNext(); // Make sure that first guid is not zero. |
} |
@@ -152,7 +152,16 @@ void MemoryDumpManager::RegisterDumpProvider( |
const scoped_refptr<SingleThreadTaskRunner>& task_runner) { |
MemoryDumpProviderInfo mdp_info(mdp, task_runner); |
AutoLock lock(lock_); |
- dump_providers_.insert(mdp_info); |
+ auto iter_new = dump_providers_.insert(mdp_info); |
+ |
+ // If there was a previous entry, replace it with the new one. This is to deal |
+ // with the case where a dump provider unregisters itself and then re- |
+ // registers before a memory dump happens, so its entry was still in the |
+ // collection but flagged |unregistered|. |
+ if (!iter_new.second) { |
+ dump_providers_.erase(iter_new.first); |
+ dump_providers_.insert(mdp_info); |
+ } |
} |
void MemoryDumpManager::RegisterDumpProvider(MemoryDumpProvider* mdp) { |
@@ -183,8 +192,7 @@ void MemoryDumpManager::UnregisterDumpProvider(MemoryDumpProvider* mdp) { |
<< "The MemoryDumpProvider attempted to unregister itself in a racy way. " |
<< "Please file a crbug."; |
- dump_providers_.erase(mdp_iter); |
- did_unregister_dump_provider_ = true; |
+ mdp_iter->unregistered = true; |
} |
void MemoryDumpManager::RequestGlobalDump(MemoryDumpType dump_type, |
@@ -228,7 +236,6 @@ void MemoryDumpManager::CreateProcessDump(const MemoryDumpRequestArgs& args, |
scoped_ptr<ProcessMemoryDumpAsyncState> pmd_async_state; |
{ |
AutoLock lock(lock_); |
- did_unregister_dump_provider_ = false; |
pmd_async_state.reset(new ProcessMemoryDumpAsyncState( |
args, dump_providers_.begin(), session_state_, callback)); |
} |
@@ -268,18 +275,10 @@ void MemoryDumpManager::ContinueAsyncProcessDump( |
bool skip_dump = false; |
{ |
AutoLock lock(lock_); |
- // In the unlikely event that a dump provider was unregistered while |
- // dumping, abort the dump, as that would make |next_dump_provider| invalid. |
- // Registration, on the other hand, is safe as per std::set<> contract. |
- if (did_unregister_dump_provider_) { |
- return AbortDumpLocked(pmd_async_state->callback, |
- pmd_async_state->task_runner, |
- pmd_async_state->req_args.dump_guid); |
- } |
- auto* mdp_info = &*pmd_async_state->next_dump_provider; |
+ auto mdp_info = pmd_async_state->next_dump_provider; |
mdp = mdp_info->dump_provider; |
- if (mdp_info->disabled) { |
+ if (mdp_info->disabled || mdp_info->unregistered) { |
skip_dump = true; |
} else if (mdp_info->task_runner && |
!mdp_info->task_runner->BelongsToCurrentThread()) { |
@@ -318,12 +317,7 @@ void MemoryDumpManager::ContinueAsyncProcessDump( |
{ |
AutoLock lock(lock_); |
- if (did_unregister_dump_provider_) { |
- return AbortDumpLocked(pmd_async_state->callback, |
- pmd_async_state->task_runner, |
- pmd_async_state->req_args.dump_guid); |
- } |
- auto* mdp_info = &*pmd_async_state->next_dump_provider; |
+ auto mdp_info = pmd_async_state->next_dump_provider; |
if (dump_successful) { |
mdp_info->consecutive_failures = 0; |
} else if (!skip_dump) { |
@@ -334,6 +328,9 @@ void MemoryDumpManager::ContinueAsyncProcessDump( |
} |
++pmd_async_state->next_dump_provider; |
finalize = pmd_async_state->next_dump_provider == dump_providers_.end(); |
+ |
+ if (mdp_info->unregistered) |
+ dump_providers_.erase(mdp_info); |
} |
if (!skip_dump && !dump_successful) { |
@@ -427,9 +424,11 @@ void MemoryDumpManager::OnTraceLogEnabled() { |
// TODO(primiano): This is a temporary hack to disable periodic memory dumps |
// when running memory benchmarks until they can be enabled/disabled in |
// base::trace_event::TraceConfig. See https://goo.gl/5Hj3o0. |
+ // The same mechanism should be used to disable periodic dumps in tests. |
if (delegate_->IsCoordinatorProcess() && |
!CommandLine::ForCurrentProcess()->HasSwitch( |
- "enable-memory-benchmarking")) { |
+ "enable-memory-benchmarking") && |
+ !disable_periodic_dumps_for_testing_) { |
g_periodic_dumps_count = 0; |
periodic_dump_timer_.Start(FROM_HERE, |
TimeDelta::FromMilliseconds(kDumpIntervalMs), |
@@ -454,7 +453,8 @@ MemoryDumpManager::MemoryDumpProviderInfo::MemoryDumpProviderInfo( |
: dump_provider(dump_provider), |
task_runner(task_runner), |
consecutive_failures(0), |
- disabled(false) {} |
+ disabled(false), |
+ unregistered(false) {} |
MemoryDumpManager::MemoryDumpProviderInfo::~MemoryDumpProviderInfo() { |
} |