| 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);
|
| }
|
| }
|
|
|
|
|