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