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
3// found in the LICENSE file.
4
5#include "media/audio/scoped_task_runner_observer.h"
6
7#include "base/bind.h"
8#include "base/synchronization/waitable_event.h"
9
10namespace media {
11
12ScopedTaskRunnerObserver::ScopedTaskRunnerObserver(
13    const scoped_refptr<base::SingleThreadTaskRunner>& task_runner)
14    : task_runner_(task_runner) {
15  ObserveLoopDestruction(true, NULL);
16}
17
18ScopedTaskRunnerObserver::~ScopedTaskRunnerObserver() {
19  ObserveLoopDestruction(false, NULL);
20}
21
22void ScopedTaskRunnerObserver::ObserveLoopDestruction(
23    bool enable,
24    base::WaitableEvent* done) {
25  // Note: |done| may be NULL.
26  if (task_runner_->BelongsToCurrentThread()) {
27    base::MessageLoop* loop = base::MessageLoop::current();
28    if (enable) {
29      loop->AddDestructionObserver(this);
30    } else {
31      loop->RemoveDestructionObserver(this);
32    }
33  } else {
34    base::WaitableEvent event(false, false);
35    if (task_runner_->PostTask(FROM_HERE,
36            base::Bind(&ScopedTaskRunnerObserver::ObserveLoopDestruction,
37                       base::Unretained(this), enable, &event))) {
38      event.Wait();
39    } else {
40      // The message loop's thread has already terminated, so no need to wait.
41    }
42  }
43
44  if (done)
45    done->Signal();
46}
47
48}  // namespace media.
49