Index: ppapi/proxy/tracked_callback_unittest.cc |
diff --git a/ppapi/shared_impl/tracked_callback_unittest.cc b/ppapi/proxy/tracked_callback_unittest.cc |
similarity index 37% |
rename from ppapi/shared_impl/tracked_callback_unittest.cc |
rename to ppapi/proxy/tracked_callback_unittest.cc |
index 12ad4235bdb66341e0c82a7b922e4864d38caf8b..dfd6c26b8bc0824562136aeeb9e05ef4b871a7d0 100644 |
--- a/ppapi/shared_impl/tracked_callback_unittest.cc |
+++ b/ppapi/proxy/tracked_callback_unittest.cc |
@@ -5,39 +5,89 @@ |
#include "base/bind.h" |
#include "base/memory/ref_counted.h" |
#include "base/message_loop/message_loop.h" |
+#include "base/run_loop.h" |
+#include "base/synchronization/waitable_event.h" |
+#include "base/threading/simple_thread.h" |
#include "ppapi/c/pp_completion_callback.h" |
#include "ppapi/c/pp_errors.h" |
+#include "ppapi/proxy/ppapi_proxy_test.h" |
+#include "ppapi/proxy/ppb_message_loop_proxy.h" |
#include "ppapi/shared_impl/callback_tracker.h" |
#include "ppapi/shared_impl/proxy_lock.h" |
#include "ppapi/shared_impl/resource.h" |
#include "ppapi/shared_impl/resource_tracker.h" |
+#include "ppapi/shared_impl/scoped_pp_resource.h" |
#include "ppapi/shared_impl/test_globals.h" |
#include "ppapi/shared_impl/tracked_callback.h" |
#include "testing/gtest/include/gtest/gtest.h" |
+// Note, this file tests TrackedCallback which lives in ppapi/shared_impl. |
+// Unfortunately, we need the test to live in ppapi/proxy so that it can use |
+// the thread support there. |
namespace ppapi { |
+namespace proxy { |
namespace { |
-class TrackedCallbackTest : public testing::Test { |
+class CallbackThread : public base::SimpleThread { |
public: |
- TrackedCallbackTest() : pp_instance_(1234) {} |
- |
- PP_Instance pp_instance() const { return pp_instance_; } |
- |
- virtual void SetUp() override { |
- ProxyAutoLock lock; |
- globals_.GetResourceTracker()->DidCreateInstance(pp_instance_); |
+ explicit CallbackThread(PP_Instance instance) |
+ : SimpleThread("CallbackThread"), instance_(instance) {} |
+ ~CallbackThread() override {} |
+ |
+ // base::SimpleThread overrides. |
+ void Start() override { |
+ { |
+ ProxyAutoLock acquire; |
+ // Create the message loop here, after PpapiGlobals has been created. |
+ message_loop_ = new MessageLoopResource(instance_); |
+ } |
+ base::SimpleThread::Start(); |
} |
- virtual void TearDown() override { |
- ProxyAutoLock lock; |
- globals_.GetResourceTracker()->DidDeleteInstance(pp_instance_); |
+ void Join() override { |
+ { |
+ ProxyAutoLock acquire; |
+ message_loop()->PostQuit(PP_TRUE); |
+ message_loop_ = nullptr; |
+ } |
+ base::SimpleThread::Join(); |
} |
+ void Run() override { |
+ ProxyAutoLock acquire; |
+ // Make a local copy of message_loop_ for this thread so we can interact |
+ // with it even after the main thread releases it. |
+ scoped_refptr<MessageLoopResource> message_loop(message_loop_); |
+ message_loop->AttachToCurrentThread(); |
+ // Note, run releases the lock to run events. |
+ message_loop->Run(); |
+ message_loop->DetachFromThread(); |
+ } |
+ |
+ MessageLoopResource* message_loop() { return message_loop_.get(); } |
private: |
- base::MessageLoop message_loop_; |
- TestGlobals globals_; |
- PP_Instance pp_instance_; |
+ PP_Instance instance_; |
+ scoped_refptr<MessageLoopResource> message_loop_; |
+}; |
+ |
+class TrackedCallbackTest : public PluginProxyTest { |
+ public: |
+ TrackedCallbackTest() : thread_(pp_instance()) {} |
+ CallbackThread& thread() { return thread_; } |
+ |
+ private: |
+ // PluginProxyTest overrides. |
+ void SetUp() override { |
+ PluginProxyTest::SetUp(); |
+ thread_.Start(); |
+ } |
+ void TearDown() override { |
+ thread_.Join(); |
+ PluginProxyTest::TearDown(); |
+ base::RunLoop run_loop; |
+ run_loop.RunUntilIdle(); |
+ } |
+ CallbackThread thread_; |
}; |
// All valid results (PP_OK, PP_ERROR_...) are nonpositive. |
@@ -45,33 +95,56 @@ const int32_t kInitializedResultValue = 1; |
const int32_t kOverrideResultValue = 2; |
struct CallbackRunInfo { |
- CallbackRunInfo() |
- : run_count(0), |
- result(kInitializedResultValue), |
- completion_task_run_count(0), |
- completion_task_result(kInitializedResultValue) {} |
- unsigned run_count; |
- int32_t result; |
- unsigned completion_task_run_count; |
- int32_t completion_task_result; |
+ explicit CallbackRunInfo(base::ThreadChecker* thread_checker) |
+ : run_count_(0), |
+ result_(kInitializedResultValue), |
+ completion_task_run_count_(0), |
+ completion_task_result_(kInitializedResultValue), |
+ thread_checker_(thread_checker), |
+ callback_did_run_event_(true, false) {} |
+ void CallbackDidRun(int32_t result) { |
+ CHECK(thread_checker_->CalledOnValidThread()); |
+ if (!run_count_) |
+ result_ = result; |
+ ++run_count_; |
+ callback_did_run_event_.Signal(); |
+ } |
+ void CompletionTaskDidRun(int32_t result) { |
+ CHECK(thread_checker_->CalledOnValidThread()); |
+ if (!completion_task_run_count_) |
+ completion_task_result_ = result; |
+ ++completion_task_run_count_; |
+ } |
+ void WaitUntilCompleted() { callback_did_run_event_.Wait(); } |
+ unsigned run_count() { return run_count_; } |
+ int32_t result() { return result_; } |
+ unsigned completion_task_run_count() { return completion_task_run_count_; } |
+ int32_t completion_task_result() { return completion_task_result_; } |
+ |
+ private: |
+ unsigned run_count_; |
+ int32_t result_; |
+ unsigned completion_task_run_count_; |
+ int32_t completion_task_result_; |
+ // Weak; owned by the creator of CallbackRunInfo. |
+ base::ThreadChecker* thread_checker_; |
+ |
+ base::WaitableEvent callback_did_run_event_; |
}; |
void TestCallback(void* user_data, int32_t result) { |
- CallbackRunInfo* info = reinterpret_cast<CallbackRunInfo*>(user_data); |
- info->run_count++; |
- if (info->run_count == 1) |
- info->result = result; |
+ CallbackRunInfo* info = static_cast<CallbackRunInfo*>(user_data); |
+ info->CallbackDidRun(result); |
} |
-} // namespace |
- |
// CallbackShutdownTest -------------------------------------------------------- |
-namespace { |
- |
class CallbackShutdownTest : public TrackedCallbackTest { |
public: |
- CallbackShutdownTest() {} |
+ CallbackShutdownTest() |
+ : info_did_run_(&thread_checker_), |
+ info_did_abort_(&thread_checker_), |
+ info_didnt_run_(&thread_checker_) {} |
// Cases: |
// (1) A callback which is run (so shouldn't be aborted on shutdown). |
@@ -82,6 +155,7 @@ class CallbackShutdownTest : public TrackedCallbackTest { |
CallbackRunInfo& info_didnt_run() { return info_didnt_run_; } // (3) |
private: |
+ base::ThreadChecker thread_checker_; |
CallbackRunInfo info_did_run_; |
CallbackRunInfo info_did_abort_; |
CallbackRunInfo info_didnt_run_; |
@@ -92,46 +166,48 @@ class CallbackShutdownTest : public TrackedCallbackTest { |
// Tests that callbacks are properly aborted on module shutdown. |
TEST_F(CallbackShutdownTest, AbortOnShutdown) { |
ProxyAutoLock lock; |
- scoped_refptr<Resource> resource(new Resource(OBJECT_IS_IMPL, pp_instance())); |
+ scoped_refptr<Resource> resource( |
+ new Resource(OBJECT_IS_PROXY, pp_instance())); |
// Set up case (1) (see above). |
- EXPECT_EQ(0U, info_did_run().run_count); |
+ EXPECT_EQ(0U, info_did_run().run_count()); |
+ // TODO(dmichael): Test this on a background thread? |
scoped_refptr<TrackedCallback> callback_did_run = new TrackedCallback( |
resource.get(), |
PP_MakeCompletionCallback(&TestCallback, &info_did_run())); |
- EXPECT_EQ(0U, info_did_run().run_count); |
+ EXPECT_EQ(0U, info_did_run().run_count()); |
callback_did_run->Run(PP_OK); |
- EXPECT_EQ(1U, info_did_run().run_count); |
- EXPECT_EQ(PP_OK, info_did_run().result); |
+ EXPECT_EQ(1U, info_did_run().run_count()); |
+ EXPECT_EQ(PP_OK, info_did_run().result()); |
// Set up case (2). |
- EXPECT_EQ(0U, info_did_abort().run_count); |
+ EXPECT_EQ(0U, info_did_abort().run_count()); |
scoped_refptr<TrackedCallback> callback_did_abort = new TrackedCallback( |
resource.get(), |
PP_MakeCompletionCallback(&TestCallback, &info_did_abort())); |
- EXPECT_EQ(0U, info_did_abort().run_count); |
+ EXPECT_EQ(0U, info_did_abort().run_count()); |
callback_did_abort->Abort(); |
- EXPECT_EQ(1U, info_did_abort().run_count); |
- EXPECT_EQ(PP_ERROR_ABORTED, info_did_abort().result); |
+ EXPECT_EQ(1U, info_did_abort().run_count()); |
+ EXPECT_EQ(PP_ERROR_ABORTED, info_did_abort().result()); |
// Set up case (3). |
- EXPECT_EQ(0U, info_didnt_run().run_count); |
+ EXPECT_EQ(0U, info_didnt_run().run_count()); |
scoped_refptr<TrackedCallback> callback_didnt_run = new TrackedCallback( |
resource.get(), |
PP_MakeCompletionCallback(&TestCallback, &info_didnt_run())); |
- EXPECT_EQ(0U, info_didnt_run().run_count); |
+ EXPECT_EQ(0U, info_didnt_run().run_count()); |
- PpapiGlobals::Get()->GetCallbackTrackerForInstance(pp_instance())->AbortAll(); |
+ GetGlobals()->GetCallbackTrackerForInstance(pp_instance())->AbortAll(); |
// Check case (1). |
- EXPECT_EQ(1U, info_did_run().run_count); |
+ EXPECT_EQ(1U, info_did_run().run_count()); |
// Check case (2). |
- EXPECT_EQ(1U, info_did_abort().run_count); |
+ EXPECT_EQ(1U, info_did_abort().run_count()); |
// Check case (3). |
- EXPECT_EQ(1U, info_didnt_run().run_count); |
- EXPECT_EQ(PP_ERROR_ABORTED, info_didnt_run().result); |
+ EXPECT_EQ(1U, info_didnt_run().run_count()); |
+ EXPECT_EQ(PP_ERROR_ABORTED, info_didnt_run().result()); |
} |
// CallbackResourceTest -------------------------------------------------------- |
@@ -145,93 +221,157 @@ class CallbackResourceTest : public TrackedCallbackTest { |
class CallbackMockResource : public Resource { |
public: |
- CallbackMockResource(PP_Instance instance) |
- : Resource(OBJECT_IS_IMPL, instance) {} |
+ static scoped_refptr<CallbackMockResource> Create(PP_Instance instance) { |
+ ProxyAutoLock acquire; |
+ return scoped_refptr<CallbackMockResource>( |
+ new CallbackMockResource(instance)); |
+ } |
~CallbackMockResource() {} |
- PP_Resource SetupForTest() { |
- PP_Resource resource_id = GetReference(); |
- EXPECT_NE(0, resource_id); |
+ // Take a reference to this resource, which will add it to the tracker. |
+ void TakeRef() { |
+ ProxyAutoLock acquire; |
+ ScopedPPResource temp_resource(ScopedPPResource::PassRef(), GetReference()); |
+ EXPECT_NE(0, temp_resource.get()); |
+ reference_holder_ = temp_resource; |
+ } |
+ // Release it, removing it from the tracker. |
+ void ReleaseRef() { |
+ ProxyAutoLock acquire; |
+ reference_holder_ = 0; |
+ } |
+ |
+ // Create the test callbacks on a background thread, so that we can verify |
+ // they are run on the same thread where they were created. |
+ void CreateCallbacksOnLoop(MessageLoopResource* loop_resource) { |
+ ProxyAutoLock acquire; |
+ // |thread_checker_| will bind to the background thread. |
+ thread_checker_.DetachFromThread(); |
+ loop_resource->message_loop_proxy()->PostTask( |
+ FROM_HERE, RunWhileLocked(base::Bind( |
+ &CallbackMockResource::CreateCallbacks, this))); |
+ } |
+ |
+ int32_t CompletionTask(CallbackRunInfo* info, int32_t result) { |
+ // The completion task must run on the thread where the callback was |
+ // created, and must hold the proxy lock. |
+ CHECK(thread_checker_.CalledOnValidThread()); |
+ ProxyLock::AssertAcquired(); |
+ |
+ // We should run before the callback. |
+ CHECK_EQ(0U, info->run_count()); |
+ info->CompletionTaskDidRun(result); |
+ return kOverrideResultValue; |
+ } |
+ |
+ void CheckInitialState() { |
+ callbacks_created_event_.Wait(); |
+ EXPECT_EQ(0U, info_did_run_.run_count()); |
+ EXPECT_EQ(0U, info_did_run_.completion_task_run_count()); |
+ |
+ EXPECT_EQ(0U, info_did_run_with_completion_task_.run_count()); |
+ EXPECT_EQ(0U, |
+ info_did_run_with_completion_task_.completion_task_run_count()); |
+ |
+ EXPECT_EQ(0U, info_did_abort_.run_count()); |
+ EXPECT_EQ(0U, info_did_abort_.completion_task_run_count()); |
+ |
+ EXPECT_EQ(0U, info_didnt_run_.run_count()); |
+ EXPECT_EQ(0U, info_didnt_run_.completion_task_run_count()); |
+ } |
+ |
+ void RunCallbacks() { |
+ callback_did_run_->Run(PP_OK); |
+ callback_did_run_with_completion_task_->Run(PP_OK); |
+ callback_did_abort_->Abort(); |
+ info_did_run_.WaitUntilCompleted(); |
+ info_did_run_with_completion_task_.WaitUntilCompleted(); |
+ info_did_abort_.WaitUntilCompleted(); |
+ } |
+ |
+ void CheckIntermediateState() { |
+ EXPECT_EQ(1U, info_did_run_.run_count()); |
+ EXPECT_EQ(PP_OK, info_did_run_.result()); |
+ EXPECT_EQ(0U, info_did_run_.completion_task_run_count()); |
+ |
+ EXPECT_EQ(1U, info_did_run_with_completion_task_.run_count()); |
+ // completion task should override the result. |
+ EXPECT_EQ(kOverrideResultValue, |
+ info_did_run_with_completion_task_.result()); |
+ EXPECT_EQ(1U, |
+ info_did_run_with_completion_task_.completion_task_run_count()); |
+ EXPECT_EQ(PP_OK, |
+ info_did_run_with_completion_task_.completion_task_result()); |
+ |
+ EXPECT_EQ(1U, info_did_abort_.run_count()); |
+ // completion task shouldn't override an abort. |
+ EXPECT_EQ(PP_ERROR_ABORTED, info_did_abort_.result()); |
+ EXPECT_EQ(1U, info_did_abort_.completion_task_run_count()); |
+ EXPECT_EQ(PP_ERROR_ABORTED, info_did_abort_.completion_task_result()); |
+ |
+ EXPECT_EQ(0U, info_didnt_run_.completion_task_run_count()); |
+ EXPECT_EQ(0U, info_didnt_run_.run_count()); |
+ } |
+ |
+ void CheckFinalState() { |
+ info_didnt_run_.WaitUntilCompleted(); |
+ EXPECT_EQ(1U, info_did_run_with_completion_task_.run_count()); |
+ EXPECT_EQ(kOverrideResultValue, |
+ info_did_run_with_completion_task_.result()); |
+ callback_did_run_with_completion_task_ = nullptr; |
+ EXPECT_EQ(1U, info_did_run_.run_count()); |
+ EXPECT_EQ(PP_OK, info_did_run_.result()); |
+ callback_did_run_ = nullptr; |
+ EXPECT_EQ(1U, info_did_abort_.run_count()); |
+ EXPECT_EQ(PP_ERROR_ABORTED, info_did_abort_.result()); |
+ callback_did_abort_ = nullptr; |
+ EXPECT_EQ(1U, info_didnt_run_.run_count()); |
+ EXPECT_EQ(PP_ERROR_ABORTED, info_didnt_run_.result()); |
+ callback_didnt_run_ = nullptr; |
+ } |
+ |
+ private: |
+ explicit CallbackMockResource(PP_Instance instance) |
+ : Resource(OBJECT_IS_PROXY, instance), |
+ info_did_run_(&thread_checker_), |
+ info_did_run_with_completion_task_(&thread_checker_), |
+ info_did_abort_(&thread_checker_), |
+ info_didnt_run_(&thread_checker_), |
+ callbacks_created_event_(true, false) {} |
+ void CreateCallbacks() { |
+ // Bind thread_checker_ to the thread where we create the callbacks. |
+ // Later, when the callback runs, it will check that it was invoked on this |
+ // same thread. |
+ CHECK(thread_checker_.CalledOnValidThread()); |
callback_did_run_ = new TrackedCallback( |
this, PP_MakeCompletionCallback(&TestCallback, &info_did_run_)); |
- EXPECT_EQ(0U, info_did_run_.run_count); |
- EXPECT_EQ(0U, info_did_run_.completion_task_run_count); |
// In order to test that the completion task can override the callback |
// result, we need to test callbacks with and without a completion task. |
callback_did_run_with_completion_task_ = new TrackedCallback( |
- this, |
- PP_MakeCompletionCallback(&TestCallback, |
- &info_did_run_with_completion_task_)); |
+ this, PP_MakeCompletionCallback(&TestCallback, |
+ &info_did_run_with_completion_task_)); |
callback_did_run_with_completion_task_->set_completion_task( |
- Bind(&CallbackMockResource::CompletionTask, |
- this, |
+ Bind(&CallbackMockResource::CompletionTask, this, |
&info_did_run_with_completion_task_)); |
- EXPECT_EQ(0U, info_did_run_with_completion_task_.run_count); |
- EXPECT_EQ(0U, info_did_run_with_completion_task_.completion_task_run_count); |
callback_did_abort_ = new TrackedCallback( |
this, PP_MakeCompletionCallback(&TestCallback, &info_did_abort_)); |
callback_did_abort_->set_completion_task( |
Bind(&CallbackMockResource::CompletionTask, this, &info_did_abort_)); |
- EXPECT_EQ(0U, info_did_abort_.run_count); |
- EXPECT_EQ(0U, info_did_abort_.completion_task_run_count); |
callback_didnt_run_ = new TrackedCallback( |
this, PP_MakeCompletionCallback(&TestCallback, &info_didnt_run_)); |
callback_didnt_run_->set_completion_task( |
Bind(&CallbackMockResource::CompletionTask, this, &info_didnt_run_)); |
- EXPECT_EQ(0U, info_didnt_run_.run_count); |
- EXPECT_EQ(0U, info_didnt_run_.completion_task_run_count); |
- callback_did_run_->Run(PP_OK); |
- callback_did_run_with_completion_task_->Run(PP_OK); |
- callback_did_abort_->Abort(); |
- |
- CheckIntermediateState(); |
- |
- return resource_id; |
+ callbacks_created_event_.Signal(); |
} |
- int32_t CompletionTask(CallbackRunInfo* info, int32_t result) { |
- // We should run before the callback. |
- EXPECT_EQ(0U, info->run_count); |
- info->completion_task_run_count++; |
- if (info->completion_task_run_count == 1) |
- info->completion_task_result = result; |
- return kOverrideResultValue; |
- } |
- |
- void CheckIntermediateState() { |
- EXPECT_EQ(1U, info_did_run_.run_count); |
- EXPECT_EQ(PP_OK, info_did_run_.result); |
- EXPECT_EQ(0U, info_did_run_.completion_task_run_count); |
- |
- EXPECT_EQ(1U, info_did_run_with_completion_task_.run_count); |
- // completion task should override the result. |
- EXPECT_EQ(kOverrideResultValue, info_did_run_with_completion_task_.result); |
- EXPECT_EQ(1U, info_did_run_with_completion_task_.completion_task_run_count); |
- EXPECT_EQ(PP_OK, info_did_run_with_completion_task_.completion_task_result); |
- |
- EXPECT_EQ(1U, info_did_abort_.run_count); |
- // completion task shouldn't override an abort. |
- EXPECT_EQ(PP_ERROR_ABORTED, info_did_abort_.result); |
- EXPECT_EQ(1U, info_did_abort_.completion_task_run_count); |
- EXPECT_EQ(PP_ERROR_ABORTED, info_did_abort_.completion_task_result); |
- |
- EXPECT_EQ(0U, info_didnt_run_.completion_task_run_count); |
- EXPECT_EQ(0U, info_didnt_run_.run_count); |
- } |
- |
- void CheckFinalState() { |
- EXPECT_EQ(1U, info_did_run_.run_count); |
- EXPECT_EQ(PP_OK, info_did_run_.result); |
- EXPECT_EQ(1U, info_did_abort_.run_count); |
- EXPECT_EQ(PP_ERROR_ABORTED, info_did_abort_.result); |
- EXPECT_EQ(1U, info_didnt_run_.run_count); |
- EXPECT_EQ(PP_ERROR_ABORTED, info_didnt_run_.result); |
- } |
+ // Used to verify that the callback runs on the same thread where it is |
+ // created. |
+ base::ThreadChecker thread_checker_; |
scoped_refptr<TrackedCallback> callback_did_run_; |
CallbackRunInfo info_did_run_; |
@@ -244,98 +384,88 @@ class CallbackMockResource : public Resource { |
scoped_refptr<TrackedCallback> callback_didnt_run_; |
CallbackRunInfo info_didnt_run_; |
+ |
+ base::WaitableEvent callbacks_created_event_; |
+ |
+ ScopedPPResource reference_holder_; |
}; |
} // namespace |
// Test that callbacks get aborted on the last resource unref. |
TEST_F(CallbackResourceTest, AbortOnNoRef) { |
- ProxyAutoLock lock; |
- ResourceTracker* resource_tracker = PpapiGlobals::Get()->GetResourceTracker(); |
- |
// Test several things: Unref-ing a resource (to zero refs) with callbacks |
// which (1) have been run, (2) have been aborted, (3) haven't been completed. |
// Check that the uncompleted one gets aborted, and that the others don't get |
// called again. |
scoped_refptr<CallbackMockResource> resource_1( |
- new CallbackMockResource(pp_instance())); |
- PP_Resource resource_1_id = resource_1->SetupForTest(); |
+ CallbackMockResource::Create(pp_instance())); |
+ resource_1->CreateCallbacksOnLoop(thread().message_loop()); |
+ resource_1->CheckInitialState(); |
+ resource_1->RunCallbacks(); |
+ resource_1->TakeRef(); |
+ resource_1->CheckIntermediateState(); |
// Also do the same for a second resource, and make sure that unref-ing the |
// first resource doesn't much up the second resource. |
scoped_refptr<CallbackMockResource> resource_2( |
- new CallbackMockResource(pp_instance())); |
- PP_Resource resource_2_id = resource_2->SetupForTest(); |
+ CallbackMockResource::Create(pp_instance())); |
+ resource_2->CreateCallbacksOnLoop(thread().message_loop()); |
+ resource_2->CheckInitialState(); |
+ resource_2->RunCallbacks(); |
+ resource_2->TakeRef(); |
+ resource_2->CheckIntermediateState(); |
// Double-check that resource #1 is still okay. |
resource_1->CheckIntermediateState(); |
// Kill resource #1, spin the message loop to run posted calls, and check that |
// things are in the expected states. |
- resource_tracker->ReleaseResource(resource_1_id); |
- { |
- ProxyAutoUnlock unlock; |
- base::MessageLoop::current()->RunUntilIdle(); |
- } |
+ resource_1->ReleaseRef(); |
+ |
resource_1->CheckFinalState(); |
resource_2->CheckIntermediateState(); |
// Kill resource #2. |
- resource_tracker->ReleaseResource(resource_2_id); |
- { |
- ProxyAutoUnlock unlock; |
- base::MessageLoop::current()->RunUntilIdle(); |
- } |
+ resource_2->ReleaseRef(); |
+ |
resource_1->CheckFinalState(); |
resource_2->CheckFinalState(); |
- // This shouldn't be needed, but make sure there are no stranded tasks. |
{ |
- ProxyAutoUnlock unlock; |
- base::MessageLoop::current()->RunUntilIdle(); |
+ ProxyAutoLock lock; |
+ resource_1 = nullptr; |
+ resource_2 = nullptr; |
} |
} |
// Test that "resurrecting" a resource (getting a new ID for a |Resource|) |
// doesn't resurrect callbacks. |
TEST_F(CallbackResourceTest, Resurrection) { |
- ProxyAutoLock lock; |
- ResourceTracker* resource_tracker = PpapiGlobals::Get()->GetResourceTracker(); |
- |
scoped_refptr<CallbackMockResource> resource( |
- new CallbackMockResource(pp_instance())); |
- PP_Resource resource_id = resource->SetupForTest(); |
- |
- // Unref it, spin the message loop to run posted calls, and check that things |
- // are in the expected states. |
- resource_tracker->ReleaseResource(resource_id); |
- { |
- ProxyAutoUnlock unlock; |
- base::MessageLoop::current()->RunUntilIdle(); |
- } |
+ CallbackMockResource::Create(pp_instance())); |
+ resource->CreateCallbacksOnLoop(thread().message_loop()); |
+ resource->CheckInitialState(); |
+ resource->RunCallbacks(); |
+ resource->TakeRef(); |
+ resource->CheckIntermediateState(); |
+ |
+ // Unref it and check that things are in the expected states. |
+ resource->ReleaseRef(); |
resource->CheckFinalState(); |
// "Resurrect" it and check that the callbacks are still dead. |
- PP_Resource new_resource_id = resource->GetReference(); |
- { |
- ProxyAutoUnlock unlock; |
- base::MessageLoop::current()->RunUntilIdle(); |
- } |
+ resource->TakeRef(); |
resource->CheckFinalState(); |
// Unref it again and do the same. |
- resource_tracker->ReleaseResource(new_resource_id); |
- { |
- ProxyAutoUnlock unlock; |
- base::MessageLoop::current()->RunUntilIdle(); |
- } |
+ resource->ReleaseRef(); |
resource->CheckFinalState(); |
- |
- // This shouldn't be needed, but make sure there are no stranded tasks. |
{ |
- ProxyAutoUnlock unlock; |
- base::MessageLoop::current()->RunUntilIdle(); |
+ ProxyAutoLock lock; |
+ resource = nullptr; |
} |
} |
+} // namespace proxy |
} // namespace ppapi |