| 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 |