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

Side by Side Diff: ppapi/shared_impl/ppb_audio_shared.cc

Issue 240523002: Add test to make sure if PPB_Audio_Shared::StartThread() works. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 years, 8 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 | Annotate | Revision Log
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 "ppapi/shared_impl/ppb_audio_shared.h" 5 #include "ppapi/shared_impl/ppb_audio_shared.h"
6 6
7 #include "base/logging.h" 7 #include "base/logging.h"
8 #include "ppapi/shared_impl/ppapi_globals.h" 8 #include "ppapi/shared_impl/ppapi_globals.h"
9 #include "ppapi/shared_impl/ppb_audio_config_shared.h" 9 #include "ppapi/shared_impl/ppb_audio_config_shared.h"
10 #include "ppapi/shared_impl/proxy_lock.h" 10 #include "ppapi/shared_impl/proxy_lock.h"
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
66 socket_->Shutdown(); 66 socket_->Shutdown();
67 StopThread(); 67 StopThread();
68 } 68 }
69 69
70 void PPB_Audio_Shared::SetCallback(const AudioCallbackCombined& callback, 70 void PPB_Audio_Shared::SetCallback(const AudioCallbackCombined& callback,
71 void* user_data) { 71 void* user_data) {
72 callback_ = callback; 72 callback_ = callback;
73 user_data_ = user_data; 73 user_data_ = user_data;
74 } 74 }
75 75
76 void PPB_Audio_Shared::SetStartPlaybackState() { 76 bool PPB_Audio_Shared::SetStartPlaybackState() {
77 DCHECK(!playing_); 77 DCHECK(!playing_);
78 #if !defined(OS_NACL) 78 #if !defined(OS_NACL)
79 DCHECK(!audio_thread_.get()); 79 DCHECK(!audio_thread_.get());
80 #else 80 #else
81 DCHECK(!thread_active_); 81 DCHECK(!thread_active_);
82 #endif 82 #endif
83 // If the socket doesn't exist, that means that the plugin has started before 83 // If the socket doesn't exist, that means that the plugin has started before
84 // the browser has had a chance to create all the shared memory info and 84 // the browser has had a chance to create all the shared memory info and
85 // notify us. This is a common case. In this case, we just set the playing_ 85 // notify us. This is a common case. In this case, we just set the playing_
86 // flag and the playback will automatically start when that data is available 86 // flag and the playback will automatically start when that data is available
87 // in SetStreamInfo. 87 // in SetStreamInfo.
88 // If StartThread() returns false, it means no thread creator is set yet.
89 // In such a case, we do not set playing state, because even if SetStreamInfo
90 // is invoked later, we cannot create a thread.
91 // Note that StartThread returns true even if socket doesn't exist as it is
bbudge 2014/04/18 13:34:40 I think this last sentence just repeats the commen
hidehiko 2014/04/18 18:16:30 Acknowledged.
92 // common situation as descibed above.
88 playing_ = true; 93 playing_ = true;
89 StartThread(); 94 if (!StartThread())
95 playing_ = false;
96 return playing_;
90 } 97 }
91 98
92 void PPB_Audio_Shared::SetStopPlaybackState() { 99 void PPB_Audio_Shared::SetStopPlaybackState() {
93 DCHECK(playing_); 100 DCHECK(playing_);
94 StopThread(); 101 StopThread();
95 playing_ = false; 102 playing_ = false;
96 } 103 }
97 104
98 void PPB_Audio_Shared::SetStreamInfo( 105 void PPB_Audio_Shared::SetStreamInfo(
99 PP_Instance instance, 106 PP_Instance instance,
(...skipping 20 matching lines...) Expand all
120 kAudioOutputChannels, sample_frame_count, shared_memory_->memory()); 127 kAudioOutputChannels, sample_frame_count, shared_memory_->memory());
121 // Setup integer audio buffer for user audio data. 128 // Setup integer audio buffer for user audio data.
122 client_buffer_size_bytes_ = audio_bus_->frames() * audio_bus_->channels() * 129 client_buffer_size_bytes_ = audio_bus_->frames() * audio_bus_->channels() *
123 kBitsPerAudioOutputSample / 8; 130 kBitsPerAudioOutputSample / 8;
124 client_buffer_.reset(new uint8_t[client_buffer_size_bytes_]); 131 client_buffer_.reset(new uint8_t[client_buffer_size_bytes_]);
125 } 132 }
126 133
127 StartThread(); 134 StartThread();
128 } 135 }
129 136
130 void PPB_Audio_Shared::StartThread() { 137 bool PPB_Audio_Shared::StartThread() {
138 #if defined(OS_NACL)
139 // Use NaCl's special API for IRT code that creates threads that call back
140 // into user code.
141 if (NULL == thread_functions.thread_create ||
142 NULL == thread_functions.thread_join)
143 return false;
144 #endif
145
131 // Don't start the thread unless all our state is set up correctly. 146 // Don't start the thread unless all our state is set up correctly.
132 if (!playing_ || !callback_.IsValid() || !socket_.get() || 147 if (!playing_ || !callback_.IsValid() || !socket_.get() ||
133 !shared_memory_->memory() || !audio_bus_.get() || !client_buffer_.get() || 148 !shared_memory_->memory() || !audio_bus_.get() || !client_buffer_.get() ||
134 bytes_per_second_ == 0) 149 bytes_per_second_ == 0)
135 return; 150 return true;
151
136 // Clear contents of shm buffer before starting audio thread. This will 152 // Clear contents of shm buffer before starting audio thread. This will
137 // prevent a burst of static if for some reason the audio thread doesn't 153 // prevent a burst of static if for some reason the audio thread doesn't
138 // start up quickly enough. 154 // start up quickly enough.
139 memset(shared_memory_->memory(), 0, shared_memory_size_); 155 memset(shared_memory_->memory(), 0, shared_memory_size_);
140 memset(client_buffer_.get(), 0, client_buffer_size_bytes_); 156 memset(client_buffer_.get(), 0, client_buffer_size_bytes_);
141 #if !defined(OS_NACL) 157 #if !defined(OS_NACL)
142 DCHECK(!audio_thread_.get()); 158 DCHECK(!audio_thread_.get());
143 audio_thread_.reset( 159 audio_thread_.reset(
144 new base::DelegateSimpleThread(this, "plugin_audio_thread")); 160 new base::DelegateSimpleThread(this, "plugin_audio_thread"));
145 audio_thread_->Start(); 161 audio_thread_->Start();
146 #else 162 #else
147 // Use NaCl's special API for IRT code that creates threads that call back 163 DCHECK(!thread_active_);
148 // into user code.
149 if (NULL == thread_functions.thread_create ||
150 NULL == thread_functions.thread_join)
151 return;
152
153 int result = thread_functions.thread_create(&thread_id_, CallRun, this); 164 int result = thread_functions.thread_create(&thread_id_, CallRun, this);
154 DCHECK_EQ(result, 0); 165 DCHECK_EQ(result, 0);
155 thread_active_ = true; 166 thread_active_ = true;
156 #endif 167 #endif
168 return true;
157 } 169 }
158 170
159 void PPB_Audio_Shared::StopThread() { 171 void PPB_Audio_Shared::StopThread() {
160 #if !defined(OS_NACL) 172 #if !defined(OS_NACL)
161 if (audio_thread_.get()) { 173 if (audio_thread_.get()) {
162 // In general, the audio thread should not do Pepper calls, but it might 174 // In general, the audio thread should not do Pepper calls, but it might
163 // anyway (for example, our Audio test does CallOnMainThread). If it did 175 // anyway (for example, our Audio test does CallOnMainThread). If it did
164 // a pepper call which acquires the lock (most of them do), and we try to 176 // a pepper call which acquires the lock (most of them do), and we try to
165 // shut down the thread and Join it while holding the lock, we would 177 // shut down the thread and Join it while holding the lock, we would
166 // deadlock. So we give up the lock here so that the thread at least _can_ 178 // deadlock. So we give up the lock here so that the thread at least _can_
167 // make Pepper calls without causing deadlock. 179 // make Pepper calls without causing deadlock.
168 CallWhileUnlocked(base::Bind(&base::DelegateSimpleThread::Join, 180 CallWhileUnlocked(base::Bind(&base::DelegateSimpleThread::Join,
169 base::Unretained(audio_thread_.get()))); 181 base::Unretained(audio_thread_.get())));
170 audio_thread_.reset(); 182 audio_thread_.reset();
171 } 183 }
172 #else 184 #else
173 if (thread_active_) { 185 if (thread_active_) {
174 // See comment above about why we unlock here. 186 // See comment above about why we unlock here.
175 int result = CallWhileUnlocked(thread_functions.thread_join, thread_id_); 187 int result = CallWhileUnlocked(thread_functions.thread_join, thread_id_);
176 DCHECK_EQ(0, result); 188 DCHECK_EQ(0, result);
177 thread_active_ = false; 189 thread_active_ = false;
178 } 190 }
179 #endif 191 #endif
180 } 192 }
181 193
182 #if defined(OS_NACL) 194 #if defined(OS_NACL)
183 // static 195 // static
184 void PPB_Audio_Shared::SetThreadFunctions( 196 void PPB_Audio_Shared::SetThreadFunctions(
185 const struct PP_ThreadFunctions* functions) { 197 const struct PP_ThreadFunctions* functions) {
186 DCHECK(thread_functions.thread_create == NULL);
187 DCHECK(thread_functions.thread_join == NULL);
188 thread_functions = *functions; 198 thread_functions = *functions;
189 } 199 }
190 200
191 // static 201 // static
192 void PPB_Audio_Shared::CallRun(void* self) { 202 void PPB_Audio_Shared::CallRun(void* self) {
193 PPB_Audio_Shared* audio = static_cast<PPB_Audio_Shared*>(self); 203 PPB_Audio_Shared* audio = static_cast<PPB_Audio_Shared*>(self);
194 audio->Run(); 204 audio->Run();
195 } 205 }
196 #endif 206 #endif
197 207
(...skipping 20 matching lines...) Expand all
218 // Let the other end know which buffer we just filled. The buffer index is 228 // Let the other end know which buffer we just filled. The buffer index is
219 // used to ensure the other end is getting the buffer it expects. For more 229 // used to ensure the other end is getting the buffer it expects. For more
220 // details on how this works see AudioSyncReader::WaitUntilDataIsReady(). 230 // details on how this works see AudioSyncReader::WaitUntilDataIsReady().
221 size_t bytes_sent = socket_->Send(&buffer_index_, sizeof(buffer_index_)); 231 size_t bytes_sent = socket_->Send(&buffer_index_, sizeof(buffer_index_));
222 if (bytes_sent != sizeof(buffer_index_)) 232 if (bytes_sent != sizeof(buffer_index_))
223 break; 233 break;
224 } 234 }
225 } 235 }
226 236
227 } // namespace ppapi 237 } // namespace ppapi
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698