Chromium Code Reviews| Index: mojo/public/cpp/bindings/lib/message.cc |
| diff --git a/mojo/public/cpp/bindings/lib/message.cc b/mojo/public/cpp/bindings/lib/message.cc |
| index 939e064b5ce178c40e298685ff0162ac7dca7542..03bdca77dbcf7932f094d3d50be8bc4a564449e3 100644 |
| --- a/mojo/public/cpp/bindings/lib/message.cc |
| +++ b/mojo/public/cpp/bindings/lib/message.cc |
| @@ -11,11 +11,24 @@ |
| #include <algorithm> |
| #include <utility> |
| +#include "base/bind.h" |
| +#include "base/lazy_instance.h" |
| #include "base/logging.h" |
| #include "base/strings/stringprintf.h" |
| +#include "base/threading/thread_local.h" |
| namespace mojo { |
| +namespace { |
| + |
| +base::LazyInstance<base::ThreadLocalPointer<internal::MessageDispatchContext>> |
| + g_tls_message_dispatch_context = LAZY_INSTANCE_INITIALIZER; |
| + |
| +base::LazyInstance<base::ThreadLocalPointer<SyncMessageResponseContext>> |
| + g_tls_sync_response_context = LAZY_INSTANCE_INITIALIZER; |
| + |
| +} // namespace |
| + |
| Message::Message() { |
| } |
| @@ -91,6 +104,32 @@ void Message::CloseHandles() { |
| } |
| } |
| +SyncMessageResponseContext::SyncMessageResponseContext() |
| + : outer_context_(current()) { |
| + g_tls_sync_response_context.Get().Set(this); |
| +} |
| + |
| +SyncMessageResponseContext::~SyncMessageResponseContext() { |
| + DCHECK_EQ(current(), this); |
| + g_tls_sync_response_context.Get().Set(outer_context_); |
| +} |
| + |
| +// static |
| +SyncMessageResponseContext* SyncMessageResponseContext::current() { |
| + return g_tls_sync_response_context.Get().Get(); |
| +} |
| + |
| +void SyncMessageResponseContext::ReportBadMessage(const std::string& error) { |
| + response_.NotifyBadMessage(error); |
| +} |
| + |
| +ReportBadMessageCallback SyncMessageResponseContext::TakeBadMessageCallback() { |
| + std::unique_ptr<Message> new_message(new Message); |
| + response_.MoveTo(new_message.get()); |
| + return base::Bind(&Message::NotifyBadMessage, |
| + base::Owned(new_message.release())); |
| +} |
| + |
| MojoResult ReadMessage(MessagePipeHandle handle, Message* message) { |
| MojoResult rv; |
| @@ -122,4 +161,43 @@ MojoResult ReadMessage(MessagePipeHandle handle, Message* message) { |
| return MOJO_RESULT_OK; |
| } |
| +void ReportBadMessage(const std::string& error) { |
| + internal::MessageDispatchContext::current()->message() |
|
yzshen1
2016/08/03 17:10:56
Does it make sense to check whether we have a Mess
Ken Rockot(use gerrit already)
2016/08/03 19:13:25
Done. We should always have one, so I've made it a
|
| + ->NotifyBadMessage(error); |
| +} |
| + |
| +ReportBadMessageCallback TakeBadMessageCallback() { |
| + std::unique_ptr<Message> new_message(new Message); |
|
yzshen1
2016/08/03 17:10:56
After taking the message, if someone tries to repo
Ken Rockot(use gerrit already)
2016/08/03 19:13:25
Done - Callback is lazily created and takes owners
|
| + internal::MessageDispatchContext::current()->message() |
| + ->MoveTo(new_message.get()); |
| + return base::Bind(&Message::NotifyBadMessage, |
| + base::Owned(new_message.release())); |
| +} |
| + |
| +namespace internal { |
| + |
| +MessageDispatchContext::MessageDispatchContext(Message* message) |
| + : outer_context_(current()), message_(message) { |
| + g_tls_message_dispatch_context.Get().Set(this); |
| +} |
| + |
| +MessageDispatchContext::~MessageDispatchContext() { |
| + DCHECK_EQ(current(), this); |
| + g_tls_message_dispatch_context.Get().Set(outer_context_); |
| +} |
| + |
| +// static |
| +MessageDispatchContext* MessageDispatchContext::current() { |
| + return g_tls_message_dispatch_context.Get().Get(); |
| +} |
| + |
| +// static |
| +void SyncMessageResponseSetup::SetCurrentSyncResponseMessage(Message* message) { |
| + SyncMessageResponseContext* context = SyncMessageResponseContext::current(); |
| + if (context) |
| + message->MoveTo(&context->response_); |
| +} |
| + |
| +} // namespace internal |
| + |
| } // namespace mojo |