summaryrefslogtreecommitdiffstats
path: root/chromium/media/audio/scoped_task_runner_observer.cc
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/media/audio/scoped_task_runner_observer.cc')
-rw-r--r--chromium/media/audio/scoped_task_runner_observer.cc48
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.