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

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

Issue 2668813002: Remove LazyInstance usage from media/ (Closed)
Patch Set: Fix presubmit comments. 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
« no previous file with comments | « media/gpu/vaapi_wrapper.cc ('k') | media/midi/midi_manager_winrt.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 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_alsa.h" 5 #include "media/midi/midi_manager_alsa.h"
6 6
7 #include <errno.h> 7 #include <errno.h>
8 #include <poll.h> 8 #include <poll.h>
9 #include <stddef.h> 9 #include <stddef.h>
10 #include <stdlib.h> 10 #include <stdlib.h>
11 11
12 #include <algorithm> 12 #include <algorithm>
13 #include <string> 13 #include <string>
14 #include <utility> 14 #include <utility>
15 15
16 #include "base/bind.h" 16 #include "base/bind.h"
17 #include "base/json/json_string_value_serializer.h" 17 #include "base/json/json_string_value_serializer.h"
18 #include "base/lazy_instance.h"
19 #include "base/logging.h" 18 #include "base/logging.h"
20 #include "base/macros.h" 19 #include "base/macros.h"
21 #include "base/memory/ptr_util.h" 20 #include "base/memory/ptr_util.h"
22 #include "base/message_loop/message_loop.h" 21 #include "base/message_loop/message_loop.h"
23 #include "base/posix/eintr_wrapper.h" 22 #include "base/posix/eintr_wrapper.h"
24 #include "base/posix/safe_strerror.h" 23 #include "base/posix/safe_strerror.h"
25 #include "base/single_thread_task_runner.h" 24 #include "base/single_thread_task_runner.h"
26 #include "base/strings/string_number_conversions.h" 25 #include "base/strings/string_number_conversions.h"
27 #include "base/strings/stringprintf.h" 26 #include "base/strings/stringprintf.h"
28 #include "base/time/time.h" 27 #include "base/time/time.h"
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
93 SND_SEQ_PORT_CAP_READ | SND_SEQ_PORT_CAP_NO_EXPORT; 92 SND_SEQ_PORT_CAP_READ | SND_SEQ_PORT_CAP_NO_EXPORT;
94 const unsigned int kCreateInputPortCaps = 93 const unsigned int kCreateInputPortCaps =
95 SND_SEQ_PORT_CAP_WRITE | SND_SEQ_PORT_CAP_NO_EXPORT; 94 SND_SEQ_PORT_CAP_WRITE | SND_SEQ_PORT_CAP_NO_EXPORT;
96 const unsigned int kCreatePortType = 95 const unsigned int kCreatePortType =
97 SND_SEQ_PORT_TYPE_MIDI_GENERIC | SND_SEQ_PORT_TYPE_APPLICATION; 96 SND_SEQ_PORT_TYPE_MIDI_GENERIC | SND_SEQ_PORT_TYPE_APPLICATION;
98 97
99 // Global variables to identify MidiManagerAlsa instance. 98 // Global variables to identify MidiManagerAlsa instance.
100 const int kInvalidInstanceId = -1; 99 const int kInvalidInstanceId = -1;
101 int g_active_instance_id = kInvalidInstanceId; 100 int g_active_instance_id = kInvalidInstanceId;
102 int g_next_instance_id = 0; 101 int g_next_instance_id = 0;
103 base::LazyInstance<base::Lock> g_instance_id_lock = LAZY_INSTANCE_INITIALIZER;
104 102
105 // Prevent current instance from quiting Finalize() while tasks run on external 103 struct MidiManagerLockHelper {
106 // TaskRunners. 104 base::Lock instance_id_lock;
107 base::LazyInstance<base::Lock> g_event_task_lock = LAZY_INSTANCE_INITIALIZER; 105
108 base::LazyInstance<base::Lock> g_send_task_lock = LAZY_INSTANCE_INITIALIZER; 106 // Prevent current instance from quiting Finalize() while tasks run on
107 // external TaskRunners.
108 base::Lock event_task_lock;
109 base::Lock send_task_lock;
110 };
111
112 MidiManagerLockHelper* GetLockHelper() {
113 static MidiManagerLockHelper* lock_helper = new MidiManagerLockHelper();
114 return lock_helper;
115 }
109 116
110 int AddrToInt(int client, int port) { 117 int AddrToInt(int client, int port) {
111 return (client << 8) | port; 118 return (client << 8) | port;
112 } 119 }
113 120
114 // Returns true if this client has an ALSA card associated with it. 121 // Returns true if this client has an ALSA card associated with it.
115 bool IsCardClient(snd_seq_client_type_t type, int client_id) { 122 bool IsCardClient(snd_seq_client_type_t type, int client_id) {
116 return (type == SND_SEQ_KERNEL_CLIENT) && 123 return (type == SND_SEQ_KERNEL_CLIENT) &&
117 (client_id >= kMinimumClientIdForCards); 124 (client_id >= kMinimumClientIdForCards);
118 } 125 }
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
178 base::AutoLock lock(lazy_init_member_lock_); 185 base::AutoLock lock(lazy_init_member_lock_);
179 186
180 // Extra CHECK to verify all members are already reset. 187 // Extra CHECK to verify all members are already reset.
181 CHECK(!initialization_thread_checker_); 188 CHECK(!initialization_thread_checker_);
182 CHECK(!in_client_); 189 CHECK(!in_client_);
183 CHECK(!out_client_); 190 CHECK(!out_client_);
184 CHECK(!decoder_); 191 CHECK(!decoder_);
185 CHECK(!udev_); 192 CHECK(!udev_);
186 CHECK(!udev_monitor_); 193 CHECK(!udev_monitor_);
187 194
188 base::AutoLock instance_id_lock(g_instance_id_lock.Get()); 195 base::AutoLock instance_id_lock(GetLockHelper()->instance_id_lock);
189 CHECK_EQ(kInvalidInstanceId, g_active_instance_id); 196 CHECK_EQ(kInvalidInstanceId, g_active_instance_id);
190 } 197 }
191 198
192 void MidiManagerAlsa::StartInitialization() { 199 void MidiManagerAlsa::StartInitialization() {
193 { 200 {
194 base::AutoLock lock(g_instance_id_lock.Get()); 201 base::AutoLock lock(GetLockHelper()->instance_id_lock);
195 CHECK_EQ(kInvalidInstanceId, g_active_instance_id); 202 CHECK_EQ(kInvalidInstanceId, g_active_instance_id);
196 instance_id_ = g_next_instance_id++; 203 instance_id_ = g_next_instance_id++;
197 g_active_instance_id = instance_id_; 204 g_active_instance_id = instance_id_;
198 } 205 }
199 206
200 base::AutoLock lock(lazy_init_member_lock_); 207 base::AutoLock lock(lazy_init_member_lock_);
201 208
202 initialization_thread_checker_.reset(new base::ThreadChecker()); 209 initialization_thread_checker_.reset(new base::ThreadChecker());
203 210
204 // Create client handles. 211 // Create client handles.
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after
320 } 327 }
321 328
322 void MidiManagerAlsa::Finalize() { 329 void MidiManagerAlsa::Finalize() {
323 base::AutoLock lock(lazy_init_member_lock_); 330 base::AutoLock lock(lazy_init_member_lock_);
324 DCHECK(initialization_thread_checker_->CalledOnValidThread()); 331 DCHECK(initialization_thread_checker_->CalledOnValidThread());
325 332
326 // Tell tasks running on TaskRunners it will soon be time to shut down. This 333 // Tell tasks running on TaskRunners it will soon be time to shut down. This
327 // gives us assurance a task running on kEventTaskRunner will stop in case the 334 // gives us assurance a task running on kEventTaskRunner will stop in case the
328 // SND_SEQ_EVENT_CLIENT_EXIT message is lost. 335 // SND_SEQ_EVENT_CLIENT_EXIT message is lost.
329 { 336 {
330 base::AutoLock lock(g_instance_id_lock.Get()); 337 base::AutoLock lock(GetLockHelper()->instance_id_lock);
331 CHECK_EQ(instance_id_, g_active_instance_id); 338 CHECK_EQ(instance_id_, g_active_instance_id);
332 g_active_instance_id = kInvalidInstanceId; 339 g_active_instance_id = kInvalidInstanceId;
333 } 340 }
334 341
335 // Ensure that no tasks run on kSendTaskRunner. 342 // Ensure that no tasks run on kSendTaskRunner.
336 base::AutoLock send_runner_lock(g_send_task_lock.Get()); 343 base::AutoLock send_runner_lock(GetLockHelper()->send_task_lock);
337 344
338 // Close the out client. This will trigger the event thread to stop, 345 // Close the out client. This will trigger the event thread to stop,
339 // because of SND_SEQ_EVENT_CLIENT_EXIT. 346 // because of SND_SEQ_EVENT_CLIENT_EXIT.
340 out_client_.reset(); 347 out_client_.reset();
341 348
342 // Ensure that no tasks run on kEventTaskRunner. 349 // Ensure that no tasks run on kEventTaskRunner.
343 base::AutoLock event_runner_lock(g_event_task_lock.Get()); 350 base::AutoLock event_runner_lock(GetLockHelper()->event_task_lock);
344 351
345 // Destruct the other stuff we initialized in StartInitialization(). 352 // Destruct the other stuff we initialized in StartInitialization().
346 udev_monitor_.reset(); 353 udev_monitor_.reset();
347 udev_.reset(); 354 udev_.reset();
348 decoder_.reset(); 355 decoder_.reset();
349 in_client_.reset(); 356 in_client_.reset();
350 initialization_thread_checker_.reset(); 357 initialization_thread_checker_.reset();
351 } 358 }
352 359
353 void MidiManagerAlsa::DispatchSendMidiData(MidiManagerClient* client, 360 void MidiManagerAlsa::DispatchSendMidiData(MidiManagerClient* client,
(...skipping 532 matching lines...) Expand 10 before | Expand all | Expand 10 after
886 } 893 }
887 894
888 void MidiManagerAlsa::SendMidiData(int instance_id, 895 void MidiManagerAlsa::SendMidiData(int instance_id,
889 MidiManagerClient* client, 896 MidiManagerClient* client,
890 uint32_t port_index, 897 uint32_t port_index,
891 const std::vector<uint8_t>& data) { 898 const std::vector<uint8_t>& data) {
892 DCHECK(service()->GetTaskRunner(kSendTaskRunner)->BelongsToCurrentThread()); 899 DCHECK(service()->GetTaskRunner(kSendTaskRunner)->BelongsToCurrentThread());
893 900
894 // Obtain the lock so that the instance could not be destructed while this 901 // Obtain the lock so that the instance could not be destructed while this
895 // method is running on the kSendTaskRunner. 902 // method is running on the kSendTaskRunner.
896 base::AutoLock lock(g_send_task_lock.Get()); 903 base::AutoLock lock(GetLockHelper()->send_task_lock);
897 { 904 {
898 // Check if Finalize() already runs. After this check, we can access |this| 905 // Check if Finalize() already runs. After this check, we can access |this|
899 // safely on the kEventTaskRunner. 906 // safely on the kEventTaskRunner.
900 base::AutoLock instance_id_lock(g_instance_id_lock.Get()); 907 base::AutoLock instance_id_lock(GetLockHelper()->instance_id_lock);
901 if (instance_id != g_active_instance_id) 908 if (instance_id != g_active_instance_id)
902 return; 909 return;
903 } 910 }
904 911
905 snd_midi_event_t* encoder; 912 snd_midi_event_t* encoder;
906 snd_midi_event_new(kSendBufferSize, &encoder); 913 snd_midi_event_new(kSendBufferSize, &encoder);
907 for (const auto datum : data) { 914 for (const auto datum : data) {
908 snd_seq_event_t event; 915 snd_seq_event_t event;
909 int result = snd_midi_event_encode_byte(encoder, datum, &event); 916 int result = snd_midi_event_encode_byte(encoder, datum, &event);
910 if (result == 1) { 917 if (result == 1) {
(...skipping 10 matching lines...) Expand all
921 } 928 }
922 snd_midi_event_free(encoder); 929 snd_midi_event_free(encoder);
923 930
924 // Acknowledge send. 931 // Acknowledge send.
925 AccumulateMidiBytesSent(client, data.size()); 932 AccumulateMidiBytesSent(client, data.size());
926 } 933 }
927 934
928 void MidiManagerAlsa::EventLoop(int instance_id) { 935 void MidiManagerAlsa::EventLoop(int instance_id) {
929 // Obtain the lock so that the instance could not be destructed while this 936 // Obtain the lock so that the instance could not be destructed while this
930 // method is running on the kEventTaskRunner. 937 // method is running on the kEventTaskRunner.
931 base::AutoLock lock(g_event_task_lock.Get()); 938 base::AutoLock lock(GetLockHelper()->event_task_lock);
932 { 939 {
933 // Check if Finalize() already runs. After this check, we can access |this| 940 // Check if Finalize() already runs. After this check, we can access |this|
934 // safely on the kEventTaskRunner. 941 // safely on the kEventTaskRunner.
935 base::AutoLock instance_id_lock(g_instance_id_lock.Get()); 942 base::AutoLock instance_id_lock(GetLockHelper()->instance_id_lock);
936 if (instance_id != g_active_instance_id) 943 if (instance_id != g_active_instance_id)
937 return; 944 return;
938 } 945 }
939 946
940 bool loop_again = true; 947 bool loop_again = true;
941 948
942 struct pollfd pfd[2]; 949 struct pollfd pfd[2];
943 snd_seq_poll_descriptors(in_client_.get(), &pfd[0], 1, POLLIN); 950 snd_seq_poll_descriptors(in_client_.get(), &pfd[0], 1, POLLIN);
944 pfd[1].fd = device::udev_monitor_get_fd(udev_monitor_.get()); 951 pfd[1].fd = device::udev_monitor_get_fd(udev_monitor_.get());
945 pfd[1].events = POLLIN; 952 pfd[1].events = POLLIN;
(...skipping 496 matching lines...) Expand 10 before | Expand all | Expand 10 after
1442 // Update our map. 1449 // Update our map.
1443 source_map_[AddrToInt(client_id, port_id)] = port_index; 1450 source_map_[AddrToInt(client_id, port_id)] = port_index;
1444 return true; 1451 return true;
1445 } 1452 }
1446 1453
1447 MidiManager* MidiManager::Create(MidiService* service) { 1454 MidiManager* MidiManager::Create(MidiService* service) {
1448 return new MidiManagerAlsa(service); 1455 return new MidiManagerAlsa(service);
1449 } 1456 }
1450 1457
1451 } // namespace midi 1458 } // namespace midi
OLDNEW
« no previous file with comments | « media/gpu/vaapi_wrapper.cc ('k') | media/midi/midi_manager_winrt.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698