Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(469)

Side by Side Diff: mojo/edk/system/local_message_pipe_endpoint.cc

Issue 814543006: Move //mojo/{public, edk} underneath //third_party (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Rebase Created 5 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « mojo/edk/system/local_message_pipe_endpoint.h ('k') | mojo/edk/system/mapping_table.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
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
3 // found in the LICENSE file.
4
5 #include "mojo/edk/system/local_message_pipe_endpoint.h"
6
7 #include <string.h>
8
9 #include "base/logging.h"
10 #include "mojo/edk/system/dispatcher.h"
11 #include "mojo/edk/system/message_in_transit.h"
12
13 namespace mojo {
14 namespace system {
15
16 LocalMessagePipeEndpoint::LocalMessagePipeEndpoint(
17 MessageInTransitQueue* message_queue)
18 : is_open_(true), is_peer_open_(true) {
19 if (message_queue)
20 message_queue_.Swap(message_queue);
21 }
22
23 LocalMessagePipeEndpoint::~LocalMessagePipeEndpoint() {
24 DCHECK(!is_open_);
25 DCHECK(message_queue_.IsEmpty()); // Should be implied by not being open.
26 }
27
28 MessagePipeEndpoint::Type LocalMessagePipeEndpoint::GetType() const {
29 return kTypeLocal;
30 }
31
32 bool LocalMessagePipeEndpoint::OnPeerClose() {
33 DCHECK(is_open_);
34 DCHECK(is_peer_open_);
35
36 HandleSignalsState old_state = GetHandleSignalsState();
37 is_peer_open_ = false;
38 HandleSignalsState new_state = GetHandleSignalsState();
39
40 if (!new_state.equals(old_state))
41 awakable_list_.AwakeForStateChange(new_state);
42
43 return true;
44 }
45
46 void LocalMessagePipeEndpoint::EnqueueMessage(
47 scoped_ptr<MessageInTransit> message) {
48 DCHECK(is_open_);
49 DCHECK(is_peer_open_);
50
51 bool was_empty = message_queue_.IsEmpty();
52 message_queue_.AddMessage(message.Pass());
53 if (was_empty)
54 awakable_list_.AwakeForStateChange(GetHandleSignalsState());
55 }
56
57 void LocalMessagePipeEndpoint::Close() {
58 DCHECK(is_open_);
59 is_open_ = false;
60 message_queue_.Clear();
61 }
62
63 void LocalMessagePipeEndpoint::CancelAllAwakables() {
64 DCHECK(is_open_);
65 awakable_list_.CancelAll();
66 }
67
68 MojoResult LocalMessagePipeEndpoint::ReadMessage(
69 UserPointer<void> bytes,
70 UserPointer<uint32_t> num_bytes,
71 DispatcherVector* dispatchers,
72 uint32_t* num_dispatchers,
73 MojoReadMessageFlags flags) {
74 DCHECK(is_open_);
75 DCHECK(!dispatchers || dispatchers->empty());
76
77 const uint32_t max_bytes = num_bytes.IsNull() ? 0 : num_bytes.Get();
78 const uint32_t max_num_dispatchers = num_dispatchers ? *num_dispatchers : 0;
79
80 if (message_queue_.IsEmpty()) {
81 return is_peer_open_ ? MOJO_RESULT_SHOULD_WAIT
82 : MOJO_RESULT_FAILED_PRECONDITION;
83 }
84
85 // TODO(vtl): If |flags & MOJO_READ_MESSAGE_FLAG_MAY_DISCARD|, we could pop
86 // and release the lock immediately.
87 bool enough_space = true;
88 MessageInTransit* message = message_queue_.PeekMessage();
89 if (!num_bytes.IsNull())
90 num_bytes.Put(message->num_bytes());
91 if (message->num_bytes() <= max_bytes)
92 bytes.PutArray(message->bytes(), message->num_bytes());
93 else
94 enough_space = false;
95
96 if (DispatcherVector* queued_dispatchers = message->dispatchers()) {
97 if (num_dispatchers)
98 *num_dispatchers = static_cast<uint32_t>(queued_dispatchers->size());
99 if (enough_space) {
100 if (queued_dispatchers->empty()) {
101 // Nothing to do.
102 } else if (queued_dispatchers->size() <= max_num_dispatchers) {
103 DCHECK(dispatchers);
104 dispatchers->swap(*queued_dispatchers);
105 } else {
106 enough_space = false;
107 }
108 }
109 } else {
110 if (num_dispatchers)
111 *num_dispatchers = 0;
112 }
113
114 message = nullptr;
115
116 if (enough_space || (flags & MOJO_READ_MESSAGE_FLAG_MAY_DISCARD)) {
117 message_queue_.DiscardMessage();
118
119 // Now it's empty, thus no longer readable.
120 if (message_queue_.IsEmpty()) {
121 // It's currently not possible to wait for non-readability, but we should
122 // do the state change anyway.
123 awakable_list_.AwakeForStateChange(GetHandleSignalsState());
124 }
125 }
126
127 if (!enough_space)
128 return MOJO_RESULT_RESOURCE_EXHAUSTED;
129
130 return MOJO_RESULT_OK;
131 }
132
133 HandleSignalsState LocalMessagePipeEndpoint::GetHandleSignalsState() const {
134 HandleSignalsState rv;
135 if (!message_queue_.IsEmpty()) {
136 rv.satisfied_signals |= MOJO_HANDLE_SIGNAL_READABLE;
137 rv.satisfiable_signals |= MOJO_HANDLE_SIGNAL_READABLE;
138 }
139 if (is_peer_open_) {
140 rv.satisfied_signals |= MOJO_HANDLE_SIGNAL_WRITABLE;
141 rv.satisfiable_signals |=
142 MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE;
143 } else {
144 rv.satisfied_signals |= MOJO_HANDLE_SIGNAL_PEER_CLOSED;
145 }
146 rv.satisfiable_signals |= MOJO_HANDLE_SIGNAL_PEER_CLOSED;
147 return rv;
148 }
149
150 MojoResult LocalMessagePipeEndpoint::AddAwakable(
151 Awakable* awakable,
152 MojoHandleSignals signals,
153 uint32_t context,
154 HandleSignalsState* signals_state) {
155 DCHECK(is_open_);
156
157 HandleSignalsState state = GetHandleSignalsState();
158 if (state.satisfies(signals)) {
159 if (signals_state)
160 *signals_state = state;
161 return MOJO_RESULT_ALREADY_EXISTS;
162 }
163 if (!state.can_satisfy(signals)) {
164 if (signals_state)
165 *signals_state = state;
166 return MOJO_RESULT_FAILED_PRECONDITION;
167 }
168
169 awakable_list_.Add(awakable, signals, context);
170 return MOJO_RESULT_OK;
171 }
172
173 void LocalMessagePipeEndpoint::RemoveAwakable(
174 Awakable* awakable,
175 HandleSignalsState* signals_state) {
176 DCHECK(is_open_);
177 awakable_list_.Remove(awakable);
178 if (signals_state)
179 *signals_state = GetHandleSignalsState();
180 }
181
182 } // namespace system
183 } // namespace mojo
OLDNEW
« no previous file with comments | « mojo/edk/system/local_message_pipe_endpoint.h ('k') | mojo/edk/system/mapping_table.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698