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

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

Issue 200283002: Fix the crash for the AudioShared. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@open_resource3
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
« no previous file with comments | « ppapi/shared_impl/ppb_audio_shared.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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/nacl_irt/public/irt_ppapi.h"
8 #include "ppapi/shared_impl/ppapi_globals.h" 9 #include "ppapi/shared_impl/ppapi_globals.h"
9 #include "ppapi/shared_impl/ppb_audio_config_shared.h" 10 #include "ppapi/shared_impl/ppb_audio_config_shared.h"
10 #include "ppapi/shared_impl/proxy_lock.h" 11 #include "ppapi/shared_impl/proxy_lock.h"
11 12
12 namespace ppapi { 13 namespace ppapi {
13 14
14 #if defined(OS_NACL)
15 namespace { 15 namespace {
16 bool g_nacl_mode = false;
16 // Because this is static, the function pointers will be NULL initially. 17 // Because this is static, the function pointers will be NULL initially.
17 PP_ThreadFunctions thread_functions; 18 PP_ThreadFunctions g_thread_functions;
18 } 19 }
19 #endif // defined(OS_NACL)
20 20
21 AudioCallbackCombined::AudioCallbackCombined() 21 AudioCallbackCombined::AudioCallbackCombined()
22 : callback_1_0_(NULL), callback_(NULL) {} 22 : callback_1_0_(NULL), callback_(NULL) {}
23 23
24 AudioCallbackCombined::AudioCallbackCombined( 24 AudioCallbackCombined::AudioCallbackCombined(
25 PPB_Audio_Callback_1_0 callback_1_0) 25 PPB_Audio_Callback_1_0 callback_1_0)
26 : callback_1_0_(callback_1_0), callback_(NULL) {} 26 : callback_1_0_(callback_1_0), callback_(NULL) {}
27 27
28 AudioCallbackCombined::AudioCallbackCombined(PPB_Audio_Callback callback) 28 AudioCallbackCombined::AudioCallbackCombined(PPB_Audio_Callback callback)
29 : callback_1_0_(NULL), callback_(callback) {} 29 : callback_1_0_(NULL), callback_(callback) {}
(...skipping 13 matching lines...) Expand all
43 } else if (callback_1_0_) { 43 } else if (callback_1_0_) {
44 callback_1_0_(sample_buffer, buffer_size_in_bytes, user_data); 44 callback_1_0_(sample_buffer, buffer_size_in_bytes, user_data);
45 } else { 45 } else {
46 NOTREACHED(); 46 NOTREACHED();
47 } 47 }
48 } 48 }
49 49
50 PPB_Audio_Shared::PPB_Audio_Shared() 50 PPB_Audio_Shared::PPB_Audio_Shared()
51 : playing_(false), 51 : playing_(false),
52 shared_memory_size_(0), 52 shared_memory_size_(0),
53 #if defined(OS_NACL) 53 nacl_thread_active_(false),
54 thread_id_(0),
55 thread_active_(false),
56 #endif
57 user_data_(NULL), 54 user_data_(NULL),
58 client_buffer_size_bytes_(0), 55 client_buffer_size_bytes_(0),
59 bytes_per_second_(0), 56 bytes_per_second_(0),
60 buffer_index_(0) { 57 buffer_index_(0) {
61 } 58 }
62 59
63 PPB_Audio_Shared::~PPB_Audio_Shared() { 60 PPB_Audio_Shared::~PPB_Audio_Shared() {
64 // Shut down the socket to escape any hanging |Receive|s. 61 // Shut down the socket to escape any hanging |Receive|s.
65 if (socket_.get()) 62 if (socket_.get())
66 socket_->Shutdown(); 63 socket_->Shutdown();
67 StopThread(); 64 StopThread();
68 } 65 }
69 66
70 void PPB_Audio_Shared::SetCallback(const AudioCallbackCombined& callback, 67 void PPB_Audio_Shared::SetCallback(const AudioCallbackCombined& callback,
71 void* user_data) { 68 void* user_data) {
72 callback_ = callback; 69 callback_ = callback;
73 user_data_ = user_data; 70 user_data_ = user_data;
74 } 71 }
75 72
76 void PPB_Audio_Shared::SetStartPlaybackState() { 73 void PPB_Audio_Shared::SetStartPlaybackState() {
77 DCHECK(!playing_); 74 DCHECK(!playing_);
78 #if !defined(OS_NACL)
79 DCHECK(!audio_thread_.get()); 75 DCHECK(!audio_thread_.get());
80 #else 76 DCHECK(!nacl_thread_active_);
81 DCHECK(!thread_active_);
82 #endif
83 // If the socket doesn't exist, that means that the plugin has started before 77 // 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 78 // 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_ 79 // 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 80 // flag and the playback will automatically start when that data is available
87 // in SetStreamInfo. 81 // in SetStreamInfo.
88 playing_ = true; 82 playing_ = true;
89 StartThread(); 83 StartThread();
90 } 84 }
91 85
92 void PPB_Audio_Shared::SetStopPlaybackState() { 86 void PPB_Audio_Shared::SetStopPlaybackState() {
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
131 // Don't start the thread unless all our state is set up correctly. 125 // Don't start the thread unless all our state is set up correctly.
132 if (!playing_ || !callback_.IsValid() || !socket_.get() || 126 if (!playing_ || !callback_.IsValid() || !socket_.get() ||
133 !shared_memory_->memory() || !audio_bus_.get() || !client_buffer_.get() || 127 !shared_memory_->memory() || !audio_bus_.get() || !client_buffer_.get() ||
134 bytes_per_second_ == 0) 128 bytes_per_second_ == 0)
135 return; 129 return;
136 // Clear contents of shm buffer before starting audio thread. This will 130 // 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 131 // prevent a burst of static if for some reason the audio thread doesn't
138 // start up quickly enough. 132 // start up quickly enough.
139 memset(shared_memory_->memory(), 0, shared_memory_size_); 133 memset(shared_memory_->memory(), 0, shared_memory_size_);
140 memset(client_buffer_.get(), 0, client_buffer_size_bytes_); 134 memset(client_buffer_.get(), 0, client_buffer_size_bytes_);
141 #if !defined(OS_NACL)
142 DCHECK(!audio_thread_.get());
143 audio_thread_.reset(
144 new base::DelegateSimpleThread(this, "plugin_audio_thread"));
145 audio_thread_->Start();
146 #else
147 // Use NaCl's special API for IRT code that creates threads that call back
148 // into user code.
149 if (!IsThreadFunctionReady())
150 return;
151 135
152 DCHECK(!thread_active_); 136 if (g_nacl_mode) {
153 int result = thread_functions.thread_create(&thread_id_, CallRun, this); 137 // Use NaCl's special API for IRT code that creates threads that call back
154 DCHECK_EQ(result, 0); 138 // into user code.
155 thread_active_ = true; 139 if (!IsThreadFunctionReady())
156 #endif 140 return;
141
142 DCHECK(!nacl_thread_active_);
143 int result =
144 g_thread_functions.thread_create(&nacl_thread_id_, CallRun, this);
145 DCHECK_EQ(0, result);
146 nacl_thread_active_ = true;
147 } else {
148 DCHECK(!audio_thread_.get());
149 audio_thread_.reset(
150 new base::DelegateSimpleThread(this, "plugin_audio_thread"));
151 audio_thread_->Start();
152 }
157 } 153 }
158 154
159 void PPB_Audio_Shared::StopThread() { 155 void PPB_Audio_Shared::StopThread() {
160 #if !defined(OS_NACL) 156 // In general, the audio thread should not do Pepper calls, but it might
161 if (audio_thread_.get()) { 157 // anyway (for example, our Audio test does CallOnMainThread). If it did a
162 // In general, the audio thread should not do Pepper calls, but it might 158 // pepper call which acquires the lock (most of them do), and we try to shut
163 // anyway (for example, our Audio test does CallOnMainThread). If it did 159 // down the thread and Join it while holding the lock, we would deadlock. So
164 // a pepper call which acquires the lock (most of them do), and we try to 160 // we give up the lock here so that the thread at least _can_ make Pepper
165 // shut down the thread and Join it while holding the lock, we would 161 // calls without causing deadlock.
166 // deadlock. So we give up the lock here so that the thread at least _can_ 162 if (g_nacl_mode) {
167 // make Pepper calls without causing deadlock. 163 if (nacl_thread_active_) {
168 CallWhileUnlocked(base::Bind(&base::DelegateSimpleThread::Join, 164 int result =
169 base::Unretained(audio_thread_.get()))); 165 CallWhileUnlocked(g_thread_functions.thread_join, nacl_thread_id_);
170 audio_thread_.reset(); 166 DCHECK_EQ(0, result);
167 nacl_thread_active_ = false;
168 }
169 } else {
170 if (audio_thread_.get()) {
171 CallWhileUnlocked(base::Bind(&base::DelegateSimpleThread::Join,
172 base::Unretained(audio_thread_.get())));
173 audio_thread_.reset();
174 }
171 } 175 }
172 #else
173 if (thread_active_) {
174 // See comment above about why we unlock here.
175 int result = CallWhileUnlocked(thread_functions.thread_join, thread_id_);
176 DCHECK_EQ(0, result);
177 thread_active_ = false;
178 }
179 #endif
180 } 176 }
181 177
182 // static 178 // static
183 bool PPB_Audio_Shared::IsThreadFunctionReady() { 179 bool PPB_Audio_Shared::IsThreadFunctionReady() {
184 #if defined(OS_NACL) 180 if (!g_nacl_mode)
185 if (thread_functions.thread_create == NULL || 181 return true;
186 thread_functions.thread_join == NULL) 182
187 return false; 183 return (g_thread_functions.thread_create != NULL &&
188 #endif 184 g_thread_functions.thread_join != NULL);
189 return true;
190 } 185 }
191 186
192 #if defined(OS_NACL) 187 // static
188 void PPB_Audio_Shared::SetNaClMode() {
189 g_nacl_mode = true;
190 }
191
193 // static 192 // static
194 void PPB_Audio_Shared::SetThreadFunctions( 193 void PPB_Audio_Shared::SetThreadFunctions(
195 const struct PP_ThreadFunctions* functions) { 194 const struct PP_ThreadFunctions* functions) {
196 thread_functions = *functions; 195 DCHECK(g_nacl_mode);
196 g_thread_functions = *functions;
197 } 197 }
198 198
199 // static 199 // static
200 void PPB_Audio_Shared::CallRun(void* self) { 200 void PPB_Audio_Shared::CallRun(void* self) {
201 PPB_Audio_Shared* audio = static_cast<PPB_Audio_Shared*>(self); 201 PPB_Audio_Shared* audio = static_cast<PPB_Audio_Shared*>(self);
202 audio->Run(); 202 audio->Run();
203 } 203 }
204 #endif
205 204
206 void PPB_Audio_Shared::Run() { 205 void PPB_Audio_Shared::Run() {
207 int pending_data = 0; 206 int pending_data = 0;
208 while (sizeof(pending_data) == 207 while (sizeof(pending_data) ==
209 socket_->Receive(&pending_data, sizeof(pending_data))) { 208 socket_->Receive(&pending_data, sizeof(pending_data))) {
210 // |buffer_index_| must track the number of Receive() calls. See the Send() 209 // |buffer_index_| must track the number of Receive() calls. See the Send()
211 // call below for why this is important. 210 // call below for why this is important.
212 ++buffer_index_; 211 ++buffer_index_;
213 if (pending_data < 0) 212 if (pending_data < 0)
214 break; 213 break;
(...skipping 11 matching lines...) Expand all
226 // Let the other end know which buffer we just filled. The buffer index is 225 // Let the other end know which buffer we just filled. The buffer index is
227 // used to ensure the other end is getting the buffer it expects. For more 226 // used to ensure the other end is getting the buffer it expects. For more
228 // details on how this works see AudioSyncReader::WaitUntilDataIsReady(). 227 // details on how this works see AudioSyncReader::WaitUntilDataIsReady().
229 size_t bytes_sent = socket_->Send(&buffer_index_, sizeof(buffer_index_)); 228 size_t bytes_sent = socket_->Send(&buffer_index_, sizeof(buffer_index_));
230 if (bytes_sent != sizeof(buffer_index_)) 229 if (bytes_sent != sizeof(buffer_index_))
231 break; 230 break;
232 } 231 }
233 } 232 }
234 233
235 } // namespace ppapi 234 } // namespace ppapi
OLDNEW
« no previous file with comments | « ppapi/shared_impl/ppb_audio_shared.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698