Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1016)

Unified Diff: ppapi/proxy/tracked_callback_unittest.cc

Issue 923263003: PPAPI: Make TrackedCallback more threadsafe (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: review comments Created 5 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « ppapi/ppapi_tests.gypi ('k') | ppapi/shared_impl/callback_tracker.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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
« no previous file with comments | « ppapi/ppapi_tests.gypi ('k') | ppapi/shared_impl/callback_tracker.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698