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
3 // found in the LICENSE file.
5 #include "mojo/public/cpp/bindings/lib/connector.h"
10 #include "mojo/public/cpp/bindings/error_handler.h"
15 // ----------------------------------------------------------------------------
17 Connector::Connector(ScopedMessagePipeHandle message_pipe,
18 MojoAsyncWaiter* waiter)
19 : error_handler_(NULL),
21 message_pipe_(message_pipe.Pass()),
22 incoming_receiver_(NULL),
26 enforce_errors_from_incoming_receiver_(true) {
27 // Even though we don't have an incoming receiver, we still want to monitor
28 // the message pipe to know if is closed or encounters an error.
32 Connector::~Connector() {
34 waiter_->CancelWait(waiter_, async_wait_id_);
37 void Connector::CloseMessagePipe() {
38 Close(message_pipe_.Pass());
41 ScopedMessagePipeHandle Connector::ReleaseMessagePipe() {
43 waiter_->CancelWait(waiter_, async_wait_id_);
46 return message_pipe_.Pass();
49 bool Connector::Accept(Message* message) {
50 assert(message_pipe_.is_valid());
58 MojoResult rv = WriteMessageRaw(
61 message->data_num_bytes(),
62 message->mutable_handles()->empty() ? NULL :
63 reinterpret_cast<const MojoHandle*>(
64 &message->mutable_handles()->front()),
65 static_cast<uint32_t>(message->mutable_handles()->size()),
66 MOJO_WRITE_MESSAGE_FLAG_NONE);
70 // The handles were successfully transferred, so we don't need the message
71 // to track their lifetime any longer.
72 message->mutable_handles()->clear();
74 case MOJO_RESULT_FAILED_PRECONDITION:
75 // There's no point in continuing to write to this pipe since the other
76 // end is gone. Avoid writing any future messages. Hide write failures
77 // from the caller since we'd like them to continue consuming any backlog
78 // of incoming messages before regarding the message pipe as closed.
82 // This particular write was rejected, presumably because of bad input.
83 // The pipe is not necessarily in a bad state.
89 bool Connector::AcceptWithResponder(Message* message,
90 MessageReceiver* responder) {
91 // TODO(darin): Implement this!
97 void Connector::CallOnHandleReady(void* closure, MojoResult result) {
98 Connector* self = static_cast<Connector*>(closure);
99 self->OnHandleReady(result);
102 void Connector::OnHandleReady(MojoResult result) {
105 if (result == MOJO_RESULT_OK) {
111 if (error_ && error_handler_)
112 error_handler_->OnConnectionError();
115 void Connector::WaitToReadMore() {
116 async_wait_id_ = waiter_->AsyncWait(waiter_,
117 message_pipe_.get().value(),
118 MOJO_WAIT_FLAG_READABLE,
119 MOJO_DEADLINE_INDEFINITE,
120 &Connector::CallOnHandleReady,
124 void Connector::ReadMore() {
126 bool receiver_result = false;
127 MojoResult rv = ReadAndDispatchMessage(
128 message_pipe_.get(), incoming_receiver_, &receiver_result);
129 if (rv == MOJO_RESULT_SHOULD_WAIT) {
133 if (rv != MOJO_RESULT_OK ||
134 (enforce_errors_from_incoming_receiver_ && !receiver_result)) {
141 } // namespace internal