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

Unified Diff: mojo/public/cpp/bindings/tests/associated_interface_unittest.cc

Issue 2608783003: Fix ThreadSafeAssociatedInterfacePtrProvider raciness. (Closed)
Patch Set: Created 4 years 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
Index: mojo/public/cpp/bindings/tests/associated_interface_unittest.cc
diff --git a/mojo/public/cpp/bindings/tests/associated_interface_unittest.cc b/mojo/public/cpp/bindings/tests/associated_interface_unittest.cc
index ac8b330f411e2eece5ed1f5c90cc390098bfd8dc..e0a10b2ddbf99d7c208e9d2f75155c1bb6b87f2f 100644
--- a/mojo/public/cpp/bindings/tests/associated_interface_unittest.cc
+++ b/mojo/public/cpp/bindings/tests/associated_interface_unittest.cc
@@ -14,6 +14,7 @@
#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
#include "base/single_thread_task_runner.h"
+#include "base/synchronization/waitable_event.h"
#include "base/threading/sequenced_task_runner_handle.h"
#include "base/threading/thread.h"
#include "base/threading/thread_task_runner_handle.h"
@@ -1057,41 +1058,44 @@ struct ForwarderTestContext {
};
TEST_F(AssociatedInterfaceTest, BindLaterThreadSafeAssociatedInterfacePtr) {
- // Create a ThreadSafeAssociatedPtr that we'll bind from a different thread.
- scoped_refptr<ThreadSafeIntegerSenderAssociatedPtr> thread_safe_ptr =
- ThreadSafeIntegerSenderAssociatedPtr::CreateUnbound();
-
// Start the thread from where we'll bind the interface pointer.
base::Thread other_thread("service test thread");
other_thread.Start();
const scoped_refptr<base::SingleThreadTaskRunner>& other_thread_task_runner =
other_thread.message_loop()->task_runner();
ForwarderTestContext* context = new ForwarderTestContext();
- {
- base::RunLoop run_loop;
- auto run_method = base::Bind(
- [](const scoped_refptr<base::TaskRunner>& main_task_runner,
- const base::Closure& quit_closure,
- const scoped_refptr<ThreadSafeIntegerSenderAssociatedPtr>&
- thread_safe_ptr,
- ForwarderTestContext* context) {
- // We are on the background thread, create the interface ptr.
- context->interface_impl =
- base::MakeUnique<IntegerSenderConnectionImpl>(
- MakeRequest(&(context->connection_ptr)));
- IntegerSenderAssociatedPtr sender;
- context->connection_ptr->GetSender(
- MakeRequest(&sender, context->connection_ptr.associated_group()));
- thread_safe_ptr->Bind(std::move(sender));
- main_task_runner->PostTask(FROM_HERE, quit_closure);
- },
- base::SequencedTaskRunnerHandle::Get(), run_loop.QuitClosure(),
- thread_safe_ptr, context);
-
- other_thread_task_runner->PostTask(FROM_HERE, run_method);
- // Block until the associated pointer is bound.
- run_loop.Run();
- }
+
+ base::WaitableEvent echo_called_event(
+ base::WaitableEvent::ResetPolicy::MANUAL,
+ base::WaitableEvent::InitialState::NOT_SIGNALED);
+
+ // Create a ThreadSafeAssociatedPtr that we'll bind from a different thread.
+ scoped_refptr<ThreadSafeIntegerSenderAssociatedPtr> thread_safe_ptr =
+ ThreadSafeIntegerSenderAssociatedPtr::CreateUnbound(
+ other_thread_task_runner);
+
+ base::RunLoop bind_run_loop;
+ auto run_method = base::Bind(
+ [](base::WaitableEvent* echo_called_event,
+ const scoped_refptr<ThreadSafeIntegerSenderAssociatedPtr>&
+ thread_safe_ptr,
+ ForwarderTestContext* context) {
+ // Wait for echo to be called on the main thread so the interface method
+ // call happens before the bind.
+ echo_called_event->Wait();
+
+ // We are on the background thread, create the interface ptr.
+ context->interface_impl =
+ base::MakeUnique<IntegerSenderConnectionImpl>(
+ MakeRequest(&(context->connection_ptr)));
+ IntegerSenderAssociatedPtr sender;
+ context->connection_ptr->GetSender(
+ MakeRequest(&sender, context->connection_ptr.associated_group()));
+ thread_safe_ptr->Bind(std::move(sender));
+ },
+ &echo_called_event, thread_safe_ptr, context);
+
+ other_thread_task_runner->PostTask(FROM_HERE, run_method);
{
// Now we can call methods on the interface from the main thread.
@@ -1103,6 +1107,10 @@ TEST_F(AssociatedInterfaceTest, BindLaterThreadSafeAssociatedInterfacePtr) {
base::RunLoop run_loop;
(*thread_safe_ptr)
->Echo(123, base::Bind(echo_callback, run_loop.QuitClosure()));
+
+ // Let the bind happen on the background thread.
+ echo_called_event.Signal();
+
// Block until the method callback is called.
run_loop.Run();
}

Powered by Google App Engine
This is Rietveld 408576698