Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(90)

Side by Side Diff: media/midi/midi_manager.cc

Issue 1315793008: Web MIDI: introduce MidiManager::Shutdown to shutdown gracefully (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: more checks in unit tests Created 5 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698