Index: mojo/public/cpp/bindings/lib/interface_endpoint_client.cc |
diff --git a/mojo/public/cpp/bindings/lib/interface_endpoint_client.cc b/mojo/public/cpp/bindings/lib/interface_endpoint_client.cc |
index 9e32c5af239b3ff45f5d22a64d0a70165f20d5b1..ddac8a58762603cc3cb6b20bd8f285ab34a498c7 100644 |
--- a/mojo/public/cpp/bindings/lib/interface_endpoint_client.cc |
+++ b/mojo/public/cpp/bindings/lib/interface_endpoint_client.cc |
@@ -50,34 +50,34 @@ class ResponderThunk : public MessageReceiverWithStatus { |
// We raise an error to signal the calling application that an error |
// condition occurred. Without this the calling application would have no |
// way of knowing it should stop waiting for a response. |
+ Error error(Error::Type::REQUEST_CANCELED); |
if (task_runner_->RunsTasksOnCurrentThread()) { |
// Please note that even if this code is run from a different task |
// runner on the same thread as |task_runner_|, it is okay to directly |
// call InterfaceEndpointClient::RaiseError(), because it will raise |
// error from the correct task runner asynchronously. |
- if (endpoint_client_) { |
- endpoint_client_->RaiseError(); |
- } |
+ if (endpoint_client_) |
+ endpoint_client_->RaiseError(std::move(error)); |
} else { |
task_runner_->PostTask( |
FROM_HERE, |
- base::Bind(&InterfaceEndpointClient::RaiseError, endpoint_client_)); |
+ base::Bind(&InterfaceEndpointClient::RaiseError, endpoint_client_, |
+ base::Passed(&error))); |
} |
} |
} |
// MessageReceiver implementation: |
- bool Accept(Message* message) override { |
+ bool Accept(Message* message, Error* error) override { |
DCHECK(task_runner_->RunsTasksOnCurrentThread()); |
accept_was_invoked_ = true; |
DCHECK(message->has_flag(kMessageIsResponse)); |
- bool result = false; |
- |
if (endpoint_client_) |
- result = endpoint_client_->Accept(message); |
+ return endpoint_client_->Accept(message, error); |
- return result; |
+ *error = Error(Error::Type::RESPONSE_DROPPED); |
+ return false; |
} |
// MessageReceiverWithStatus implementation: |
@@ -123,8 +123,9 @@ InterfaceEndpointClient::HandleIncomingMessageThunk:: |
~HandleIncomingMessageThunk() {} |
bool InterfaceEndpointClient::HandleIncomingMessageThunk::Accept( |
- Message* message) { |
- return owner_->HandleValidatedMessage(message); |
+ Message* message, |
+ Error* error) { |
+ return owner_->HandleValidatedMessage(message, error); |
} |
// ---------------------------------------------------------------------------- |
@@ -186,31 +187,36 @@ ScopedInterfaceEndpointHandle InterfaceEndpointClient::PassHandle() { |
return std::move(handle_); |
} |
-void InterfaceEndpointClient::RaiseError() { |
+void InterfaceEndpointClient::RaiseError(Error error) { |
DCHECK(thread_checker_.CalledOnValidThread()); |
- handle_.router()->RaiseError(); |
+ handle_.router()->RaiseError(std::move(error)); |
} |
-bool InterfaceEndpointClient::Accept(Message* message) { |
+bool InterfaceEndpointClient::Accept(Message* message, Error* error) { |
DCHECK(thread_checker_.CalledOnValidThread()); |
DCHECK(controller_); |
DCHECK(!message->has_flag(kMessageExpectsResponse)); |
- if (encountered_error_) |
+ if (encountered_error_ || !controller_->SendMessage(message)) { |
+ *error = Error(Error::Type::SEND_FAILED); |
return false; |
+ } |
- return controller_->SendMessage(message); |
+ return true; |
} |
bool InterfaceEndpointClient::AcceptWithResponder(Message* message, |
- MessageReceiver* responder) { |
+ MessageReceiver* responder, |
+ Error* error) { |
DCHECK(thread_checker_.CalledOnValidThread()); |
DCHECK(controller_); |
DCHECK(message->has_flag(kMessageExpectsResponse)); |
- if (encountered_error_) |
+ if (encountered_error_) { |
+ *error = Error(Error::Type::SEND_FAILED); |
return false; |
+ } |
// Reserve 0 in case we want it to convey special meaning in the future. |
uint64_t request_id = next_request_id_++; |
@@ -220,8 +226,10 @@ bool InterfaceEndpointClient::AcceptWithResponder(Message* message, |
message->set_request_id(request_id); |
bool is_sync = message->has_flag(kMessageIsSync); |
- if (!controller_->SendMessage(message)) |
+ if (!controller_->SendMessage(message)) { |
+ *error = Error(Error::Type::SEND_FAILED); |
return false; |
+ } |
if (!is_sync) { |
// We assume ownership of |responder|. |
@@ -243,8 +251,10 @@ bool InterfaceEndpointClient::AcceptWithResponder(Message* message, |
auto iter = sync_responses_.find(request_id); |
DCHECK_EQ(&response_received, iter->second->response_received); |
if (response_received) { |
+ Error send_response_error; |
std::unique_ptr<Message> response = std::move(iter->second->response); |
- ignore_result(sync_responder->Accept(response.get())); |
+ ignore_result(sync_responder->Accept(response.get(), |
+ &send_response_error)); |
} |
sync_responses_.erase(iter); |
} |
@@ -253,10 +263,11 @@ bool InterfaceEndpointClient::AcceptWithResponder(Message* message, |
return true; |
} |
-bool InterfaceEndpointClient::HandleIncomingMessage(Message* message) { |
+bool InterfaceEndpointClient::HandleIncomingMessage(Message* message, |
+ Error* error) { |
DCHECK(thread_checker_.CalledOnValidThread()); |
- return payload_validator_->Accept(message); |
+ return payload_validator_->Accept(message, error); |
} |
void InterfaceEndpointClient::NotifyError() { |
@@ -268,16 +279,20 @@ void InterfaceEndpointClient::NotifyError() { |
error_handler_.Run(); |
} |
-bool InterfaceEndpointClient::HandleValidatedMessage(Message* message) { |
+bool InterfaceEndpointClient::HandleValidatedMessage(Message* message, |
+ Error* error) { |
DCHECK_EQ(handle_.id(), message->interface_id()); |
if (message->has_flag(kMessageExpectsResponse)) { |
- if (!incoming_receiver_) |
+ if (!incoming_receiver_) { |
+ *error = Error(Error::Type::REQUEST_DROPPED); |
return false; |
+ } |
MessageReceiverWithStatus* responder = |
new ResponderThunk(weak_ptr_factory_.GetWeakPtr(), task_runner_); |
- bool ok = incoming_receiver_->AcceptWithResponder(message, responder); |
+ bool ok = incoming_receiver_->AcceptWithResponder(message, responder, |
+ error); |
if (!ok) |
delete responder; |
return ok; |
@@ -286,8 +301,10 @@ bool InterfaceEndpointClient::HandleValidatedMessage(Message* message) { |
if (message->has_flag(kMessageIsSync)) { |
auto it = sync_responses_.find(request_id); |
- if (it == sync_responses_.end()) |
+ if (it == sync_responses_.end()) { |
+ *error = Error::ForUnexpectedResponse(interface_name_, message); |
return false; |
+ } |
it->second->response.reset(new Message()); |
message->MoveTo(it->second->response.get()); |
*it->second->response_received = true; |
@@ -295,16 +312,20 @@ bool InterfaceEndpointClient::HandleValidatedMessage(Message* message) { |
} |
auto it = async_responders_.find(request_id); |
- if (it == async_responders_.end()) |
+ if (it == async_responders_.end()) { |
+ *error = Error::ForUnexpectedResponse(interface_name_, message); |
return false; |
+ } |
std::unique_ptr<MessageReceiver> responder = std::move(it->second); |
async_responders_.erase(it); |
- return responder->Accept(message); |
+ return responder->Accept(message, error); |
} else { |
- if (!incoming_receiver_) |
+ if (!incoming_receiver_) { |
+ *error = Error(Error::Type::REQUEST_DROPPED); |
return false; |
+ } |
- return incoming_receiver_->Accept(message); |
+ return incoming_receiver_->Accept(message, error); |
} |
} |