OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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/edk/system/channel_endpoint.h" | 5 #include "mojo/edk/system/channel_endpoint.h" |
6 | 6 |
7 #include "base/logging.h" | 7 #include "base/logging.h" |
8 #include "mojo/edk/system/channel.h" | 8 #include "mojo/edk/system/channel.h" |
9 #include "mojo/edk/system/message_pipe.h" | 9 #include "mojo/edk/system/message_pipe.h" |
10 #include "mojo/edk/system/transport_data.h" | 10 #include "mojo/edk/system/transport_data.h" |
11 | 11 |
12 namespace mojo { | 12 namespace mojo { |
13 namespace system { | 13 namespace system { |
14 | 14 |
15 ChannelEndpoint::ChannelEndpoint(MessagePipe* message_pipe, unsigned port) | 15 ChannelEndpoint::ChannelEndpoint(MessagePipe* message_pipe, |
| 16 unsigned port, |
| 17 MessageInTransitQueue* message_queue) |
16 : message_pipe_(message_pipe), port_(port), channel_(nullptr) { | 18 : message_pipe_(message_pipe), port_(port), channel_(nullptr) { |
17 DCHECK(message_pipe_.get()); | 19 DCHECK(message_pipe_.get() || message_queue); |
18 DCHECK(port_ == 0 || port_ == 1); | 20 DCHECK(port_ == 0 || port_ == 1); |
19 } | |
20 | 21 |
21 void ChannelEndpoint::TakeMessages(MessageInTransitQueue* message_queue) { | 22 if (message_queue) |
22 DCHECK(paused_message_queue_.IsEmpty()); | 23 paused_message_queue_.Swap(message_queue); |
23 paused_message_queue_.Swap(message_queue); | |
24 } | 24 } |
25 | 25 |
26 bool ChannelEndpoint::EnqueueMessage(scoped_ptr<MessageInTransit> message) { | 26 bool ChannelEndpoint::EnqueueMessage(scoped_ptr<MessageInTransit> message) { |
27 DCHECK(message); | 27 DCHECK(message); |
28 | 28 |
29 base::AutoLock locker(lock_); | 29 base::AutoLock locker(lock_); |
30 | 30 |
31 if (!channel_ || !remote_id_.is_valid()) { | 31 if (!channel_ || !remote_id_.is_valid()) { |
32 // We may reach here if we haven't been attached or run yet. | 32 // We may reach here if we haven't been attached or run yet. |
33 // TODO(vtl): We may also reach here if the channel is shut down early for | 33 // TODO(vtl): We may also reach here if the channel is shut down early for |
34 // some reason (with live message pipes on it). We can't check |state_| yet, | 34 // some reason (with live message pipes on it). We can't check |state_| yet, |
35 // until it's protected under lock, but in this case we should return false | 35 // until it's protected under lock, but in this case we should return false |
36 // (and not enqueue any messages). | 36 // (and not enqueue any messages). |
37 paused_message_queue_.AddMessage(message.Pass()); | 37 paused_message_queue_.AddMessage(message.Pass()); |
38 return true; | 38 return true; |
39 } | 39 } |
40 | 40 |
41 // TODO(vtl): Currently, this only works in the "running" case. | 41 // TODO(vtl): Currently, this only works in the "running" case. |
42 DCHECK(remote_id_.is_valid()); | 42 DCHECK(remote_id_.is_valid()); |
43 | 43 |
44 return WriteMessageNoLock(message.Pass()); | 44 return WriteMessageNoLock(message.Pass()); |
45 } | 45 } |
46 | 46 |
47 void ChannelEndpoint::DetachFromMessagePipe() { | 47 void ChannelEndpoint::DetachFromMessagePipe() { |
48 // TODO(vtl): Once |message_pipe_| is under |lock_|, we should null it out | |
49 // here. For now, get the channel to do so for us. | |
50 | |
51 { | 48 { |
52 base::AutoLock locker(lock_); | 49 base::AutoLock locker(lock_); |
53 DCHECK(message_pipe_.get()); | 50 DCHECK(message_pipe_.get()); |
54 message_pipe_ = nullptr; | 51 message_pipe_ = nullptr; |
55 | 52 |
56 if (!channel_) | 53 if (!channel_) |
57 return; | 54 return; |
58 DCHECK(local_id_.is_valid()); | 55 DCHECK(local_id_.is_valid()); |
59 // TODO(vtl): Once we combine "run" into "attach", |remote_id_| should valid | 56 // TODO(vtl): Once we combine "run" into "attach", |remote_id_| should valid |
60 // here as well. | 57 // here as well. |
(...skipping 16 matching lines...) Expand all Loading... |
77 DCHECK(!local_id_.is_valid()); | 74 DCHECK(!local_id_.is_valid()); |
78 DCHECK(!remote_id_.is_valid()); | 75 DCHECK(!remote_id_.is_valid()); |
79 channel_ = channel; | 76 channel_ = channel; |
80 local_id_ = local_id; | 77 local_id_ = local_id; |
81 remote_id_ = remote_id; | 78 remote_id_ = remote_id; |
82 | 79 |
83 while (!paused_message_queue_.IsEmpty()) { | 80 while (!paused_message_queue_.IsEmpty()) { |
84 LOG_IF(WARNING, !WriteMessageNoLock(paused_message_queue_.GetMessage())) | 81 LOG_IF(WARNING, !WriteMessageNoLock(paused_message_queue_.GetMessage())) |
85 << "Failed to write enqueue message to channel"; | 82 << "Failed to write enqueue message to channel"; |
86 } | 83 } |
| 84 |
| 85 if (!message_pipe_.get()) { |
| 86 channel_->DetachEndpoint(this, local_id_, remote_id_); |
| 87 channel_ = nullptr; |
| 88 local_id_ = ChannelEndpointId(); |
| 89 remote_id_ = ChannelEndpointId(); |
| 90 } |
87 } | 91 } |
88 | 92 |
89 bool ChannelEndpoint::OnReadMessage( | 93 bool ChannelEndpoint::OnReadMessage( |
90 const MessageInTransit::View& message_view, | 94 const MessageInTransit::View& message_view, |
91 embedder::ScopedPlatformHandleVectorPtr platform_handles) { | 95 embedder::ScopedPlatformHandleVectorPtr platform_handles) { |
92 scoped_ptr<MessageInTransit> message(new MessageInTransit(message_view)); | 96 scoped_ptr<MessageInTransit> message(new MessageInTransit(message_view)); |
93 scoped_refptr<MessagePipe> message_pipe; | 97 scoped_refptr<MessagePipe> message_pipe; |
94 unsigned port; | 98 unsigned port; |
95 { | 99 { |
96 base::AutoLock locker(lock_); | 100 base::AutoLock locker(lock_); |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
168 DCHECK(remote_id_.is_valid()); | 172 DCHECK(remote_id_.is_valid()); |
169 | 173 |
170 message->SerializeAndCloseDispatchers(channel_); | 174 message->SerializeAndCloseDispatchers(channel_); |
171 message->set_source_id(local_id_); | 175 message->set_source_id(local_id_); |
172 message->set_destination_id(remote_id_); | 176 message->set_destination_id(remote_id_); |
173 return channel_->WriteMessage(message.Pass()); | 177 return channel_->WriteMessage(message.Pass()); |
174 } | 178 } |
175 | 179 |
176 } // namespace system | 180 } // namespace system |
177 } // namespace mojo | 181 } // namespace mojo |
OLD | NEW |