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

Side by Side Diff: webkit/glue/media/buffered_data_source.cc

Issue 6342018: Fix a teardown hang caused by an Abort() call while there is a pending read. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fix DCHECK so it allows a state transition for teardown. Created 9 years, 11 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) 2010 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2010 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 "webkit/glue/media/buffered_data_source.h" 5 #include "webkit/glue/media/buffered_data_source.h"
6 6
7 #include "media/base/filter_host.h" 7 #include "media/base/filter_host.h"
8 #include "net/base/net_errors.h" 8 #include "net/base/net_errors.h"
9 #include "webkit/glue/webkit_glue.h" 9 #include "webkit/glue/webkit_glue.h"
10 10
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after
130 void BufferedDataSource::SetPlaybackRate(float playback_rate) { 130 void BufferedDataSource::SetPlaybackRate(float playback_rate) {
131 render_loop_->PostTask(FROM_HERE, 131 render_loop_->PostTask(FROM_HERE,
132 NewRunnableMethod(this, &BufferedDataSource::SetPlaybackRateTask, 132 NewRunnableMethod(this, &BufferedDataSource::SetPlaybackRateTask,
133 playback_rate)); 133 playback_rate));
134 } 134 }
135 135
136 ///////////////////////////////////////////////////////////////////////////// 136 /////////////////////////////////////////////////////////////////////////////
137 // media::DataSource implementation. 137 // media::DataSource implementation.
138 void BufferedDataSource::Read(int64 position, size_t size, uint8* data, 138 void BufferedDataSource::Read(int64 position, size_t size, uint8* data,
139 media::DataSource::ReadCallback* read_callback) { 139 media::DataSource::ReadCallback* read_callback) {
140 DCHECK(read_callback);
141
142 {
143 base::AutoLock auto_lock(lock_);
144 DCHECK(!read_callback_.get());
145
146 if (stop_signal_received_ || stopped_on_render_loop_) {
147 read_callback->RunWithParams(
148 Tuple1<size_t>(static_cast<size_t>(media::DataSource::kReadError)));
149 delete read_callback;
150 return;
151 }
152
153 read_callback_.reset(read_callback);
154 }
155
140 render_loop_->PostTask(FROM_HERE, 156 render_loop_->PostTask(FROM_HERE,
141 NewRunnableMethod(this, &BufferedDataSource::ReadTask, 157 NewRunnableMethod(this, &BufferedDataSource::ReadTask,
142 position, static_cast<int>(size), data, read_callback)); 158 position, static_cast<int>(size), data));
143 } 159 }
144 160
145 bool BufferedDataSource::GetSize(int64* size_out) { 161 bool BufferedDataSource::GetSize(int64* size_out) {
146 if (total_bytes_ != kPositionNotSpecified) { 162 if (total_bytes_ != kPositionNotSpecified) {
147 *size_out = total_bytes_; 163 *size_out = total_bytes_;
148 return true; 164 return true;
149 } 165 }
150 *size_out = 0; 166 *size_out = 0;
151 return false; 167 return false;
152 } 168 }
153 169
154 bool BufferedDataSource::IsStreaming() { 170 bool BufferedDataSource::IsStreaming() {
155 return streaming_; 171 return streaming_;
156 } 172 }
157 173
158 bool BufferedDataSource::HasSingleOrigin() { 174 bool BufferedDataSource::HasSingleOrigin() {
159 DCHECK(MessageLoop::current() == render_loop_); 175 DCHECK(MessageLoop::current() == render_loop_);
160 return single_origin_; 176 return single_origin_;
161 } 177 }
162 178
163 void BufferedDataSource::Abort() { 179 void BufferedDataSource::Abort() {
164 DCHECK(MessageLoop::current() == render_loop_); 180 DCHECK(MessageLoop::current() == render_loop_);
165 181
166 // If we are told to abort, immediately return from any pending read 182 {
167 // with an error. 183 base::AutoLock auto_lock(lock_);
168 if (read_callback_.get()) { 184
169 base::AutoLock auto_lock(lock_); 185 // If we are told to abort, immediately return from any pending read
186 // with an error.
187 if (read_callback_.get())
170 DoneRead_Locked(net::ERR_FAILED); 188 DoneRead_Locked(net::ERR_FAILED);
171 } 189 }
172 190
173 CleanupTask(); 191 CleanupTask();
174 frame_ = NULL; 192 frame_ = NULL;
175 } 193 }
176 194
177 ///////////////////////////////////////////////////////////////////////////// 195 /////////////////////////////////////////////////////////////////////////////
178 // Render thread tasks. 196 // Render thread tasks.
179 void BufferedDataSource::InitializeTask() { 197 void BufferedDataSource::InitializeTask() {
(...skipping 25 matching lines...) Expand all
205 loader_ = CreateResourceLoader(kPositionNotSpecified, 223 loader_ = CreateResourceLoader(kPositionNotSpecified,
206 kPositionNotSpecified); 224 kPositionNotSpecified);
207 loader_->Start( 225 loader_->Start(
208 NewCallback(this, &BufferedDataSource::NonHttpInitialStartCallback), 226 NewCallback(this, &BufferedDataSource::NonHttpInitialStartCallback),
209 NewCallback(this, &BufferedDataSource::NetworkEventCallback), 227 NewCallback(this, &BufferedDataSource::NetworkEventCallback),
210 frame_); 228 frame_);
211 } 229 }
212 } 230 }
213 231
214 void BufferedDataSource::ReadTask( 232 void BufferedDataSource::ReadTask(
215 int64 position, int read_size, uint8* buffer, 233 int64 position,
216 media::DataSource::ReadCallback* read_callback) { 234 int read_size,
235 uint8* buffer) {
217 DCHECK(MessageLoop::current() == render_loop_); 236 DCHECK(MessageLoop::current() == render_loop_);
218 if (stopped_on_render_loop_) 237 {
219 return; 238 base::AutoLock auto_lock(lock_);
239 if (stopped_on_render_loop_)
240 return;
220 241
221 DCHECK(!read_callback_.get()); 242 DCHECK(read_callback_.get());
222 DCHECK(read_callback); 243 }
223 244
224 // Saves the read parameters. 245 // Saves the read parameters.
225 read_position_ = position; 246 read_position_ = position;
226 read_size_ = read_size; 247 read_size_ = read_size;
227 read_callback_.reset(read_callback);
228 read_buffer_ = buffer; 248 read_buffer_ = buffer;
229 read_submitted_time_ = base::Time::Now(); 249 read_submitted_time_ = base::Time::Now();
230 read_attempts_ = 0; 250 read_attempts_ = 0;
231 251
232 // Call to read internal to perform the actual read. 252 // Call to read internal to perform the actual read.
233 ReadInternal(); 253 ReadInternal();
234 } 254 }
235 255
236 void BufferedDataSource::CleanupTask() { 256 void BufferedDataSource::CleanupTask() {
237 DCHECK(MessageLoop::current() == render_loop_); 257 DCHECK(MessageLoop::current() == render_loop_);
238 if (stopped_on_render_loop_) 258
239 return; 259 {
260 base::AutoLock auto_lock(lock_);
261 if (stopped_on_render_loop_)
262 return;
263
264 read_callback_.reset();
265 }
240 266
241 // Stop the watch dog. 267 // Stop the watch dog.
242 watch_dog_timer_.Stop(); 268 watch_dog_timer_.Stop();
243 269
244 // We just need to stop the loader, so it stops activity. 270 // We just need to stop the loader, so it stops activity.
245 if (loader_.get()) 271 if (loader_.get())
246 loader_->Stop(); 272 loader_->Stop();
247 273
248 // Reset the parameters of the current read request. 274 // Reset the parameters of the current read request.
249 read_callback_.reset();
250 read_position_ = 0; 275 read_position_ = 0;
251 read_size_ = 0; 276 read_size_ = 0;
252 read_buffer_ = 0; 277 read_buffer_ = 0;
253 read_submitted_time_ = base::Time(); 278 read_submitted_time_ = base::Time();
254 read_attempts_ = 0; 279 read_attempts_ = 0;
255 280
256 // Signal that stop task has finished execution. 281 // Signal that stop task has finished execution.
257 stopped_on_render_loop_ = true; 282 stopped_on_render_loop_ = true;
258 } 283 }
259 284
260 void BufferedDataSource::RestartLoadingTask() { 285 void BufferedDataSource::RestartLoadingTask() {
261 DCHECK(MessageLoop::current() == render_loop_); 286 DCHECK(MessageLoop::current() == render_loop_);
262 if (stopped_on_render_loop_) 287 if (stopped_on_render_loop_)
263 return; 288 return;
264 289
265 // If there's no outstanding read then return early. 290 {
266 if (!read_callback_.get()) 291 // If there's no outstanding read then return early.
267 return; 292 base::AutoLock auto_lock(lock_);
293 if (!read_callback_.get())
294 return;
295 }
268 296
269 loader_ = CreateResourceLoader(read_position_, kPositionNotSpecified); 297 loader_ = CreateResourceLoader(read_position_, kPositionNotSpecified);
270 loader_->SetAllowDefer(!media_is_paused_); 298 loader_->SetAllowDefer(!media_is_paused_);
271 loader_->Start( 299 loader_->Start(
272 NewCallback(this, &BufferedDataSource::PartialReadStartCallback), 300 NewCallback(this, &BufferedDataSource::PartialReadStartCallback),
273 NewCallback(this, &BufferedDataSource::NetworkEventCallback), 301 NewCallback(this, &BufferedDataSource::NetworkEventCallback),
274 frame_); 302 frame_);
275 } 303 }
276 304
277 void BufferedDataSource::WatchDogTask() { 305 void BufferedDataSource::WatchDogTask() {
278 DCHECK(MessageLoop::current() == render_loop_); 306 DCHECK(MessageLoop::current() == render_loop_);
279 if (stopped_on_render_loop_) 307 if (stopped_on_render_loop_)
280 return; 308 return;
281 309
282 // We only care if there is an active read request. 310 // We only care if there is an active read request.
283 if (!read_callback_.get()) 311 {
284 return; 312 base::AutoLock auto_lock(lock_);
313 if (!read_callback_.get())
314 return;
315 }
285 316
286 DCHECK(loader_.get()); 317 DCHECK(loader_.get());
287 base::TimeDelta delta = base::Time::Now() - read_submitted_time_; 318 base::TimeDelta delta = base::Time::Now() - read_submitted_time_;
288 if (delta < GetTimeoutMilliseconds()) 319 if (delta < GetTimeoutMilliseconds())
289 return; 320 return;
290 321
291 // TODO(hclam): Maybe raise an error here. But if an error is reported 322 // TODO(hclam): Maybe raise an error here. But if an error is reported
292 // the whole pipeline may get destroyed... 323 // the whole pipeline may get destroyed...
293 if (read_attempts_ >= kReadTrials) 324 if (read_attempts_ >= kReadTrials)
294 return; 325 return;
(...skipping 280 matching lines...) Expand 10 before | Expand all | Expand 10 after
575 return; 606 return;
576 607
577 if (network_activity != network_activity_) { 608 if (network_activity != network_activity_) {
578 network_activity_ = network_activity; 609 network_activity_ = network_activity;
579 host()->SetNetworkActivity(network_activity); 610 host()->SetNetworkActivity(network_activity);
580 } 611 }
581 host()->SetBufferedBytes(buffered_position + 1); 612 host()->SetBufferedBytes(buffered_position + 1);
582 } 613 }
583 614
584 } // namespace webkit_glue 615 } // namespace webkit_glue
OLDNEW
« no previous file with comments | « webkit/glue/media/buffered_data_source.h ('k') | webkit/glue/media/buffered_data_source_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698