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/system/local_message_pipe_endpoint.h" | 5 #include "mojo/system/local_message_pipe_endpoint.h" |
6 | 6 |
7 #include <string.h> | 7 #include <string.h> |
8 | 8 |
9 #include "base/logging.h" | 9 #include "base/logging.h" |
10 #include "mojo/system/dispatcher.h" | 10 #include "mojo/system/dispatcher.h" |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
59 new_satisfiable_flags != old_satisfiable_flags) { | 59 new_satisfiable_flags != old_satisfiable_flags) { |
60 waiter_list_.AwakeWaitersForStateChange(new_satisfied_flags, | 60 waiter_list_.AwakeWaitersForStateChange(new_satisfied_flags, |
61 new_satisfiable_flags); | 61 new_satisfiable_flags); |
62 } | 62 } |
63 | 63 |
64 return true; | 64 return true; |
65 } | 65 } |
66 | 66 |
67 MojoResult LocalMessagePipeEndpoint::CanEnqueueMessage( | 67 MojoResult LocalMessagePipeEndpoint::CanEnqueueMessage( |
68 const MessageInTransit* /*message*/, | 68 const MessageInTransit* /*message*/, |
69 const std::vector<Dispatcher*>* dispatchers) { | 69 const std::vector<Dispatcher*>* /*dispatchers*/) { |
70 // TODO(vtl) | |
71 if (dispatchers) { | |
72 NOTIMPLEMENTED(); | |
73 return MOJO_RESULT_UNIMPLEMENTED; | |
74 } | |
75 return MOJO_RESULT_OK; | 70 return MOJO_RESULT_OK; |
76 } | 71 } |
77 | 72 |
78 void LocalMessagePipeEndpoint::EnqueueMessage( | 73 void LocalMessagePipeEndpoint::EnqueueMessage( |
79 MessageInTransit* message, | 74 MessageInTransit* message, |
80 std::vector<scoped_refptr<Dispatcher> >* dispatchers) { | 75 std::vector<scoped_refptr<Dispatcher> >* dispatchers) { |
81 DCHECK(is_open_); | 76 DCHECK(is_open_); |
82 DCHECK(is_peer_open_); | 77 DCHECK(is_peer_open_); |
83 | 78 |
84 // TODO(vtl) | |
85 DCHECK(!dispatchers || dispatchers->empty()); | |
86 | |
87 bool was_empty = message_queue_.empty(); | 79 bool was_empty = message_queue_.empty(); |
88 message_queue_.push_back(MessageQueueEntry()); | 80 message_queue_.push_back(MessageQueueEntry()); |
89 message_queue_.back().message = message; | 81 message_queue_.back().message = message; |
90 if (dispatchers) | 82 if (dispatchers) |
91 message_queue_.back().dispatchers.swap(*dispatchers); | 83 message_queue_.back().dispatchers.swap(*dispatchers); |
92 if (was_empty) { | 84 if (was_empty) { |
93 waiter_list_.AwakeWaitersForStateChange(SatisfiedFlags(), | 85 waiter_list_.AwakeWaitersForStateChange(SatisfiedFlags(), |
94 SatisfiableFlags()); | 86 SatisfiableFlags()); |
95 } | 87 } |
96 } | 88 } |
97 | 89 |
98 void LocalMessagePipeEndpoint::CancelAllWaiters() { | 90 void LocalMessagePipeEndpoint::CancelAllWaiters() { |
99 DCHECK(is_open_); | 91 DCHECK(is_open_); |
100 waiter_list_.CancelAllWaiters(); | 92 waiter_list_.CancelAllWaiters(); |
101 } | 93 } |
102 | 94 |
103 // TODO(vtl): Support receiving handles. | |
104 MojoResult LocalMessagePipeEndpoint::ReadMessage( | 95 MojoResult LocalMessagePipeEndpoint::ReadMessage( |
105 void* bytes, uint32_t* num_bytes, | 96 void* bytes, uint32_t* num_bytes, |
106 uint32_t max_num_dispatchers, | |
107 std::vector<scoped_refptr<Dispatcher> >* dispatchers, | 97 std::vector<scoped_refptr<Dispatcher> >* dispatchers, |
| 98 uint32_t* num_dispatchers, |
108 MojoReadMessageFlags flags) { | 99 MojoReadMessageFlags flags) { |
109 DCHECK(is_open_); | 100 DCHECK(is_open_); |
| 101 DCHECK(!dispatchers || dispatchers->empty()); |
110 | 102 |
111 const uint32_t max_bytes = num_bytes ? *num_bytes : 0; | 103 const uint32_t max_bytes = num_bytes ? *num_bytes : 0; |
| 104 const uint32_t max_num_dispatchers = num_dispatchers ? *num_dispatchers : 0; |
112 | 105 |
113 if (message_queue_.empty()) { | 106 if (message_queue_.empty()) { |
114 return is_peer_open_ ? MOJO_RESULT_NOT_FOUND : | 107 return is_peer_open_ ? MOJO_RESULT_NOT_FOUND : |
115 MOJO_RESULT_FAILED_PRECONDITION; | 108 MOJO_RESULT_FAILED_PRECONDITION; |
116 } | 109 } |
117 | 110 |
118 // TODO(vtl): If |flags & MOJO_READ_MESSAGE_FLAG_MAY_DISCARD|, we could pop | 111 // TODO(vtl): If |flags & MOJO_READ_MESSAGE_FLAG_MAY_DISCARD|, we could pop |
119 // and release the lock immediately. | 112 // and release the lock immediately. |
120 bool not_enough_space = false; | 113 bool enough_space = true; |
121 MessageInTransit* const message = message_queue_.front().message; | 114 const MessageInTransit* queued_message = message_queue_.front().message; |
122 if (num_bytes) | 115 if (num_bytes) |
123 *num_bytes = message->data_size(); | 116 *num_bytes = queued_message->data_size(); |
124 if (message->data_size() <= max_bytes) | 117 if (queued_message->data_size() <= max_bytes) |
125 memcpy(bytes, message->data(), message->data_size()); | 118 memcpy(bytes, queued_message->data(), queued_message->data_size()); |
126 else | 119 else |
127 not_enough_space = true; | 120 enough_space = false; |
128 | 121 |
129 if (!not_enough_space || (flags & MOJO_READ_MESSAGE_FLAG_MAY_DISCARD)) { | 122 std::vector<scoped_refptr<Dispatcher> >* queued_dispatchers = |
| 123 &message_queue_.front().dispatchers; |
| 124 if (num_dispatchers) |
| 125 *num_dispatchers = static_cast<uint32_t>(queued_dispatchers->size()); |
| 126 if (enough_space) { |
| 127 if (queued_dispatchers->empty()) { |
| 128 // Nothing to do. |
| 129 } else if (queued_dispatchers->size() <= max_num_dispatchers) { |
| 130 DCHECK(dispatchers); |
| 131 dispatchers->swap(*queued_dispatchers); |
| 132 } else { |
| 133 enough_space = false; |
| 134 } |
| 135 } |
| 136 |
| 137 if (enough_space || (flags & MOJO_READ_MESSAGE_FLAG_MAY_DISCARD)) { |
130 message_queue_.pop_front(); | 138 message_queue_.pop_front(); |
131 | 139 |
132 // Now it's empty, thus no longer readable. | 140 // Now it's empty, thus no longer readable. |
133 if (message_queue_.empty()) { | 141 if (message_queue_.empty()) { |
134 // It's currently not possible to wait for non-readability, but we should | 142 // It's currently not possible to wait for non-readability, but we should |
135 // do the state change anyway. | 143 // do the state change anyway. |
136 waiter_list_.AwakeWaitersForStateChange(SatisfiedFlags(), | 144 waiter_list_.AwakeWaitersForStateChange(SatisfiedFlags(), |
137 SatisfiableFlags()); | 145 SatisfiableFlags()); |
138 } | 146 } |
139 } | 147 } |
140 | 148 |
141 if (not_enough_space) | 149 if (!enough_space) |
142 return MOJO_RESULT_RESOURCE_EXHAUSTED; | 150 return MOJO_RESULT_RESOURCE_EXHAUSTED; |
143 | 151 |
144 return MOJO_RESULT_OK; | 152 return MOJO_RESULT_OK; |
145 } | 153 } |
146 | 154 |
147 MojoResult LocalMessagePipeEndpoint::AddWaiter(Waiter* waiter, | 155 MojoResult LocalMessagePipeEndpoint::AddWaiter(Waiter* waiter, |
148 MojoWaitFlags flags, | 156 MojoWaitFlags flags, |
149 MojoResult wake_result) { | 157 MojoResult wake_result) { |
150 DCHECK(is_open_); | 158 DCHECK(is_open_); |
151 | 159 |
(...skipping 24 matching lines...) Expand all Loading... |
176 MojoWaitFlags satisfiable_flags = 0; | 184 MojoWaitFlags satisfiable_flags = 0; |
177 if (!message_queue_.empty() || is_peer_open_) | 185 if (!message_queue_.empty() || is_peer_open_) |
178 satisfiable_flags |= MOJO_WAIT_FLAG_READABLE; | 186 satisfiable_flags |= MOJO_WAIT_FLAG_READABLE; |
179 if (is_peer_open_) | 187 if (is_peer_open_) |
180 satisfiable_flags |= MOJO_WAIT_FLAG_WRITABLE; | 188 satisfiable_flags |= MOJO_WAIT_FLAG_WRITABLE; |
181 return satisfiable_flags; | 189 return satisfiable_flags; |
182 } | 190 } |
183 | 191 |
184 } // namespace system | 192 } // namespace system |
185 } // namespace mojo | 193 } // namespace mojo |
OLD | NEW |