diff options
author | scherkus@chromium.org <scherkus@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-06-17 20:40:37 +0000 |
---|---|---|
committer | scherkus@chromium.org <scherkus@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-06-17 20:40:37 +0000 |
commit | 9aa0f33d659f91cc92a3108fa52ac7e0bad7ade4 (patch) | |
tree | 054cb2d2d61754ef7134b917de632fbf6452c702 | |
parent | 6a0968853359103f9b13cb1652572509d902ea40 (diff) | |
download | chromium_src-9aa0f33d659f91cc92a3108fa52ac7e0bad7ade4.zip chromium_src-9aa0f33d659f91cc92a3108fa52ac7e0bad7ade4.tar.gz chromium_src-9aa0f33d659f91cc92a3108fa52ac7e0bad7ade4.tar.bz2 |
Cancel SimpleDataSource's request when stopped to prevent asserting.
BUG=http://crbug.com/13907
TEST=some media layout tests might start passing
Review URL: http://codereview.chromium.org/125229
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@18652 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | webkit/glue/media/simple_data_source.cc | 84 | ||||
-rw-r--r-- | webkit/glue/media/simple_data_source.h | 17 |
2 files changed, 79 insertions, 22 deletions
diff --git a/webkit/glue/media/simple_data_source.cc b/webkit/glue/media/simple_data_source.cc index 0d09f92..7cc541f 100644 --- a/webkit/glue/media/simple_data_source.cc +++ b/webkit/glue/media/simple_data_source.cc @@ -18,42 +18,39 @@ SimpleDataSource::SimpleDataSource(MessageLoop* render_loop, int32 routing_id) : routing_id_(routing_id), render_loop_(render_loop), size_(-1), - position_(0) { + position_(0), + state_(UNINITIALIZED) { DCHECK(render_loop); } SimpleDataSource::~SimpleDataSource() { + AutoLock auto_lock(lock_); + DCHECK(state_ == UNINITIALIZED || state_ == STOPPED); } -void SimpleDataSource::Stop() {} +void SimpleDataSource::Stop() { + AutoLock auto_lock(lock_); + state_ = STOPPED; + + // Post a task to the render thread to cancel loading the resource. + render_loop_->PostTask(FROM_HERE, + NewRunnableMethod(this, &SimpleDataSource::CancelTask)); +} bool SimpleDataSource::Initialize(const std::string& url) { - SetURL(GURL(url)); + AutoLock auto_lock(lock_); + DCHECK_EQ(state_, UNINITIALIZED); + state_ = INITIALIZING; // Validate the URL. + SetURL(GURL(url)); if (!url_.is_valid()) { return false; } - // Create our bridge and post a task to start loading the resource. - bridge_.reset(webkit_glue::ResourceLoaderBridge::Create( - "GET", - url_, - url_, - GURL::EmptyGURL(), // TODO(scherkus): provide referer here. - "null", // TODO(abarth): provide frame_origin - "null", // TODO(abarth): provide main_frame_origin - "", - net::LOAD_BYPASS_CACHE, - base::GetCurrentProcId(), - ResourceType::MEDIA, - // TODO(michaeln): delegate->mediaplayer->frame-> - // app_cache_context()->context_id() - // For now don't service media resource requests from the appcache. - WebAppCacheContext::kNoAppCacheContextId, - routing_id_)); + // Post a task to the render thread to start loading the resource. render_loop_->PostTask(FROM_HERE, - NewRunnableMethod(this, &SimpleDataSource::StartTask)); + NewRunnableMethod(this, &SimpleDataSource::StartTask)); return true; } @@ -110,7 +107,18 @@ void SimpleDataSource::OnReceivedData(const char* data, int len) { void SimpleDataSource::OnCompletedRequest(const URLRequestStatus& status, const std::string& security_info) { + AutoLock auto_lock(lock_); + // It's possible this gets called after Stop(), in which case |host_| is no + // longer valid. + if (state_ == STOPPED) { + return; + } + + // Otherwise we should be initializing and have created a bridge. + DCHECK_EQ(state_, INITIALIZING); + DCHECK(bridge_.get()); bridge_.reset(); + // If we don't get a content length or the request has failed, report it // as a network error. DCHECK(size_ == -1 || size_ == data_.length()); @@ -121,6 +129,9 @@ void SimpleDataSource::OnCompletedRequest(const URLRequestStatus& status, host_->Error(media::PIPELINE_ERROR_NETWORK); return; } + + // We're initialized! + state_ = INITIALIZED; host_->SetTotalBytes(size_); host_->SetBufferedBytes(size_); host_->InitializationComplete(); @@ -139,8 +150,39 @@ void SimpleDataSource::SetURL(const GURL& url) { } void SimpleDataSource::StartTask() { + AutoLock auto_lock(lock_); DCHECK(MessageLoop::current() == render_loop_); + DCHECK_EQ(state_, INITIALIZING); + + // Create our bridge and start loading the resource. + bridge_.reset(webkit_glue::ResourceLoaderBridge::Create( + "GET", + url_, + url_, + GURL::EmptyGURL(), // TODO(scherkus): provide referer here. + "null", // TODO(abarth): provide frame_origin + "null", // TODO(abarth): provide main_frame_origin + "", + net::LOAD_BYPASS_CACHE, + base::GetCurrentProcId(), + ResourceType::MEDIA, + // TODO(michaeln): delegate->mediaplayer->frame-> + // app_cache_context()->context_id() + // For now don't service media resource requests from the appcache. + WebAppCacheContext::kNoAppCacheContextId, + routing_id_)); bridge_->Start(this); } +void SimpleDataSource::CancelTask() { + AutoLock auto_lock(lock_); + DCHECK_EQ(state_, STOPPED); + + // Cancel any pending requests. + if (bridge_.get()) { + bridge_->Cancel(); + bridge_.reset(); + } +} + } // namespace webkit_glue diff --git a/webkit/glue/media/simple_data_source.h b/webkit/glue/media/simple_data_source.h index c1e0a00..55693ff 100644 --- a/webkit/glue/media/simple_data_source.h +++ b/webkit/glue/media/simple_data_source.h @@ -63,9 +63,12 @@ class SimpleDataSource : public media::DataSource, // Updates |url_| and |media_format_| with the given URL. void SetURL(const GURL& url); - // Start the resource loading on the render thread. + // Creates and starts the resource loading on the render thread. void StartTask(); + // Cancels and deletes the resource loading on the render thread. + void CancelTask(); + // Passed in during construction, used when creating the bridge. int32 routing_id_; @@ -81,6 +84,18 @@ class SimpleDataSource : public media::DataSource, int64 size_; int64 position_; + // Simple state tracking variable. + enum State { + UNINITIALIZED, + INITIALIZING, + INITIALIZED, + STOPPED, + }; + State state_; + + // Used for accessing |state_|. + Lock lock_; + DISALLOW_COPY_AND_ASSIGN(SimpleDataSource); }; |