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/bindings/lib/connector.h" | 5 #include "mojo/public/bindings/lib/connector.h" |
6 | 6 |
7 #include <assert.h> | |
8 #include <stdlib.h> | 7 #include <stdlib.h> |
9 | 8 |
10 #include <algorithm> | 9 #include "mojo/public/bindings/error_handler.h" |
11 | 10 |
12 namespace mojo { | 11 namespace mojo { |
13 namespace internal { | 12 namespace internal { |
14 | 13 |
15 // ---------------------------------------------------------------------------- | 14 // ---------------------------------------------------------------------------- |
16 | 15 |
17 Connector::Connector(ScopedMessagePipeHandle message_pipe, | 16 Connector::Connector(ScopedMessagePipeHandle message_pipe, |
18 MojoAsyncWaiter* waiter) | 17 MojoAsyncWaiter* waiter) |
19 : waiter_(waiter), | 18 : error_handler_(NULL), |
| 19 waiter_(waiter), |
20 message_pipe_(message_pipe.Pass()), | 20 message_pipe_(message_pipe.Pass()), |
21 incoming_receiver_(NULL), | 21 incoming_receiver_(NULL), |
22 async_wait_id_(0), | 22 async_wait_id_(0), |
23 error_(false) { | 23 error_(false) { |
| 24 // Even though we don't have an incoming receiver, we still want to monitor |
| 25 // the message pipe to know if is closed or encounters an error. |
| 26 WaitToReadMore(); |
24 } | 27 } |
25 | 28 |
26 Connector::~Connector() { | 29 Connector::~Connector() { |
27 if (async_wait_id_) | 30 if (async_wait_id_) |
28 waiter_->CancelWait(waiter_, async_wait_id_); | 31 waiter_->CancelWait(waiter_, async_wait_id_); |
29 } | 32 } |
30 | 33 |
31 void Connector::SetIncomingReceiver(MessageReceiver* receiver) { | |
32 assert(!incoming_receiver_); | |
33 incoming_receiver_ = receiver; | |
34 if (incoming_receiver_) | |
35 WaitToReadMore(); | |
36 } | |
37 | |
38 bool Connector::Accept(Message* message) { | 34 bool Connector::Accept(Message* message) { |
39 if (error_) | 35 if (error_) |
40 return false; | 36 return false; |
41 | 37 |
42 WriteOne(message); | 38 WriteOne(message); |
43 return !error_; | 39 return !error_; |
44 } | 40 } |
45 | 41 |
46 // static | 42 // static |
47 void Connector::OnHandleReady(void* closure, MojoResult result) { | 43 void Connector::CallOnHandleReady(void* closure, MojoResult result) { |
48 Connector* self = static_cast<Connector*>(closure); | 44 Connector* self = static_cast<Connector*>(closure); |
49 self->async_wait_id_ = 0; | 45 self->OnHandleReady(result); |
50 self->ReadMore(); | 46 } |
| 47 |
| 48 void Connector::OnHandleReady(MojoResult result) { |
| 49 async_wait_id_ = 0; |
| 50 |
| 51 if (result == MOJO_RESULT_OK) { |
| 52 ReadMore(); |
| 53 } else { |
| 54 error_ = true; |
| 55 } |
| 56 |
| 57 if (error_ && error_handler_) |
| 58 error_handler_->OnError(); |
51 } | 59 } |
52 | 60 |
53 void Connector::WaitToReadMore() { | 61 void Connector::WaitToReadMore() { |
54 async_wait_id_ = waiter_->AsyncWait(waiter_, | 62 async_wait_id_ = waiter_->AsyncWait(waiter_, |
55 message_pipe_.get().value(), | 63 message_pipe_.get().value(), |
56 MOJO_WAIT_FLAG_READABLE, | 64 MOJO_WAIT_FLAG_READABLE, |
57 MOJO_DEADLINE_INDEFINITE, | 65 MOJO_DEADLINE_INDEFINITE, |
58 &Connector::OnHandleReady, | 66 &Connector::CallOnHandleReady, |
59 this); | 67 this); |
60 } | 68 } |
61 | 69 |
62 void Connector::ReadMore() { | 70 void Connector::ReadMore() { |
63 for (;;) { | 71 for (;;) { |
64 MojoResult rv; | 72 MojoResult rv; |
65 | 73 |
66 uint32_t num_bytes = 0, num_handles = 0; | 74 uint32_t num_bytes = 0, num_handles = 0; |
67 rv = ReadMessageRaw(message_pipe_.get(), | 75 rv = ReadMessageRaw(message_pipe_.get(), |
68 NULL, | 76 NULL, |
(...skipping 19 matching lines...) Expand all Loading... |
88 &num_bytes, | 96 &num_bytes, |
89 message.handles.empty() ? NULL : | 97 message.handles.empty() ? NULL : |
90 reinterpret_cast<MojoHandle*>(&message.handles[0]), | 98 reinterpret_cast<MojoHandle*>(&message.handles[0]), |
91 &num_handles, | 99 &num_handles, |
92 MOJO_READ_MESSAGE_FLAG_NONE); | 100 MOJO_READ_MESSAGE_FLAG_NONE); |
93 if (rv != MOJO_RESULT_OK) { | 101 if (rv != MOJO_RESULT_OK) { |
94 error_ = true; | 102 error_ = true; |
95 break; | 103 break; |
96 } | 104 } |
97 | 105 |
98 incoming_receiver_->Accept(&message); | 106 if (incoming_receiver_) |
| 107 incoming_receiver_->Accept(&message); |
99 } | 108 } |
100 } | 109 } |
101 | 110 |
102 void Connector::WriteOne(Message* message) { | 111 void Connector::WriteOne(Message* message) { |
103 MojoResult rv = WriteMessageRaw( | 112 MojoResult rv = WriteMessageRaw( |
104 message_pipe_.get(), | 113 message_pipe_.get(), |
105 message->data, | 114 message->data, |
106 message->data->header.num_bytes, | 115 message->data->header.num_bytes, |
107 message->handles.empty() ? NULL : | 116 message->handles.empty() ? NULL : |
108 reinterpret_cast<const MojoHandle*>(&message->handles[0]), | 117 reinterpret_cast<const MojoHandle*>(&message->handles[0]), |
109 static_cast<uint32_t>(message->handles.size()), | 118 static_cast<uint32_t>(message->handles.size()), |
110 MOJO_WRITE_MESSAGE_FLAG_NONE); | 119 MOJO_WRITE_MESSAGE_FLAG_NONE); |
111 if (rv == MOJO_RESULT_OK) { | 120 if (rv == MOJO_RESULT_OK) { |
112 // The handles were successfully transferred, so we don't need the message | 121 // The handles were successfully transferred, so we don't need the message |
113 // to track their lifetime any longer. | 122 // to track their lifetime any longer. |
114 message->handles.clear(); | 123 message->handles.clear(); |
115 } else { | 124 } else { |
116 error_ = true; | 125 error_ = true; |
117 } | 126 } |
118 } | 127 } |
119 | 128 |
120 } // namespace internal | 129 } // namespace internal |
121 } // namespace mojo | 130 } // namespace mojo |
OLD | NEW |