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/message_in_transit.h" | 11 #include "mojo/system/message_in_transit.h" |
11 | 12 |
12 namespace mojo { | 13 namespace mojo { |
13 namespace system { | 14 namespace system { |
14 | 15 |
| 16 LocalMessagePipeEndpoint::MessageQueueEntry::MessageQueueEntry() |
| 17 : message(NULL) { |
| 18 } |
| 19 |
| 20 // See comment in header file. |
| 21 LocalMessagePipeEndpoint::MessageQueueEntry::MessageQueueEntry( |
| 22 const MessageQueueEntry& other) |
| 23 : message(NULL) { |
| 24 DCHECK(!other.message); |
| 25 DCHECK(other.dispatchers.empty()); |
| 26 } |
| 27 |
| 28 LocalMessagePipeEndpoint::MessageQueueEntry::~MessageQueueEntry() { |
| 29 if (message) |
| 30 message->Destroy(); |
| 31 } |
| 32 |
15 LocalMessagePipeEndpoint::LocalMessagePipeEndpoint() | 33 LocalMessagePipeEndpoint::LocalMessagePipeEndpoint() |
16 : is_open_(true), | 34 : is_open_(true), |
17 is_peer_open_(true) { | 35 is_peer_open_(true) { |
18 } | 36 } |
19 | 37 |
20 LocalMessagePipeEndpoint::~LocalMessagePipeEndpoint() { | 38 LocalMessagePipeEndpoint::~LocalMessagePipeEndpoint() { |
21 DCHECK(!is_open_); | 39 DCHECK(!is_open_); |
22 } | 40 } |
23 | 41 |
24 void LocalMessagePipeEndpoint::Close() { | 42 void LocalMessagePipeEndpoint::Close() { |
25 DCHECK(is_open_); | 43 DCHECK(is_open_); |
26 is_open_ = false; | 44 is_open_ = false; |
27 for (std::deque<MessageInTransit*>::iterator it = message_queue_.begin(); | |
28 it != message_queue_.end(); | |
29 ++it) { | |
30 (*it)->Destroy(); | |
31 } | |
32 message_queue_.clear(); | 45 message_queue_.clear(); |
33 } | 46 } |
34 | 47 |
35 bool LocalMessagePipeEndpoint::OnPeerClose() { | 48 bool LocalMessagePipeEndpoint::OnPeerClose() { |
36 DCHECK(is_open_); | 49 DCHECK(is_open_); |
37 DCHECK(is_peer_open_); | 50 DCHECK(is_peer_open_); |
38 | 51 |
39 MojoWaitFlags old_satisfied_flags = SatisfiedFlags(); | 52 MojoWaitFlags old_satisfied_flags = SatisfiedFlags(); |
40 MojoWaitFlags old_satisfiable_flags = SatisfiableFlags(); | 53 MojoWaitFlags old_satisfiable_flags = SatisfiableFlags(); |
41 is_peer_open_ = false; | 54 is_peer_open_ = false; |
42 MojoWaitFlags new_satisfied_flags = SatisfiedFlags(); | 55 MojoWaitFlags new_satisfied_flags = SatisfiedFlags(); |
43 MojoWaitFlags new_satisfiable_flags = SatisfiableFlags(); | 56 MojoWaitFlags new_satisfiable_flags = SatisfiableFlags(); |
44 | 57 |
45 if (new_satisfied_flags != old_satisfied_flags || | 58 if (new_satisfied_flags != old_satisfied_flags || |
46 new_satisfiable_flags != old_satisfiable_flags) { | 59 new_satisfiable_flags != old_satisfiable_flags) { |
47 waiter_list_.AwakeWaitersForStateChange(new_satisfied_flags, | 60 waiter_list_.AwakeWaitersForStateChange(new_satisfied_flags, |
48 new_satisfiable_flags); | 61 new_satisfiable_flags); |
49 } | 62 } |
50 | 63 |
51 return true; | 64 return true; |
52 } | 65 } |
53 | 66 |
54 MojoResult LocalMessagePipeEndpoint::EnqueueMessage( | 67 MojoResult LocalMessagePipeEndpoint::CanEnqueueMessage( |
| 68 const MessageInTransit* /*message*/, |
| 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; |
| 76 } |
| 77 |
| 78 void LocalMessagePipeEndpoint::EnqueueMessage( |
55 MessageInTransit* message, | 79 MessageInTransit* message, |
56 const std::vector<Dispatcher*>* dispatchers) { | 80 std::vector<scoped_refptr<Dispatcher> >* dispatchers) { |
57 DCHECK(is_open_); | 81 DCHECK(is_open_); |
58 DCHECK(is_peer_open_); | 82 DCHECK(is_peer_open_); |
59 | 83 |
60 // TODO(vtl) | 84 // TODO(vtl) |
61 if (dispatchers) { | 85 DCHECK(!dispatchers || dispatchers->empty()); |
62 message->Destroy(); | |
63 return MOJO_RESULT_UNIMPLEMENTED; | |
64 } | |
65 | 86 |
66 bool was_empty = message_queue_.empty(); | 87 bool was_empty = message_queue_.empty(); |
67 message_queue_.push_back(message); | 88 message_queue_.push_back(MessageQueueEntry()); |
| 89 message_queue_.back().message = message; |
| 90 if (dispatchers) |
| 91 message_queue_.back().dispatchers.swap(*dispatchers); |
68 if (was_empty) { | 92 if (was_empty) { |
69 waiter_list_.AwakeWaitersForStateChange(SatisfiedFlags(), | 93 waiter_list_.AwakeWaitersForStateChange(SatisfiedFlags(), |
70 SatisfiableFlags()); | 94 SatisfiableFlags()); |
71 } | 95 } |
72 | |
73 return MOJO_RESULT_OK; | |
74 } | 96 } |
75 | 97 |
76 void LocalMessagePipeEndpoint::CancelAllWaiters() { | 98 void LocalMessagePipeEndpoint::CancelAllWaiters() { |
77 DCHECK(is_open_); | 99 DCHECK(is_open_); |
78 waiter_list_.CancelAllWaiters(); | 100 waiter_list_.CancelAllWaiters(); |
79 } | 101 } |
80 | 102 |
81 // TODO(vtl): Support receiving handles. | 103 // TODO(vtl): Support receiving handles. |
82 MojoResult LocalMessagePipeEndpoint::ReadMessage( | 104 MojoResult LocalMessagePipeEndpoint::ReadMessage( |
83 void* bytes, uint32_t* num_bytes, | 105 void* bytes, uint32_t* num_bytes, |
84 uint32_t max_num_dispatchers, | 106 uint32_t max_num_dispatchers, |
85 std::vector<scoped_refptr<Dispatcher> >* dispatchers, | 107 std::vector<scoped_refptr<Dispatcher> >* dispatchers, |
86 MojoReadMessageFlags flags) { | 108 MojoReadMessageFlags flags) { |
87 DCHECK(is_open_); | 109 DCHECK(is_open_); |
88 | 110 |
89 const uint32_t max_bytes = num_bytes ? *num_bytes : 0; | 111 const uint32_t max_bytes = num_bytes ? *num_bytes : 0; |
90 // TODO(vtl): We'll need this later: | |
91 // const uint32_t max_handles = num_handles ? *num_handles : 0; | |
92 | 112 |
93 if (message_queue_.empty()) { | 113 if (message_queue_.empty()) { |
94 return is_peer_open_ ? MOJO_RESULT_NOT_FOUND : | 114 return is_peer_open_ ? MOJO_RESULT_NOT_FOUND : |
95 MOJO_RESULT_FAILED_PRECONDITION; | 115 MOJO_RESULT_FAILED_PRECONDITION; |
96 } | 116 } |
97 | 117 |
98 // TODO(vtl): If |flags & MOJO_READ_MESSAGE_FLAG_MAY_DISCARD|, we could pop | 118 // TODO(vtl): If |flags & MOJO_READ_MESSAGE_FLAG_MAY_DISCARD|, we could pop |
99 // and release the lock immediately. | 119 // and release the lock immediately. |
100 bool not_enough_space = false; | 120 bool not_enough_space = false; |
101 MessageInTransit* const message = message_queue_.front(); | 121 MessageInTransit* const message = message_queue_.front().message; |
102 if (num_bytes) | 122 if (num_bytes) |
103 *num_bytes = message->data_size(); | 123 *num_bytes = message->data_size(); |
104 if (message->data_size() <= max_bytes) | 124 if (message->data_size() <= max_bytes) |
105 memcpy(bytes, message->data(), message->data_size()); | 125 memcpy(bytes, message->data(), message->data_size()); |
106 else | 126 else |
107 not_enough_space = true; | 127 not_enough_space = true; |
108 | 128 |
109 if (!not_enough_space || (flags & MOJO_READ_MESSAGE_FLAG_MAY_DISCARD)) { | 129 if (!not_enough_space || (flags & MOJO_READ_MESSAGE_FLAG_MAY_DISCARD)) { |
110 message_queue_.pop_front(); | 130 message_queue_.pop_front(); |
111 message->Destroy(); | |
112 | 131 |
113 // Now it's empty, thus no longer readable. | 132 // Now it's empty, thus no longer readable. |
114 if (message_queue_.empty()) { | 133 if (message_queue_.empty()) { |
115 // It's currently not possible to wait for non-readability, but we should | 134 // It's currently not possible to wait for non-readability, but we should |
116 // do the state change anyway. | 135 // do the state change anyway. |
117 waiter_list_.AwakeWaitersForStateChange(SatisfiedFlags(), | 136 waiter_list_.AwakeWaitersForStateChange(SatisfiedFlags(), |
118 SatisfiableFlags()); | 137 SatisfiableFlags()); |
119 } | 138 } |
120 } | 139 } |
121 | 140 |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
157 MojoWaitFlags satisfiable_flags = 0; | 176 MojoWaitFlags satisfiable_flags = 0; |
158 if (!message_queue_.empty() || is_peer_open_) | 177 if (!message_queue_.empty() || is_peer_open_) |
159 satisfiable_flags |= MOJO_WAIT_FLAG_READABLE; | 178 satisfiable_flags |= MOJO_WAIT_FLAG_READABLE; |
160 if (is_peer_open_) | 179 if (is_peer_open_) |
161 satisfiable_flags |= MOJO_WAIT_FLAG_WRITABLE; | 180 satisfiable_flags |= MOJO_WAIT_FLAG_WRITABLE; |
162 return satisfiable_flags; | 181 return satisfiable_flags; |
163 } | 182 } |
164 | 183 |
165 } // namespace system | 184 } // namespace system |
166 } // namespace mojo | 185 } // namespace mojo |
OLD | NEW |