Chromium Code Reviews| Index: webkit/glue/media/buffered_data_source_unittest.cc |
| diff --git a/webkit/glue/media/buffered_data_source_unittest.cc b/webkit/glue/media/buffered_data_source_unittest.cc |
| index 6e9a87d15dded92b600c33d6e3399db78ebbe665..f3708038a05314ae5d2d54e20bf88e861d430b92 100644 |
| --- a/webkit/glue/media/buffered_data_source_unittest.cc |
| +++ b/webkit/glue/media/buffered_data_source_unittest.cc |
| @@ -492,4 +492,70 @@ TEST_F(BufferedDataSourceTest, FileHasLoadedState) { |
| StopDataSource(); |
| } |
| +// This test makes sure that Stop() does not require a task to run on |
| +// |message_loop_| before it calls its callback. This prevents accidental |
| +// introduction of a pipeline teardown deadlock. The pipeline owner blocks |
| +// the render message loop while waiting for Stop() to complete. Since this |
| +// object runs on the render message loop, Stop() will not complete if it |
| +// requires a task to run on the the message loop that is being blocked. |
| +TEST_F(BufferedDataSourceTest, StopDoesNotUseMessageLoopForCallback) { |
| + InitializeDataSource(kFileUrl, net::OK, true, 1024, LOADED); |
| + |
| + // Create a callback that lets us verify that it was called before |
| + // Stop() returns. This is to make sure that the callback does not |
| + // require |message_loop_| to execute tasks before being called. |
| + media::MockCallback* stop_callback = media::NewExpectedCallback(); |
| + bool stop_done_called = false; |
| + ON_CALL(*stop_callback, RunWithParams(_)) |
|
scherkus (not reviewing)
2011/01/26 03:04:10
nice usage :)
to confirm this keeps the expectati
acolwell GONE FROM CHROMIUM
2011/01/26 17:41:05
Thanks.
|
| + .WillByDefault(Assign(&stop_done_called, true)); |
| + |
| + // Stop() the data source like normal. |
| + data_source_->Stop(stop_callback); |
| + |
| + // Verify that the callback was called inside the Stop() call. |
| + EXPECT_TRUE(stop_done_called); |
| + |
| + message_loop_->RunAllPending(); |
| +} |
| + |
| +TEST_F(BufferedDataSourceTest, AbortDuringPendingRead) { |
| + InitializeDataSource(kFileUrl, net::OK, true, 1024, LOADED); |
| + |
| + // Setup a way to verify that Read() is not called on the loader. |
| + // We are doing this to make sure that the ReadTask() is still on |
| + // the message loop queue when Abort() is called. |
| + bool read_called = false; |
| + ON_CALL(*loader_, Read(_, _, _ , _)) |
| + .WillByDefault(DoAll(Assign(&read_called, true), |
| + DeleteArg<3>())); |
| + |
| + // Initiate a Read() on the data source, but don't allow the |
| + // message loop to run. |
| + data_source_->Read( |
| + 0, 10, buffer_, |
| + NewCallback(static_cast<BufferedDataSourceTest*>(this), |
| + &BufferedDataSourceTest::ReadCallback)); |
| + |
| + // Call Abort() with the read pending. |
| + EXPECT_CALL(*this, ReadCallback(-1)); |
| + EXPECT_CALL(*loader_, Stop()); |
| + data_source_->Abort(); |
| + |
| + // Verify that Read()'s after the Abort() issue callback with an error. |
| + EXPECT_CALL(*this, ReadCallback(-1)); |
| + data_source_->Read( |
| + 0, 10, buffer_, |
| + NewCallback(static_cast<BufferedDataSourceTest*>(this), |
| + &BufferedDataSourceTest::ReadCallback)); |
| + |
| + // Stop() the data source like normal. |
| + data_source_->Stop(media::NewExpectedCallback()); |
| + |
| + // Allow cleanup task to run. |
| + message_loop_->RunAllPending(); |
| + |
| + // Verify that Read() was not called on the loader. |
| + EXPECT_FALSE(read_called); |
| +} |
| + |
| } // namespace webkit_glue |