OLD | NEW |
---|---|
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "media/midi/midi_manager.h" | 5 #include "media/midi/midi_manager.h" |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/message_loop/message_loop.h" | 8 #include "base/message_loop/message_loop.h" |
9 #include "base/metrics/histogram_macros.h" | 9 #include "base/metrics/histogram_macros.h" |
10 #include "base/trace_event/trace_event.h" | 10 #include "base/trace_event/trace_event.h" |
(...skipping 25 matching lines...) Expand all Loading... | |
36 | 36 |
37 void ReportUsage(Usage usage) { | 37 void ReportUsage(Usage usage) { |
38 UMA_HISTOGRAM_ENUMERATION("Media.Midi.Usage", | 38 UMA_HISTOGRAM_ENUMERATION("Media.Midi.Usage", |
39 static_cast<Sample>(usage), | 39 static_cast<Sample>(usage), |
40 static_cast<Sample>(Usage::MAX) + 1); | 40 static_cast<Sample>(Usage::MAX) + 1); |
41 } | 41 } |
42 | 42 |
43 } // namespace | 43 } // namespace |
44 | 44 |
45 MidiManager::MidiManager() | 45 MidiManager::MidiManager() |
46 : initialized_(false), result_(Result::NOT_INITIALIZED) { | 46 : initialized_(false), finalized_(false), result_(Result::NOT_INITIALIZED) { |
47 ReportUsage(Usage::CREATED); | 47 ReportUsage(Usage::CREATED); |
48 } | 48 } |
49 | 49 |
50 MidiManager::~MidiManager() { | 50 MidiManager::~MidiManager() { |
51 UMA_HISTOGRAM_ENUMERATION("Media.Midi.ResultOnShutdown", | 51 // Make sure that Finalize() is called to clean up resources allocated on |
52 static_cast<Sample>(result_), | 52 // the Chrome_IOThread. |
53 static_cast<Sample>(Result::MAX) + 1); | 53 DCHECK(finalized_); |
54 } | 54 } |
55 | 55 |
56 #if !defined(OS_MACOSX) && !defined(OS_WIN) && \ | 56 #if !defined(OS_MACOSX) && !defined(OS_WIN) && \ |
57 !(defined(USE_ALSA) && defined(USE_UDEV)) && !defined(OS_ANDROID) | 57 !(defined(USE_ALSA) && defined(USE_UDEV)) && !defined(OS_ANDROID) |
58 MidiManager* MidiManager::Create() { | 58 MidiManager* MidiManager::Create() { |
59 ReportUsage(Usage::CREATED_ON_UNSUPPORTED_PLATFORMS); | 59 ReportUsage(Usage::CREATED_ON_UNSUPPORTED_PLATFORMS); |
60 return new MidiManager; | 60 return new MidiManager; |
61 } | 61 } |
62 #endif | 62 #endif |
63 | 63 |
64 void MidiManager::Shutdown() { | |
65 UMA_HISTOGRAM_ENUMERATION("Media.Midi.ResultOnShutdown", | |
66 static_cast<int>(result_), | |
67 static_cast<int>(Result::MAX) + 1); | |
68 base::AutoLock auto_lock(lock_); | |
69 if (session_thread_runner_) { | |
70 session_thread_runner_->PostTask( | |
71 FROM_HERE, base::Bind(&MidiManager::ShutdownOnSessionThread, | |
72 base::Unretained(this))); | |
73 session_thread_runner_ = nullptr; | |
74 } else { | |
75 finalized_ = true; | |
76 } | |
77 } | |
78 | |
64 void MidiManager::StartSession(MidiManagerClient* client) { | 79 void MidiManager::StartSession(MidiManagerClient* client) { |
65 ReportUsage(Usage::SESSION_STARTED); | 80 ReportUsage(Usage::SESSION_STARTED); |
66 | 81 |
67 bool session_is_ready; | 82 bool session_is_ready; |
68 bool session_needs_initialization = false; | 83 bool session_needs_initialization = false; |
69 bool too_many_pending_clients_exist = false; | 84 bool too_many_pending_clients_exist = false; |
70 | 85 |
71 { | 86 { |
72 base::AutoLock auto_lock(lock_); | 87 base::AutoLock auto_lock(lock_); |
73 session_is_ready = initialized_; | 88 session_is_ready = initialized_; |
(...skipping 14 matching lines...) Expand all Loading... | |
88 session_needs_initialization = pending_clients_.empty(); | 103 session_needs_initialization = pending_clients_.empty(); |
89 pending_clients_.insert(client); | 104 pending_clients_.insert(client); |
90 } | 105 } |
91 } | 106 } |
92 } | 107 } |
93 | 108 |
94 // Lazily initialize the MIDI back-end. | 109 // Lazily initialize the MIDI back-end. |
95 if (!session_is_ready) { | 110 if (!session_is_ready) { |
96 if (session_needs_initialization) { | 111 if (session_needs_initialization) { |
97 TRACE_EVENT0("midi", "MidiManager::StartInitialization"); | 112 TRACE_EVENT0("midi", "MidiManager::StartInitialization"); |
98 session_thread_runner_ = | 113 { |
99 base::MessageLoop::current()->task_runner(); | 114 base::AutoLock auto_lock(lock_); |
115 // Stop calling StartInitialization() if Shutdown() was already called. | |
116 if (finalized_) | |
yhirano
2015/09/11 15:59:47
Should we call CompleteStartSession with INITIALIZ
Takashi Toyoshima
2015/09/17 07:30:49
This isn't easy because I do not want to call clie
| |
117 return; | |
118 session_thread_runner_ = base::MessageLoop::current()->task_runner(); | |
119 } | |
100 StartInitialization(); | 120 StartInitialization(); |
101 } | 121 } |
102 if (too_many_pending_clients_exist) { | 122 if (too_many_pending_clients_exist) { |
103 // Return an error immediately if there are too many requests. | 123 // Return an error immediately if there are too many requests. |
104 client->CompleteStartSession(Result::INITIALIZATION_ERROR); | 124 client->CompleteStartSession(Result::INITIALIZATION_ERROR); |
105 return; | 125 return; |
106 } | 126 } |
107 // CompleteInitialization() will be called asynchronously when platform | 127 // CompleteInitialization() will be called asynchronously when platform |
108 // dependent initialization is finished. | 128 // dependent initialization is finished. |
109 return; | 129 return; |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
147 const std::vector<uint8>& data, | 167 const std::vector<uint8>& data, |
148 double timestamp) { | 168 double timestamp) { |
149 NOTREACHED(); | 169 NOTREACHED(); |
150 } | 170 } |
151 | 171 |
152 void MidiManager::StartInitialization() { | 172 void MidiManager::StartInitialization() { |
153 CompleteInitialization(Result::NOT_SUPPORTED); | 173 CompleteInitialization(Result::NOT_SUPPORTED); |
154 } | 174 } |
155 | 175 |
156 void MidiManager::CompleteInitialization(Result result) { | 176 void MidiManager::CompleteInitialization(Result result) { |
157 DCHECK(session_thread_runner_.get()); | 177 base::AutoLock auto_lock(lock_); |
158 // It is safe to post a task to the IO thread from here because the IO thread | 178 if (session_thread_runner_) { |
159 // should have stopped if the MidiManager is going to be destructed. | 179 session_thread_runner_->PostTask( |
160 session_thread_runner_->PostTask( | 180 FROM_HERE, base::Bind(&MidiManager::CompleteInitializationInternal, |
161 FROM_HERE, | 181 base::Unretained(this), result)); |
162 base::Bind(&MidiManager::CompleteInitializationInternal, | 182 } |
163 base::Unretained(this), | |
164 result)); | |
165 } | 183 } |
166 | 184 |
167 void MidiManager::AddInputPort(const MidiPortInfo& info) { | 185 void MidiManager::AddInputPort(const MidiPortInfo& info) { |
168 ReportUsage(Usage::INPUT_PORT_ADDED); | 186 ReportUsage(Usage::INPUT_PORT_ADDED); |
169 base::AutoLock auto_lock(lock_); | 187 base::AutoLock auto_lock(lock_); |
170 input_ports_.push_back(info); | 188 input_ports_.push_back(info); |
171 for (auto client : clients_) | 189 for (auto client : clients_) |
172 client->AddInputPort(info); | 190 client->AddInputPort(info); |
173 } | 191 } |
174 | 192 |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
235 | 253 |
236 void MidiManager::AddInitialPorts(MidiManagerClient* client) { | 254 void MidiManager::AddInitialPorts(MidiManagerClient* client) { |
237 lock_.AssertAcquired(); | 255 lock_.AssertAcquired(); |
238 | 256 |
239 for (const auto& info : input_ports_) | 257 for (const auto& info : input_ports_) |
240 client->AddInputPort(info); | 258 client->AddInputPort(info); |
241 for (const auto& info : output_ports_) | 259 for (const auto& info : output_ports_) |
242 client->AddOutputPort(info); | 260 client->AddOutputPort(info); |
243 } | 261 } |
244 | 262 |
263 void MidiManager::ShutdownOnSessionThread() { | |
264 Finalize(); | |
265 base::AutoLock auto_lock(lock_); | |
266 finalized_ = true; | |
267 } | |
268 | |
245 } // namespace midi | 269 } // namespace midi |
246 } // namespace media | 270 } // namespace media |
OLD | NEW |