1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
media / audio / scoped_task_runner_observer.cc [blame]
// Copyright 2012 The Chromium Authors
// 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/functional/bind.h"
#include "base/synchronization/waitable_event.h"
#include "base/task/single_thread_task_runner.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::CurrentThread loop = base::CurrentThread::Get();
if (enable) {
loop->AddDestructionObserver(this);
} else {
loop->RemoveDestructionObserver(this);
}
} else {
base::WaitableEvent event(base::WaitableEvent::ResetPolicy::AUTOMATIC,
base::WaitableEvent::InitialState::NOT_SIGNALED);
if (task_runner_->PostTask(
FROM_HERE,
base::BindOnce(&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.