diff options
Diffstat (limited to 'chromium/media/audio/scoped_task_runner_observer.cc')
-rw-r--r-- | chromium/media/audio/scoped_task_runner_observer.cc | 48 |
1 files changed, 48 insertions, 0 deletions
diff --git a/chromium/media/audio/scoped_task_runner_observer.cc b/chromium/media/audio/scoped_task_runner_observer.cc new file mode 100644 index 00000000000..9f4eac28511 --- /dev/null +++ b/chromium/media/audio/scoped_task_runner_observer.cc @@ -0,0 +1,48 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "media/audio/scoped_task_runner_observer.h" + +#include "base/bind.h" +#include "base/synchronization/waitable_event.h" + +namespace media { + +ScopedTaskRunnerObserver::ScopedTaskRunnerObserver( + const scoped_refptr<base::SingleThreadTaskRunner>& task_runner) + : task_runner_(task_runner) { + ObserveLoopDestruction(true, NULL); +} + +ScopedTaskRunnerObserver::~ScopedTaskRunnerObserver() { + ObserveLoopDestruction(false, NULL); +} + +void ScopedTaskRunnerObserver::ObserveLoopDestruction( + bool enable, + base::WaitableEvent* done) { + // Note: |done| may be NULL. + if (task_runner_->BelongsToCurrentThread()) { + base::MessageLoop* loop = base::MessageLoop::current(); + if (enable) { + loop->AddDestructionObserver(this); + } else { + loop->RemoveDestructionObserver(this); + } + } else { + base::WaitableEvent event(false, false); + if (task_runner_->PostTask(FROM_HERE, + base::Bind(&ScopedTaskRunnerObserver::ObserveLoopDestruction, + base::Unretained(this), enable, &event))) { + event.Wait(); + } else { + // The message loop's thread has already terminated, so no need to wait. + } + } + + if (done) + done->Signal(); +} + +} // namespace media. |