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

Side by Side Diff: media/audio/audio_device_thread.cc

Issue 2038053002: Change audio render thread checking to use new AudioRendererSink::BelongsToRendererThread() (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Code review fixes (dalecurtis@). Created 4 years, 6 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) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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/audio/audio_device_thread.h" 5 #include "media/audio/audio_device_thread.h"
6 6
7 #include <stddef.h> 7 #include <stddef.h>
8 #include <stdint.h> 8 #include <stdint.h>
9 9
10 #include <algorithm> 10 #include <algorithm>
11 #include <limits> 11 #include <limits>
12 12
13 #include "base/bind.h" 13 #include "base/bind.h"
14 #include "base/logging.h" 14 #include "base/logging.h"
15 #include "base/macros.h" 15 #include "base/macros.h"
16 #include "base/memory/aligned_memory.h" 16 #include "base/memory/aligned_memory.h"
17 #include "base/message_loop/message_loop.h" 17 #include "base/message_loop/message_loop.h"
18 #include "base/numerics/safe_conversions.h" 18 #include "base/numerics/safe_conversions.h"
19 #include "base/synchronization/lock.h"
20 #include "base/synchronization/waitable_event.h"
19 #include "base/threading/platform_thread.h" 21 #include "base/threading/platform_thread.h"
20 #include "base/threading/thread_restrictions.h" 22 #include "base/threading/thread_restrictions.h"
21 #include "media/base/audio_bus.h" 23 #include "media/base/audio_bus.h"
22 24
23 using base::PlatformThread; 25 using base::PlatformThread;
24 26
25 namespace media { 27 namespace media {
26 28
27 // The actual worker thread implementation. It's very bare bones and much 29 // The actual worker thread implementation. It's very bare bones and much
28 // simpler than SimpleThread (no synchronization in Start, etc) and supports 30 // simpler than SimpleThread (no synchronization in Start, etc) and supports
29 // joining the thread handle asynchronously via a provided message loop even 31 // joining the thread handle asynchronously via a provided message loop even
30 // after the Thread object itself has been deleted. 32 // after the Thread object itself has been deleted.
31 class AudioDeviceThread::Thread 33 class AudioDeviceThread::Thread
32 : public PlatformThread::Delegate, 34 : public PlatformThread::Delegate,
33 public base::RefCountedThreadSafe<AudioDeviceThread::Thread> { 35 public base::RefCountedThreadSafe<AudioDeviceThread::Thread> {
34 public: 36 public:
35 Thread(AudioDeviceThread::Callback* callback, 37 Thread(AudioDeviceThread::Callback* callback,
36 base::SyncSocket::Handle socket, 38 base::SyncSocket::Handle socket,
37 const char* thread_name, 39 const char* thread_name,
38 bool synchronized_buffers); 40 bool synchronized_buffers);
39 41
40 void Start(); 42 void Start();
41 43
42 // Stops the thread. If |loop_for_join| is non-NULL, the function posts 44 // Stops the thread. If |loop_for_join| is non-NULL, the function posts
43 // a task to join (close) the thread handle later instead of waiting for 45 // a task to join (close) the thread handle later instead of waiting for
44 // the thread. If loop_for_join is NULL, then the function waits 46 // the thread. If loop_for_join is NULL, then the function waits
45 // synchronously for the thread to terminate. 47 // synchronously for the thread to terminate.
46 void Stop(base::MessageLoop* loop_for_join); 48 void Stop(base::MessageLoop* loop_for_join);
47 49
50 // Returns true if called on the device thread, otherwise false.
51 bool BelongsToRenderingThread();
52
48 private: 53 private:
49 friend class base::RefCountedThreadSafe<AudioDeviceThread::Thread>; 54 friend class base::RefCountedThreadSafe<AudioDeviceThread::Thread>;
50 ~Thread() override; 55 ~Thread() override;
51 56
52 // Overrides from PlatformThread::Delegate. 57 // Overrides from PlatformThread::Delegate.
53 void ThreadMain() override; 58 void ThreadMain() override;
54 59
55 // Runs the loop that reads from the socket. 60 // Runs the loop that reads from the socket.
56 void Run(); 61 void Run();
57 62
58 private: 63 private:
59 base::PlatformThreadHandle thread_; 64 base::PlatformThreadHandle thread_;
60 AudioDeviceThread::Callback* callback_; 65 AudioDeviceThread::Callback* callback_;
61 base::CancelableSyncSocket socket_; 66 base::CancelableSyncSocket socket_;
62 base::Lock callback_lock_; 67 base::Lock callback_lock_;
63 const char* thread_name_; 68 const char* thread_name_;
64 const bool synchronized_buffers_; 69 const bool synchronized_buffers_;
65 70
71 // The thread's id once it has started.
72 base::PlatformThreadId id_;
tommi (sloooow) - chröme 2016/06/13 14:15:21 thread_id_
Henrik Grunell 2016/06/14 11:30:01 Removed.
73 mutable base::WaitableEvent id_event_; // Protects |id_|.
tommi (sloooow) - chröme 2016/06/13 14:15:21 how does the event protect the thread id variable?
Henrik Grunell 2016/06/13 20:38:35 I'll clarify that. (It's set once only, and when d
Henrik Grunell 2016/06/14 11:30:01 Removed.
74
66 DISALLOW_COPY_AND_ASSIGN(Thread); 75 DISALLOW_COPY_AND_ASSIGN(Thread);
67 }; 76 };
68 77
69 // AudioDeviceThread implementation 78 // AudioDeviceThread implementation
70 79
71 AudioDeviceThread::AudioDeviceThread() { 80 AudioDeviceThread::AudioDeviceThread() {
72 } 81 }
73 82
74 AudioDeviceThread::~AudioDeviceThread() { DCHECK(!thread_.get()); } 83 AudioDeviceThread::~AudioDeviceThread() { DCHECK(!thread_.get()); }
75 84
(...skipping 14 matching lines...) Expand all
90 thread_->Stop(loop_for_join); 99 thread_->Stop(loop_for_join);
91 thread_ = NULL; 100 thread_ = NULL;
92 } 101 }
93 } 102 }
94 103
95 bool AudioDeviceThread::IsStopped() { 104 bool AudioDeviceThread::IsStopped() {
96 base::AutoLock auto_lock(thread_lock_); 105 base::AutoLock auto_lock(thread_lock_);
97 return !thread_.get(); 106 return !thread_.get();
98 } 107 }
99 108
109 bool AudioDeviceThread::BelongsToRenderingThread() {
110 base::AutoLock auto_lock(thread_lock_);
tommi (sloooow) - chröme 2016/06/13 14:15:21 It seems unfortunate to require a lock for this...
Henrik Grunell 2016/06/14 11:30:01 This has been removed altogether.
111 return thread_.get() ? thread_->BelongsToRenderingThread() : false;
tommi (sloooow) - chröme 2016/06/13 14:15:21 nit: return thread_ && thread_->CurrentThreadIsRe
Henrik Grunell 2016/06/14 11:30:01 Removed.
112 }
113
100 // AudioDeviceThread::Thread implementation 114 // AudioDeviceThread::Thread implementation
101 AudioDeviceThread::Thread::Thread(AudioDeviceThread::Callback* callback, 115 AudioDeviceThread::Thread::Thread(AudioDeviceThread::Callback* callback,
102 base::SyncSocket::Handle socket, 116 base::SyncSocket::Handle socket,
103 const char* thread_name, 117 const char* thread_name,
104 bool synchronized_buffers) 118 bool synchronized_buffers)
105 : thread_(), 119 : thread_(),
106 callback_(callback), 120 callback_(callback),
107 socket_(socket), 121 socket_(socket),
108 thread_name_(thread_name), 122 thread_name_(thread_name),
109 synchronized_buffers_(synchronized_buffers) { 123 synchronized_buffers_(synchronized_buffers),
110 } 124 id_(base::kInvalidThreadId),
125 id_event_(base::WaitableEvent::ResetPolicy::MANUAL,
126 base::WaitableEvent::InitialState::NOT_SIGNALED) {}
111 127
112 AudioDeviceThread::Thread::~Thread() { 128 AudioDeviceThread::Thread::~Thread() {
113 DCHECK(thread_.is_null()); 129 DCHECK(thread_.is_null());
114 } 130 }
115 131
116 void AudioDeviceThread::Thread::Start() { 132 void AudioDeviceThread::Thread::Start() {
117 base::AutoLock auto_lock(callback_lock_); 133 base::AutoLock auto_lock(callback_lock_);
118 DCHECK(thread_.is_null()); 134 DCHECK(thread_.is_null());
119 // This reference will be released when the thread exists. 135 // This reference will be released when the thread exists.
120 AddRef(); 136 AddRef();
(...skipping 17 matching lines...) Expand all
138 if (!thread.is_null()) { 154 if (!thread.is_null()) {
139 if (loop_for_join) { 155 if (loop_for_join) {
140 loop_for_join->PostTask(FROM_HERE, 156 loop_for_join->PostTask(FROM_HERE,
141 base::Bind(&base::PlatformThread::Join, thread)); 157 base::Bind(&base::PlatformThread::Join, thread));
142 } else { 158 } else {
143 base::PlatformThread::Join(thread); 159 base::PlatformThread::Join(thread);
144 } 160 }
145 } 161 }
146 } 162 }
147 163
164 bool AudioDeviceThread::Thread::BelongsToRenderingThread() {
165 // If the thread is created but not started yet, wait for |id_| being ready.
166 base::ThreadRestrictions::ScopedAllowWait allow_wait;
167 id_event_.Wait();
tommi (sloooow) - chröme 2016/06/13 14:15:21 would be great to not require an event object for
Henrik Grunell 2016/06/13 20:38:35 So I shall.
Henrik Grunell 2016/06/14 11:30:01 This has been removed.
168 return id_ == PlatformThread::CurrentId();
169 }
170
148 void AudioDeviceThread::Thread::ThreadMain() { 171 void AudioDeviceThread::Thread::ThreadMain() {
172 id_ = PlatformThread::CurrentId();
173 DCHECK_NE(base::kInvalidThreadId, id_);
174 id_event_.Signal();
175
149 PlatformThread::SetName(thread_name_); 176 PlatformThread::SetName(thread_name_);
150 177
151 // Singleton access is safe from this thread as long as callback is non-NULL. 178 // Singleton access is safe from this thread as long as callback is non-NULL.
152 // The callback is the only point where the thread calls out to 'unknown' code 179 // The callback is the only point where the thread calls out to 'unknown' code
153 // that might touch singletons and the lifetime of the callback is controlled 180 // that might touch singletons and the lifetime of the callback is controlled
154 // by another thread on which singleton access is OK as well. 181 // by another thread on which singleton access is OK as well.
155 base::ThreadRestrictions::SetSingletonAllowed(true); 182 base::ThreadRestrictions::SetSingletonAllowed(true);
156 183
157 { // NOLINT 184 { // NOLINT
158 base::AutoLock auto_lock(callback_lock_); 185 base::AutoLock auto_lock(callback_lock_);
159 if (callback_) 186 if (callback_)
160 callback_->InitializeOnAudioThread(); 187 callback_->InitializeOnAudioThread();
tommi (sloooow) - chröme 2016/06/13 14:15:21 It looks like AudioDeviceThread itself doesn't nee
Henrik Grunell 2016/06/13 20:38:35 Well, that could perhaps work. And is perhaps bett
Henrik Grunell 2016/06/14 11:30:01 This should be fine, good suggestion. Done.
161 } 188 }
162 189
163 Run(); 190 Run();
164 191
165 // Release the reference for the thread. Note that after this, the Thread 192 // Release the reference for the thread. Note that after this, the Thread
166 // instance will most likely be deleted. 193 // instance will most likely be deleted.
167 Release(); 194 Release();
168 } 195 }
169 196
170 void AudioDeviceThread::Thread::Run() { 197 void AudioDeviceThread::Thread::Run() {
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
233 } 260 }
234 261
235 AudioDeviceThread::Callback::~Callback() {} 262 AudioDeviceThread::Callback::~Callback() {}
236 263
237 void AudioDeviceThread::Callback::InitializeOnAudioThread() { 264 void AudioDeviceThread::Callback::InitializeOnAudioThread() {
238 MapSharedMemory(); 265 MapSharedMemory();
239 CHECK(shared_memory_.memory()); 266 CHECK(shared_memory_.memory());
240 } 267 }
241 268
242 } // namespace media. 269 } // namespace media.
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698