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

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

Issue 2673423002: Web MIDI: add dynamic MidiManager instantiation support for Linux (Closed)
Patch Set: update metrics Created 3 years, 10 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 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 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_service.h" 5 #include "media/midi/midi_service.h"
6 6
7 #include "base/feature_list.h"
8 #include "base/memory/ptr_util.h"
9 #include "base/strings/stringprintf.h"
7 #include "media/midi/midi_manager.h" 10 #include "media/midi/midi_manager.h"
11 #include "media/midi/midi_switches.h"
8 12
9 namespace midi { 13 namespace midi {
10 14
15 namespace {
16
17 // TODO(toyoshim): Support on all platforms. See https://crbug.com/672793.
18 #if defined(OS_LINUX)
19 constexpr bool kIsDynamicInstantiationSupported = true;
20 #else
21 constexpr bool kIsDynamicInstantiationSupported = false;
22 #endif
23
24 MidiService* g_midi_service = nullptr;
25
26 } // namespace
27
11 MidiService::MidiService(std::unique_ptr<MidiManager> manager) { 28 MidiService::MidiService(std::unique_ptr<MidiManager> manager) {
12 base::AutoLock lock(lock_); 29 base::AutoLock lock(lock_);
13 if (manager.get()) 30
31 CHECK(!g_midi_service);
32 g_midi_service = this;
33
34 is_dynamic_instantiation_enabled_ = false;
35 active_clients_ = 0u;
36 if (manager.get()) {
14 manager_ = std::move(manager); 37 manager_ = std::move(manager);
15 else 38 } else if (kIsDynamicInstantiationSupported &&
16 manager_.reset(MidiManager::Create()); 39 base::FeatureList::IsEnabled(
40 features::kMidiManagerDynamicInstantiation)) {
41 is_dynamic_instantiation_enabled_ = true;
42 } else {
43 manager_ = base::WrapUnique(MidiManager::Create());
44 }
17 } 45 }
18 46
19 MidiService::~MidiService() { 47 MidiService::~MidiService() {
20 base::AutoLock lock(lock_); 48 base::AutoLock lock(lock_);
49
21 manager_.reset(); 50 manager_.reset();
51
52 CHECK(g_midi_service);
53 g_midi_service = nullptr;
54
55 base::AutoLock threads_lock(threads_lock_);
56 threads_.clear();
22 } 57 }
23 58
24 void MidiService::Shutdown() { 59 void MidiService::Shutdown() {
25 base::AutoLock lock(lock_); 60 base::AutoLock lock(lock_);
26 manager_->Shutdown(); 61 if (manager_.get())
62 manager_->Shutdown();
27 } 63 }
28 64
29 void MidiService::StartSession(MidiManagerClient* client) { 65 void MidiService::StartSession(MidiManagerClient* client) {
30 base::AutoLock lock(lock_); 66 base::AutoLock lock(lock_);
67 if (!manager_.get()) {
68 CHECK(is_dynamic_instantiation_enabled_);
69 CHECK_EQ(0u, active_clients_);
70 manager_.reset(MidiManager::Create());
71 }
72 active_clients_++;
31 manager_->StartSession(client); 73 manager_->StartSession(client);
32 } 74 }
33 75
34 void MidiService::EndSession(MidiManagerClient* client) { 76 void MidiService::EndSession(MidiManagerClient* client) {
35 base::AutoLock lock(lock_); 77 base::AutoLock lock(lock_);
78 CHECK(manager_.get());
79 CHECK_NE(0u, active_clients_);
36 manager_->EndSession(client); 80 manager_->EndSession(client);
81 active_clients_--;
82 if (is_dynamic_instantiation_enabled_ && !active_clients_) {
83 // MidiManager for each platform should be able to shutdown correctly even
84 // if following Shutdown() call happens in the middle of
85 // StartInitialization() to support the dynamic instantiation feature.
86 manager_->Shutdown();
87 manager_.reset();
88 }
37 } 89 }
38 90
39 void MidiService::DispatchSendMidiData(MidiManagerClient* client, 91 void MidiService::DispatchSendMidiData(MidiManagerClient* client,
40 uint32_t port_index, 92 uint32_t port_index,
41 const std::vector<uint8_t>& data, 93 const std::vector<uint8_t>& data,
42 double timestamp) { 94 double timestamp) {
43 base::AutoLock lock(lock_); 95 base::AutoLock lock(lock_);
44 manager_->DispatchSendMidiData(client, port_index, data, timestamp); 96 manager_->DispatchSendMidiData(client, port_index, data, timestamp);
45 } 97 }
46 98
99 // static
100 scoped_refptr<base::SingleThreadTaskRunner> MidiService::GetTaskRunner(
101 size_t runner_id) {
102 // MidiService outlives MidiManager that could call GetTaskRunner().
103 return g_midi_service->GetTaskRunnerImpl(runner_id);
yhirano 2017/02/08 03:50:24 Is it possible to store a MidiService pointer in M
104 }
105
106 scoped_refptr<base::SingleThreadTaskRunner> MidiService::GetTaskRunnerImpl(
107 size_t runner_id) {
108 base::AutoLock lock(threads_lock_);
109 if (threads_.size() <= runner_id)
110 threads_.resize(runner_id + 1);
111 if (!threads_[runner_id].get()) {
112 threads_[runner_id] = base::MakeUnique<base::Thread>(
113 base::StringPrintf("MidiServiceThread(%zu)", runner_id));
114 threads_[runner_id]->Start();
115 }
116 return threads_[runner_id]->task_runner();
117 }
118
47 } // namespace midi 119 } // namespace midi
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698