Index: content/common/associated_interface_provider_impl.cc |
diff --git a/content/common/associated_interface_provider_impl.cc b/content/common/associated_interface_provider_impl.cc |
index 647ba6a161407b5e698863420df35cb043c4d096..69988b93a00245ae3a10c7a8a8e589fef409f2c7 100644 |
--- a/content/common/associated_interface_provider_impl.cc |
+++ b/content/common/associated_interface_provider_impl.cc |
@@ -3,6 +3,8 @@ |
// found in the LICENSE file. |
#include "content/common/associated_interface_provider_impl.h" |
+#include "base/callback.h" |
+#include "base/run_loop.h" |
#include "mojo/public/cpp/bindings/associated_binding.h" |
namespace content { |
@@ -24,6 +26,14 @@ class AssociatedInterfaceProviderImpl::LocalProvider |
binders_[name] = binder; |
} |
+ void WaitForBinding(const std::string& name) { |
ncarter (slow)
2017/04/21 20:42:13
Assuming this is test-only code, we should find a
Charlie Harrison
2017/04/21 20:48:02
Sorry, this is no longer up to date since rockot@
|
+ DCHECK(binders_.find(name) != binders_.end()); |
+ base::RunLoop run_loop; |
+ quit_closure_ = run_loop.QuitClosure(); |
+ name_to_wait_for_ = name; |
+ run_loop.Run(); |
+ } |
+ |
private: |
// mojom::AssociatedInterfaceProvider: |
void GetAssociatedInterface( |
@@ -32,6 +42,11 @@ class AssociatedInterfaceProviderImpl::LocalProvider |
auto it = binders_.find(name); |
if (it != binders_.end()) |
it->second.Run(request.PassHandle()); |
+ |
+ if (name == name_to_wait_for_) { |
+ name_to_wait_for_.clear(); |
+ std::move(quit_closure_).Run(); |
+ } |
} |
using BinderMap = |
@@ -39,6 +54,9 @@ class AssociatedInterfaceProviderImpl::LocalProvider |
base::Callback<void(mojo::ScopedInterfaceEndpointHandle)>>; |
BinderMap binders_; |
+ base::Closure quit_closure_; |
+ std::string name_to_wait_for_; |
+ |
mojo::AssociatedBinding<mojom::AssociatedInterfaceProvider> |
associated_interface_provider_binding_; |
}; |
@@ -59,7 +77,12 @@ void AssociatedInterfaceProviderImpl::GetInterface( |
mojo::ScopedInterfaceEndpointHandle handle) { |
mojom::AssociatedInterfaceAssociatedRequest request; |
request.Bind(std::move(handle)); |
- return proxy_->GetAssociatedInterface(name, std::move(request)); |
+ proxy_->GetAssociatedInterface(name, std::move(request)); |
+ |
+ // In tests, make sure the interface is bound before continuing, to ensure we |
+ // don't deadlock for sync messages. |
+ if (local_provider_) |
+ local_provider_->WaitForBinding(name); |
Ken Rockot(use gerrit already)
2017/04/21 18:26:58
Hmm. On one hand, I'm really not a fan of code whi
Charlie Harrison
2017/04/21 18:46:10
Hm, this makes sense but it's a bit tricky because
|
} |
void AssociatedInterfaceProviderImpl::OverrideBinderForTesting( |