Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "mojo/public/cpp/bindings/message.h" | 5 #include "mojo/public/cpp/bindings/message.h" |
| 6 | 6 |
| 7 #include <stddef.h> | 7 #include <stddef.h> |
| 8 #include <stdint.h> | 8 #include <stdint.h> |
| 9 #include <stdlib.h> | 9 #include <stdlib.h> |
| 10 | 10 |
| 11 #include <algorithm> | 11 #include <algorithm> |
| 12 #include <utility> | 12 #include <utility> |
| 13 | 13 |
| 14 #include "base/bind.h" | |
| 15 #include "base/lazy_instance.h" | |
| 14 #include "base/logging.h" | 16 #include "base/logging.h" |
| 15 #include "base/strings/stringprintf.h" | 17 #include "base/strings/stringprintf.h" |
| 18 #include "base/threading/thread_local.h" | |
| 16 | 19 |
| 17 namespace mojo { | 20 namespace mojo { |
| 18 | 21 |
| 22 namespace { | |
| 23 | |
| 24 base::LazyInstance<base::ThreadLocalPointer<internal::MessageDispatchContext>> | |
| 25 g_tls_message_dispatch_context = LAZY_INSTANCE_INITIALIZER; | |
| 26 | |
| 27 base::LazyInstance<base::ThreadLocalPointer<SyncMessageResponseContext>> | |
| 28 g_tls_sync_response_context = LAZY_INSTANCE_INITIALIZER; | |
| 29 | |
| 30 } // namespace | |
| 31 | |
| 19 Message::Message() { | 32 Message::Message() { |
| 20 } | 33 } |
| 21 | 34 |
| 22 Message::~Message() { | 35 Message::~Message() { |
| 23 CloseHandles(); | 36 CloseHandles(); |
| 24 } | 37 } |
| 25 | 38 |
| 26 void Message::Initialize(size_t capacity, bool zero_initialized) { | 39 void Message::Initialize(size_t capacity, bool zero_initialized) { |
| 27 DCHECK(!buffer_); | 40 DCHECK(!buffer_); |
| 28 buffer_.reset(new internal::MessageBuffer(capacity, zero_initialized)); | 41 buffer_.reset(new internal::MessageBuffer(capacity, zero_initialized)); |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 84 } | 97 } |
| 85 | 98 |
| 86 void Message::CloseHandles() { | 99 void Message::CloseHandles() { |
| 87 for (std::vector<Handle>::iterator it = handles_.begin(); | 100 for (std::vector<Handle>::iterator it = handles_.begin(); |
| 88 it != handles_.end(); ++it) { | 101 it != handles_.end(); ++it) { |
| 89 if (it->is_valid()) | 102 if (it->is_valid()) |
| 90 CloseRaw(*it); | 103 CloseRaw(*it); |
| 91 } | 104 } |
| 92 } | 105 } |
| 93 | 106 |
| 107 SyncMessageResponseContext::SyncMessageResponseContext() | |
| 108 : outer_context_(current()) { | |
| 109 g_tls_sync_response_context.Get().Set(this); | |
| 110 } | |
| 111 | |
| 112 SyncMessageResponseContext::~SyncMessageResponseContext() { | |
| 113 DCHECK_EQ(current(), this); | |
| 114 g_tls_sync_response_context.Get().Set(outer_context_); | |
| 115 } | |
| 116 | |
| 117 // static | |
| 118 SyncMessageResponseContext* SyncMessageResponseContext::current() { | |
| 119 return g_tls_sync_response_context.Get().Get(); | |
| 120 } | |
| 121 | |
| 122 void SyncMessageResponseContext::ReportBadMessage(const std::string& error) { | |
| 123 response_.NotifyBadMessage(error); | |
| 124 } | |
| 125 | |
| 126 ReportBadMessageCallback SyncMessageResponseContext::TakeBadMessageCallback() { | |
| 127 std::unique_ptr<Message> new_message(new Message); | |
| 128 response_.MoveTo(new_message.get()); | |
| 129 return base::Bind(&Message::NotifyBadMessage, | |
| 130 base::Owned(new_message.release())); | |
| 131 } | |
| 132 | |
| 94 MojoResult ReadMessage(MessagePipeHandle handle, Message* message) { | 133 MojoResult ReadMessage(MessagePipeHandle handle, Message* message) { |
| 95 MojoResult rv; | 134 MojoResult rv; |
| 96 | 135 |
| 97 std::vector<Handle> handles; | 136 std::vector<Handle> handles; |
| 98 ScopedMessageHandle mojo_message; | 137 ScopedMessageHandle mojo_message; |
| 99 uint32_t num_bytes = 0, num_handles = 0; | 138 uint32_t num_bytes = 0, num_handles = 0; |
| 100 rv = ReadMessageNew(handle, | 139 rv = ReadMessageNew(handle, |
| 101 &mojo_message, | 140 &mojo_message, |
| 102 &num_bytes, | 141 &num_bytes, |
| 103 nullptr, | 142 nullptr, |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 115 } | 154 } |
| 116 | 155 |
| 117 if (rv != MOJO_RESULT_OK) | 156 if (rv != MOJO_RESULT_OK) |
| 118 return rv; | 157 return rv; |
| 119 | 158 |
| 120 message->InitializeFromMojoMessage( | 159 message->InitializeFromMojoMessage( |
| 121 std::move(mojo_message), num_bytes, &handles); | 160 std::move(mojo_message), num_bytes, &handles); |
| 122 return MOJO_RESULT_OK; | 161 return MOJO_RESULT_OK; |
| 123 } | 162 } |
| 124 | 163 |
| 164 void ReportBadMessage(const std::string& error) { | |
| 165 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
| |
| 166 ->NotifyBadMessage(error); | |
| 167 } | |
| 168 | |
| 169 ReportBadMessageCallback TakeBadMessageCallback() { | |
| 170 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
| |
| 171 internal::MessageDispatchContext::current()->message() | |
| 172 ->MoveTo(new_message.get()); | |
| 173 return base::Bind(&Message::NotifyBadMessage, | |
| 174 base::Owned(new_message.release())); | |
| 175 } | |
| 176 | |
| 177 namespace internal { | |
| 178 | |
| 179 MessageDispatchContext::MessageDispatchContext(Message* message) | |
| 180 : outer_context_(current()), message_(message) { | |
| 181 g_tls_message_dispatch_context.Get().Set(this); | |
| 182 } | |
| 183 | |
| 184 MessageDispatchContext::~MessageDispatchContext() { | |
| 185 DCHECK_EQ(current(), this); | |
| 186 g_tls_message_dispatch_context.Get().Set(outer_context_); | |
| 187 } | |
| 188 | |
| 189 // static | |
| 190 MessageDispatchContext* MessageDispatchContext::current() { | |
| 191 return g_tls_message_dispatch_context.Get().Get(); | |
| 192 } | |
| 193 | |
| 194 // static | |
| 195 void SyncMessageResponseSetup::SetCurrentSyncResponseMessage(Message* message) { | |
| 196 SyncMessageResponseContext* context = SyncMessageResponseContext::current(); | |
| 197 if (context) | |
| 198 message->MoveTo(&context->response_); | |
| 199 } | |
| 200 | |
| 201 } // namespace internal | |
| 202 | |
| 125 } // namespace mojo | 203 } // namespace mojo |
| OLD | NEW |