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

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

Issue 1396783004: Convert mojo::system::ChannelEndpointClient to use our new refcounting stuff (instead of base's). (Closed) Base URL: https://github.com/domokit/mojo.git@master
Patch Set: Created 5 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
« no previous file with comments | « mojo/edk/system/channel_endpoint.h ('k') | mojo/edk/system/channel_endpoint_client.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 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/edk/system/channel_endpoint.h" 5 #include "mojo/edk/system/channel_endpoint.h"
6 6
7 #include <utility> 7 #include <utility>
8 8
9 #include "base/logging.h" 9 #include "base/logging.h"
10 #include "base/threading/platform_thread.h" 10 #include "base/threading/platform_thread.h"
(...skipping 17 matching lines...) Expand all
28 case State::RUNNING: 28 case State::RUNNING:
29 return WriteMessageNoLock(std::move(message)); 29 return WriteMessageNoLock(std::move(message));
30 case State::DEAD: 30 case State::DEAD:
31 return false; 31 return false;
32 } 32 }
33 33
34 NOTREACHED(); 34 NOTREACHED();
35 return false; 35 return false;
36 } 36 }
37 37
38 bool ChannelEndpoint::ReplaceClient(ChannelEndpointClient* client, 38 bool ChannelEndpoint::ReplaceClient(RefPtr<ChannelEndpointClient>&& client,
39 unsigned client_port) { 39 unsigned client_port) {
40 DCHECK(client); 40 DCHECK(client);
41 41
42 MutexLocker locker(&mutex_); 42 MutexLocker locker(&mutex_);
43 DCHECK(client_); 43 DCHECK(client_);
44 DCHECK(client != client_.get() || client_port != client_port_); 44 DCHECK(client != client_ || client_port != client_port_);
45 client_ = client; 45 client_ = std::move(client);
46 client_port_ = client_port; 46 client_port_ = client_port;
47 return state_ != State::DEAD; 47 return state_ != State::DEAD;
48 } 48 }
49 49
50 void ChannelEndpoint::DetachFromClient() { 50 void ChannelEndpoint::DetachFromClient() {
51 MutexLocker locker(&mutex_); 51 MutexLocker locker(&mutex_);
52 DCHECK(client_); 52 DCHECK(client_);
53 client_ = nullptr; 53 client_ = nullptr;
54 54
55 if (!channel_) 55 if (!channel_)
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
95 DCHECK_EQ(message->type(), MessageInTransit::Type::ENDPOINT); 95 DCHECK_EQ(message->type(), MessageInTransit::Type::ENDPOINT);
96 96
97 // TODO(vtl) 97 // TODO(vtl)
98 // Note that this won't crash on Release builds, which is important (since the 98 // Note that this won't crash on Release builds, which is important (since the
99 // other side may be malicious). Doing nothing is safe and will dispose of the 99 // other side may be malicious). Doing nothing is safe and will dispose of the
100 // message. 100 // message.
101 NOTREACHED(); 101 NOTREACHED();
102 } 102 }
103 103
104 void ChannelEndpoint::DetachFromChannel() { 104 void ChannelEndpoint::DetachFromChannel() {
105 scoped_refptr<ChannelEndpointClient> client; 105 RefPtr<ChannelEndpointClient> client;
106 unsigned client_port = 0; 106 unsigned client_port = 0;
107 { 107 {
108 MutexLocker locker(&mutex_); 108 MutexLocker locker(&mutex_);
109 109
110 if (client_) { 110 if (client_) {
111 // Take a ref, and call |OnDetachFromChannel()| outside the lock. 111 // Take a ref, and call |OnDetachFromChannel()| outside the lock.
112 client = client_; 112 client = client_;
113 client_port = client_port_; 113 client_port = client_port_;
114 } 114 }
115 115
116 // |channel_| may already be null if we already detached from the channel in 116 // |channel_| may already be null if we already detached from the channel in
117 // |DetachFromClient()| by calling |Channel::DetachEndpoint()| (and there 117 // |DetachFromClient()| by calling |Channel::DetachEndpoint()| (and there
118 // are racing detaches). 118 // are racing detaches).
119 if (channel_) 119 if (channel_)
120 DieNoLock(); 120 DieNoLock();
121 else 121 else
122 DCHECK(state_ == State::DEAD); 122 DCHECK(state_ == State::DEAD);
123 } 123 }
124 124
125 // If |ReplaceClient()| is called (from another thread) after the above locked 125 // If |ReplaceClient()| is called (from another thread) after the above locked
126 // section but before we call |OnDetachFromChannel()|, |ReplaceClient()| 126 // section but before we call |OnDetachFromChannel()|, |ReplaceClient()|
127 // returns false to notify the caller that the channel was already detached. 127 // returns false to notify the caller that the channel was already detached.
128 // (The old client has to accept the arguably-spurious call to 128 // (The old client has to accept the arguably-spurious call to
129 // |OnDetachFromChannel()|.) 129 // |OnDetachFromChannel()|.)
130 if (client) 130 if (client)
131 client->OnDetachFromChannel(client_port); 131 client->OnDetachFromChannel(client_port);
132 } 132 }
133 133
134 ChannelEndpoint::ChannelEndpoint(ChannelEndpointClient* client, 134 ChannelEndpoint::ChannelEndpoint(RefPtr<ChannelEndpointClient>&& client,
135 unsigned client_port, 135 unsigned client_port,
136 MessageInTransitQueue* message_queue) 136 MessageInTransitQueue* message_queue)
137 : state_(State::PAUSED), 137 : state_(State::PAUSED),
138 client_(client), 138 client_(std::move(client)),
139 client_port_(client_port), 139 client_port_(client_port),
140 channel_(nullptr) { 140 channel_(nullptr) {
141 DCHECK(client_ || message_queue); 141 DCHECK(client_ || message_queue);
142 142
143 if (message_queue) 143 if (message_queue)
144 channel_message_queue_.Swap(message_queue); 144 channel_message_queue_.Swap(message_queue);
145 } 145 }
146 146
147 ChannelEndpoint::~ChannelEndpoint() { 147 ChannelEndpoint::~ChannelEndpoint() {
148 DCHECK(!client_); 148 DCHECK(!client_);
(...skipping 15 matching lines...) Expand all
164 message->SerializeAndCloseDispatchers(channel_); 164 message->SerializeAndCloseDispatchers(channel_);
165 message->set_source_id(local_id_); 165 message->set_source_id(local_id_);
166 message->set_destination_id(remote_id_); 166 message->set_destination_id(remote_id_);
167 return channel_->WriteMessage(std::move(message)); 167 return channel_->WriteMessage(std::move(message));
168 } 168 }
169 169
170 void ChannelEndpoint::OnReadMessageForClient( 170 void ChannelEndpoint::OnReadMessageForClient(
171 std::unique_ptr<MessageInTransit> message) { 171 std::unique_ptr<MessageInTransit> message) {
172 DCHECK_EQ(message->type(), MessageInTransit::Type::ENDPOINT_CLIENT); 172 DCHECK_EQ(message->type(), MessageInTransit::Type::ENDPOINT_CLIENT);
173 173
174 scoped_refptr<ChannelEndpointClient> client; 174 RefPtr<ChannelEndpointClient> client;
175 unsigned client_port = 0; 175 unsigned client_port = 0;
176 176
177 // This loop is to make |ReplaceClient()| work. We can't call the client's 177 // This loop is to make |ReplaceClient()| work. We can't call the client's
178 // |OnReadMessage()| under our lock, so by the time we do that, |client| may 178 // |OnReadMessage()| under our lock, so by the time we do that, |client| may
179 // no longer be our client. 179 // no longer be our client.
180 // 180 //
181 // In that case, |client| must return false. We'll then yield, and retry with 181 // In that case, |client| must return false. We'll then yield, and retry with
182 // the new client. (Theoretically, the client could be replaced again.) 182 // the new client. (Theoretically, the client could be replaced again.)
183 // 183 //
184 // This solution isn't terribly elegant, but it's the least costly way of 184 // This solution isn't terribly elegant, but it's the least costly way of
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
219 DCHECK(remote_id_.is_valid()); 219 DCHECK(remote_id_.is_valid());
220 220
221 state_ = State::DEAD; 221 state_ = State::DEAD;
222 channel_ = nullptr; 222 channel_ = nullptr;
223 local_id_ = ChannelEndpointId(); 223 local_id_ = ChannelEndpointId();
224 remote_id_ = ChannelEndpointId(); 224 remote_id_ = ChannelEndpointId();
225 } 225 }
226 226
227 } // namespace system 227 } // namespace system
228 } // namespace mojo 228 } // namespace mojo
OLDNEW
« no previous file with comments | « mojo/edk/system/channel_endpoint.h ('k') | mojo/edk/system/channel_endpoint_client.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698