Commit 615510b0 authored by dalecurtis's avatar dalecurtis Committed by Commit bot

Update last audio tick time during suspend and resume.

If someone suspends their computer and resumes more than a minute
later, the browser io thread may tick before the audio thread can
update the last tick time ==> crash :(

The solution is to disable hang detection during suspend and only
reenable it once resume completes; at which point we can update
the tick count. If we're actually hung, we'll crash after the next
interval elapses.

BUG=471046
TEST=none

Review URL: https://codereview.chromium.org/1036933003

Cr-Commit-Position: refs/heads/master@{#322509}
parent 3c7961f3
......@@ -9,6 +9,7 @@
#include "base/lazy_instance.h"
#include "base/logging.h"
#include "base/message_loop/message_loop.h"
#include "base/power_monitor/power_monitor.h"
#include "build/build_config.h"
#include "media/audio/fake_audio_log_factory.h"
......@@ -19,24 +20,46 @@ AudioManager* g_last_created = NULL;
// Helper class for managing global AudioManager data and hang timers. If the
// audio thread is unresponsive for more than a minute we want to crash the
// process so we can catch offenders quickly in the field.
class AudioManagerHelper {
class AudioManagerHelper : public base::PowerObserver {
public:
AudioManagerHelper() : max_hung_task_time_(base::TimeDelta::FromMinutes(1)) {}
~AudioManagerHelper() {}
AudioManagerHelper()
: max_hung_task_time_(base::TimeDelta::FromMinutes(1)),
hang_detection_enabled_(true) {}
~AudioManagerHelper() override {}
void StartHangTimer(
const scoped_refptr<base::SingleThreadTaskRunner>& monitor_task_runner) {
CHECK(!monitor_task_runner_);
monitor_task_runner_ = monitor_task_runner;
base::PowerMonitor::Get()->AddObserver(this);
UpdateLastAudioThreadTimeTick();
CrashOnAudioThreadHang();
}
// Disable hang detection when the system goes into the suspend state.
void OnSuspend() override {
base::AutoLock lock(hang_lock_);
hang_detection_enabled_ = false;
}
// Reenable hang detection once the system comes out of the suspend state.
void OnResume() override {
base::AutoLock lock(hang_lock_);
hang_detection_enabled_ = true;
last_audio_thread_timer_tick_ = base::TimeTicks::Now();
}
// Runs on |monitor_task_runner| typically, but may be started on any thread.
void CrashOnAudioThreadHang() {
base::AutoLock lock(hang_lock_);
CHECK(base::TimeTicks::Now() - last_audio_thread_timer_tick_ <=
max_hung_task_time_);
// Don't attempt to verify the tick time if the system is in the process of
// suspending or resuming.
if (hang_detection_enabled_) {
CHECK(base::TimeTicks::Now() - last_audio_thread_timer_tick_ <=
max_hung_task_time_);
}
monitor_task_runner_->PostDelayedTask(
FROM_HERE, base::Bind(&AudioManagerHelper::CrashOnAudioThreadHang,
base::Unretained(this)),
......@@ -63,6 +86,7 @@ class AudioManagerHelper {
scoped_refptr<base::SingleThreadTaskRunner> monitor_task_runner_;
base::Lock hang_lock_;
bool hang_detection_enabled_;
base::TimeTicks last_audio_thread_timer_tick_;
DISALLOW_COPY_AND_ASSIGN(AudioManagerHelper);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment