| OLD | NEW |
| 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 "base/bind.h" | 5 #include "base/bind.h" |
| 6 #include "base/memory/ref_counted.h" | 6 #include "base/memory/ref_counted.h" |
| 7 #include "base/message_loop/message_loop.h" | 7 #include "base/message_loop/message_loop.h" |
| 8 #include "ppapi/c/pp_completion_callback.h" | 8 #include "ppapi/c/pp_completion_callback.h" |
| 9 #include "ppapi/c/pp_errors.h" | 9 #include "ppapi/c/pp_errors.h" |
| 10 #include "ppapi/shared_impl/callback_tracker.h" | 10 #include "ppapi/shared_impl/callback_tracker.h" |
| 11 #include "ppapi/shared_impl/proxy_lock.h" |
| 11 #include "ppapi/shared_impl/resource.h" | 12 #include "ppapi/shared_impl/resource.h" |
| 12 #include "ppapi/shared_impl/resource_tracker.h" | 13 #include "ppapi/shared_impl/resource_tracker.h" |
| 13 #include "ppapi/shared_impl/test_globals.h" | 14 #include "ppapi/shared_impl/test_globals.h" |
| 14 #include "ppapi/shared_impl/tracked_callback.h" | 15 #include "ppapi/shared_impl/tracked_callback.h" |
| 15 #include "testing/gtest/include/gtest/gtest.h" | 16 #include "testing/gtest/include/gtest/gtest.h" |
| 16 | 17 |
| 17 namespace ppapi { | 18 namespace ppapi { |
| 18 | 19 |
| 19 namespace { | 20 namespace { |
| 20 | 21 |
| 21 class TrackedCallbackTest : public testing::Test { | 22 class TrackedCallbackTest : public testing::Test { |
| 22 public: | 23 public: |
| 23 TrackedCallbackTest() | 24 TrackedCallbackTest() |
| 24 : message_loop_(base::MessageLoop::TYPE_DEFAULT), pp_instance_(1234) {} | 25 : message_loop_(base::MessageLoop::TYPE_DEFAULT), pp_instance_(1234) {} |
| 25 | 26 |
| 26 PP_Instance pp_instance() const { return pp_instance_; } | 27 PP_Instance pp_instance() const { return pp_instance_; } |
| 27 | 28 |
| 28 virtual void SetUp() OVERRIDE { | 29 virtual void SetUp() OVERRIDE { |
| 30 ProxyLock::EnableLockingOnThreadForTest(); |
| 31 ProxyAutoLock lock; |
| 29 globals_.GetResourceTracker()->DidCreateInstance(pp_instance_); | 32 globals_.GetResourceTracker()->DidCreateInstance(pp_instance_); |
| 30 } | 33 } |
| 31 virtual void TearDown() OVERRIDE { | 34 virtual void TearDown() OVERRIDE { |
| 35 ProxyAutoLock lock; |
| 32 globals_.GetResourceTracker()->DidDeleteInstance(pp_instance_); | 36 globals_.GetResourceTracker()->DidDeleteInstance(pp_instance_); |
| 33 } | 37 } |
| 34 | 38 |
| 35 private: | 39 private: |
| 36 base::MessageLoop message_loop_; | 40 base::MessageLoop message_loop_; |
| 37 TestGlobals globals_; | 41 TestGlobals globals_; |
| 38 PP_Instance pp_instance_; | 42 PP_Instance pp_instance_; |
| 39 }; | 43 }; |
| 40 | 44 |
| 41 // All valid results (PP_OK, PP_ERROR_...) are nonpositive. | 45 // All valid results (PP_OK, PP_ERROR_...) are nonpositive. |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 82 private: | 86 private: |
| 83 CallbackRunInfo info_did_run_; | 87 CallbackRunInfo info_did_run_; |
| 84 CallbackRunInfo info_did_abort_; | 88 CallbackRunInfo info_did_abort_; |
| 85 CallbackRunInfo info_didnt_run_; | 89 CallbackRunInfo info_didnt_run_; |
| 86 }; | 90 }; |
| 87 | 91 |
| 88 } // namespace | 92 } // namespace |
| 89 | 93 |
| 90 // Tests that callbacks are properly aborted on module shutdown. | 94 // Tests that callbacks are properly aborted on module shutdown. |
| 91 TEST_F(CallbackShutdownTest, AbortOnShutdown) { | 95 TEST_F(CallbackShutdownTest, AbortOnShutdown) { |
| 96 ProxyAutoLock lock; |
| 92 scoped_refptr<Resource> resource(new Resource(OBJECT_IS_IMPL, pp_instance())); | 97 scoped_refptr<Resource> resource(new Resource(OBJECT_IS_IMPL, pp_instance())); |
| 93 | 98 |
| 94 // Set up case (1) (see above). | 99 // Set up case (1) (see above). |
| 95 EXPECT_EQ(0U, info_did_run().run_count); | 100 EXPECT_EQ(0U, info_did_run().run_count); |
| 96 scoped_refptr<TrackedCallback> callback_did_run = new TrackedCallback( | 101 scoped_refptr<TrackedCallback> callback_did_run = new TrackedCallback( |
| 97 resource.get(), | 102 resource.get(), |
| 98 PP_MakeCompletionCallback(&TestCallback, &info_did_run())); | 103 PP_MakeCompletionCallback(&TestCallback, &info_did_run())); |
| 99 EXPECT_EQ(0U, info_did_run().run_count); | 104 EXPECT_EQ(0U, info_did_run().run_count); |
| 100 callback_did_run->Run(PP_OK); | 105 callback_did_run->Run(PP_OK); |
| 101 EXPECT_EQ(1U, info_did_run().run_count); | 106 EXPECT_EQ(1U, info_did_run().run_count); |
| (...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 243 CallbackRunInfo info_did_abort_; | 248 CallbackRunInfo info_did_abort_; |
| 244 | 249 |
| 245 scoped_refptr<TrackedCallback> callback_didnt_run_; | 250 scoped_refptr<TrackedCallback> callback_didnt_run_; |
| 246 CallbackRunInfo info_didnt_run_; | 251 CallbackRunInfo info_didnt_run_; |
| 247 }; | 252 }; |
| 248 | 253 |
| 249 } // namespace | 254 } // namespace |
| 250 | 255 |
| 251 // Test that callbacks get aborted on the last resource unref. | 256 // Test that callbacks get aborted on the last resource unref. |
| 252 TEST_F(CallbackResourceTest, AbortOnNoRef) { | 257 TEST_F(CallbackResourceTest, AbortOnNoRef) { |
| 258 ProxyAutoLock lock; |
| 253 ResourceTracker* resource_tracker = | 259 ResourceTracker* resource_tracker = |
| 254 PpapiGlobals::Get()->GetResourceTracker(); | 260 PpapiGlobals::Get()->GetResourceTracker(); |
| 255 | 261 |
| 256 // Test several things: Unref-ing a resource (to zero refs) with callbacks | 262 // Test several things: Unref-ing a resource (to zero refs) with callbacks |
| 257 // which (1) have been run, (2) have been aborted, (3) haven't been completed. | 263 // which (1) have been run, (2) have been aborted, (3) haven't been completed. |
| 258 // Check that the uncompleted one gets aborted, and that the others don't get | 264 // Check that the uncompleted one gets aborted, and that the others don't get |
| 259 // called again. | 265 // called again. |
| 260 scoped_refptr<CallbackMockResource> resource_1( | 266 scoped_refptr<CallbackMockResource> resource_1( |
| 261 new CallbackMockResource(pp_instance())); | 267 new CallbackMockResource(pp_instance())); |
| 262 PP_Resource resource_1_id = resource_1->SetupForTest(); | 268 PP_Resource resource_1_id = resource_1->SetupForTest(); |
| 263 | 269 |
| 264 // Also do the same for a second resource, and make sure that unref-ing the | 270 // Also do the same for a second resource, and make sure that unref-ing the |
| 265 // first resource doesn't much up the second resource. | 271 // first resource doesn't much up the second resource. |
| 266 scoped_refptr<CallbackMockResource> resource_2( | 272 scoped_refptr<CallbackMockResource> resource_2( |
| 267 new CallbackMockResource(pp_instance())); | 273 new CallbackMockResource(pp_instance())); |
| 268 PP_Resource resource_2_id = resource_2->SetupForTest(); | 274 PP_Resource resource_2_id = resource_2->SetupForTest(); |
| 269 | 275 |
| 270 // Double-check that resource #1 is still okay. | 276 // Double-check that resource #1 is still okay. |
| 271 resource_1->CheckIntermediateState(); | 277 resource_1->CheckIntermediateState(); |
| 272 | 278 |
| 273 // Kill resource #1, spin the message loop to run posted calls, and check that | 279 // Kill resource #1, spin the message loop to run posted calls, and check that |
| 274 // things are in the expected states. | 280 // things are in the expected states. |
| 275 resource_tracker->ReleaseResource(resource_1_id); | 281 resource_tracker->ReleaseResource(resource_1_id); |
| 276 base::MessageLoop::current()->RunUntilIdle(); | 282 { |
| 283 ProxyAutoUnlock unlock; |
| 284 base::MessageLoop::current()->RunUntilIdle(); |
| 285 } |
| 277 resource_1->CheckFinalState(); | 286 resource_1->CheckFinalState(); |
| 278 resource_2->CheckIntermediateState(); | 287 resource_2->CheckIntermediateState(); |
| 279 | 288 |
| 280 // Kill resource #2. | 289 // Kill resource #2. |
| 281 resource_tracker->ReleaseResource(resource_2_id); | 290 resource_tracker->ReleaseResource(resource_2_id); |
| 282 base::MessageLoop::current()->RunUntilIdle(); | 291 { |
| 292 ProxyAutoUnlock unlock; |
| 293 base::MessageLoop::current()->RunUntilIdle(); |
| 294 } |
| 283 resource_1->CheckFinalState(); | 295 resource_1->CheckFinalState(); |
| 284 resource_2->CheckFinalState(); | 296 resource_2->CheckFinalState(); |
| 285 | 297 |
| 286 // This shouldn't be needed, but make sure there are no stranded tasks. | 298 // This shouldn't be needed, but make sure there are no stranded tasks. |
| 287 base::MessageLoop::current()->RunUntilIdle(); | 299 { |
| 300 ProxyAutoUnlock unlock; |
| 301 base::MessageLoop::current()->RunUntilIdle(); |
| 302 } |
| 288 } | 303 } |
| 289 | 304 |
| 290 // Test that "resurrecting" a resource (getting a new ID for a |Resource|) | 305 // Test that "resurrecting" a resource (getting a new ID for a |Resource|) |
| 291 // doesn't resurrect callbacks. | 306 // doesn't resurrect callbacks. |
| 292 TEST_F(CallbackResourceTest, Resurrection) { | 307 TEST_F(CallbackResourceTest, Resurrection) { |
| 308 ProxyAutoLock lock; |
| 293 ResourceTracker* resource_tracker = | 309 ResourceTracker* resource_tracker = |
| 294 PpapiGlobals::Get()->GetResourceTracker(); | 310 PpapiGlobals::Get()->GetResourceTracker(); |
| 295 | 311 |
| 296 scoped_refptr<CallbackMockResource> resource( | 312 scoped_refptr<CallbackMockResource> resource( |
| 297 new CallbackMockResource(pp_instance())); | 313 new CallbackMockResource(pp_instance())); |
| 298 PP_Resource resource_id = resource->SetupForTest(); | 314 PP_Resource resource_id = resource->SetupForTest(); |
| 299 | 315 |
| 300 // Unref it, spin the message loop to run posted calls, and check that things | 316 // Unref it, spin the message loop to run posted calls, and check that things |
| 301 // are in the expected states. | 317 // are in the expected states. |
| 302 resource_tracker->ReleaseResource(resource_id); | 318 resource_tracker->ReleaseResource(resource_id); |
| 303 base::MessageLoop::current()->RunUntilIdle(); | 319 { |
| 320 ProxyAutoUnlock unlock; |
| 321 base::MessageLoop::current()->RunUntilIdle(); |
| 322 } |
| 304 resource->CheckFinalState(); | 323 resource->CheckFinalState(); |
| 305 | 324 |
| 306 // "Resurrect" it and check that the callbacks are still dead. | 325 // "Resurrect" it and check that the callbacks are still dead. |
| 307 PP_Resource new_resource_id = resource->GetReference(); | 326 PP_Resource new_resource_id = resource->GetReference(); |
| 308 base::MessageLoop::current()->RunUntilIdle(); | 327 { |
| 328 ProxyAutoUnlock unlock; |
| 329 base::MessageLoop::current()->RunUntilIdle(); |
| 330 } |
| 309 resource->CheckFinalState(); | 331 resource->CheckFinalState(); |
| 310 | 332 |
| 311 // Unref it again and do the same. | 333 // Unref it again and do the same. |
| 312 resource_tracker->ReleaseResource(new_resource_id); | 334 resource_tracker->ReleaseResource(new_resource_id); |
| 313 base::MessageLoop::current()->RunUntilIdle(); | 335 { |
| 336 ProxyAutoUnlock unlock; |
| 337 base::MessageLoop::current()->RunUntilIdle(); |
| 338 } |
| 314 resource->CheckFinalState(); | 339 resource->CheckFinalState(); |
| 315 | 340 |
| 316 // This shouldn't be needed, but make sure there are no stranded tasks. | 341 // This shouldn't be needed, but make sure there are no stranded tasks. |
| 317 base::MessageLoop::current()->RunUntilIdle(); | 342 { |
| 343 ProxyAutoUnlock unlock; |
| 344 base::MessageLoop::current()->RunUntilIdle(); |
| 345 } |
| 318 } | 346 } |
| 319 | 347 |
| 320 } // namespace ppapi | 348 } // namespace ppapi |
| OLD | NEW |