summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorscherkus@chromium.org <scherkus@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-06-17 20:40:37 +0000
committerscherkus@chromium.org <scherkus@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-06-17 20:40:37 +0000
commit9aa0f33d659f91cc92a3108fa52ac7e0bad7ade4 (patch)
tree054cb2d2d61754ef7134b917de632fbf6452c702
parent6a0968853359103f9b13cb1652572509d902ea40 (diff)
downloadchromium_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.cc84
-rw-r--r--webkit/glue/media/simple_data_source.h17
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);
};