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

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

Issue 27060003: Mojo: Abstract out the endpoints of MessagePipes. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: rebased Created 7 years, 2 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 | Annotate | Revision Log
« no previous file with comments | « mojo/system/local_message_pipe_endpoint.h ('k') | mojo/system/message_pipe.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/system/local_message_pipe_endpoint.h"
6
7 #include <string.h>
8
9 #include "base/logging.h"
10 #include "base/stl_util.h"
11 #include "mojo/system/message_in_transit.h"
12
13 namespace mojo {
14 namespace system {
15
16 LocalMessagePipeEndpoint::LocalMessagePipeEndpoint()
17 : is_open_(true),
18 is_peer_open_(true) {
19 }
20
21 LocalMessagePipeEndpoint::~LocalMessagePipeEndpoint() {
22 DCHECK(!is_open_);
23 }
24
25 void LocalMessagePipeEndpoint::OnPeerClose() {
26 DCHECK(is_open_);
27 DCHECK(is_peer_open_);
28
29 MojoWaitFlags old_satisfied_flags = SatisfiedFlags();
30 MojoWaitFlags old_satisfiable_flags = SatisfiableFlags();
31 is_peer_open_ = false;
32 MojoWaitFlags new_satisfied_flags = SatisfiedFlags();
33 MojoWaitFlags new_satisfiable_flags = SatisfiableFlags();
34
35 if (new_satisfied_flags != old_satisfied_flags ||
36 new_satisfiable_flags != old_satisfiable_flags) {
37 waiter_list_.AwakeWaitersForStateChange(new_satisfied_flags,
38 new_satisfiable_flags);
39 }
40 }
41
42 MojoResult LocalMessagePipeEndpoint::EnqueueMessage(
43 const void* bytes, uint32_t num_bytes,
44 const MojoHandle* handles, uint32_t num_handles,
45 MojoWriteMessageFlags /*flags*/) {
46 DCHECK(is_open_);
47 DCHECK(is_peer_open_);
48
49 bool was_empty = message_queue_.empty();
50
51 // TODO(vtl): Eventually (with C++11), this should be an |emplace_back()|.
52 message_queue_.push_back(MessageInTransit::Create(bytes, num_bytes));
53 // TODO(vtl): Support sending handles.
54
55 if (was_empty) {
56 waiter_list_.AwakeWaitersForStateChange(SatisfiedFlags(),
57 SatisfiableFlags());
58 }
59
60 return MOJO_RESULT_OK;
61 }
62
63 void LocalMessagePipeEndpoint::CancelAllWaiters() {
64 DCHECK(is_open_);
65 waiter_list_.CancelAllWaiters();
66 }
67
68 void LocalMessagePipeEndpoint::Close() {
69 DCHECK(is_open_);
70 is_open_ = false;
71 STLDeleteElements(&message_queue_);
72 }
73
74 MojoResult LocalMessagePipeEndpoint::ReadMessage(
75 void* bytes, uint32_t* num_bytes,
76 MojoHandle* handles, uint32_t* num_handles,
77 MojoReadMessageFlags flags) {
78 DCHECK(is_open_);
79
80 const uint32_t max_bytes = num_bytes ? *num_bytes : 0;
81 // TODO(vtl): We'll need this later:
82 // const uint32_t max_handles = num_handles ? *num_handles : 0;
83
84 if (message_queue_.empty())
85 return MOJO_RESULT_NOT_FOUND;
86
87 // TODO(vtl): If |flags & MOJO_READ_MESSAGE_FLAG_MAY_DISCARD|, we could pop
88 // and release the lock immediately.
89 bool not_enough_space = false;
90 MessageInTransit* const message = message_queue_.front();
91 if (num_bytes)
92 *num_bytes = message->data_size();
93 if (message->data_size() <= max_bytes)
94 memcpy(bytes, message->data(), message->data_size());
95 else
96 not_enough_space = true;
97
98 // TODO(vtl): Support receiving handles.
99 if (num_handles)
100 *num_handles = 0;
101
102 if (!not_enough_space || (flags & MOJO_READ_MESSAGE_FLAG_MAY_DISCARD)) {
103 message_queue_.pop_front();
104 message->Destroy();
105
106 // Now it's empty, thus no longer readable.
107 if (message_queue_.empty()) {
108 // It's currently not possible to wait for non-readability, but we should
109 // do the state change anyway.
110 waiter_list_.AwakeWaitersForStateChange(SatisfiedFlags(),
111 SatisfiableFlags());
112 }
113 }
114
115 if (not_enough_space)
116 return MOJO_RESULT_RESOURCE_EXHAUSTED;
117
118 return MOJO_RESULT_OK;
119 }
120
121 MojoResult LocalMessagePipeEndpoint::AddWaiter(Waiter* waiter,
122 MojoWaitFlags flags,
123 MojoResult wake_result) {
124 DCHECK(is_open_);
125
126 if ((flags & SatisfiedFlags()))
127 return MOJO_RESULT_ALREADY_EXISTS;
128 if (!(flags & SatisfiableFlags()))
129 return MOJO_RESULT_FAILED_PRECONDITION;
130
131 waiter_list_.AddWaiter(waiter, flags, wake_result);
132 return MOJO_RESULT_OK;
133 }
134
135 void LocalMessagePipeEndpoint::RemoveWaiter(Waiter* waiter) {
136 DCHECK(is_open_);
137 waiter_list_.RemoveWaiter(waiter);
138 }
139
140 MojoWaitFlags LocalMessagePipeEndpoint::SatisfiedFlags() {
141 MojoWaitFlags satisfied_flags = 0;
142 if (!message_queue_.empty())
143 satisfied_flags |= MOJO_WAIT_FLAG_READABLE;
144 if (is_peer_open_)
145 satisfied_flags |= MOJO_WAIT_FLAG_WRITABLE;
146 return satisfied_flags;
147 }
148
149 MojoWaitFlags LocalMessagePipeEndpoint::SatisfiableFlags() {
150 MojoWaitFlags satisfiable_flags = 0;
151 if (!message_queue_.empty() || is_peer_open_)
152 satisfiable_flags |= MOJO_WAIT_FLAG_READABLE;
153 if (is_peer_open_)
154 satisfiable_flags |= MOJO_WAIT_FLAG_WRITABLE;
155 return satisfiable_flags;
156 }
157
158 } // namespace system
159 } // namespace mojo
160
OLDNEW
« no previous file with comments | « mojo/system/local_message_pipe_endpoint.h ('k') | mojo/system/message_pipe.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698