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

Unified Diff: third_party/mojo/src/mojo/edk/system/channel_endpoint.cc

Issue 1019173002: Update mojo sdk to rev 7214b7ec7d27563b2666afad86cf1c5895c56c18 (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Keep permission service alive if embedder drops requests Created 5 years, 9 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 side-by-side diff with in-line comments
Download patch
Index: third_party/mojo/src/mojo/edk/system/channel_endpoint.cc
diff --git a/third_party/mojo/src/mojo/edk/system/channel_endpoint.cc b/third_party/mojo/src/mojo/edk/system/channel_endpoint.cc
index 0e071d8eef50a2187b773dee198a9886f0307fd2..72d9e280669297aa888b139fc12080f7dfc4edc1 100644
--- a/third_party/mojo/src/mojo/edk/system/channel_endpoint.cc
+++ b/third_party/mojo/src/mojo/edk/system/channel_endpoint.cc
@@ -93,45 +93,18 @@ void ChannelEndpoint::AttachAndRun(Channel* channel,
}
void ChannelEndpoint::OnReadMessage(scoped_ptr<MessageInTransit> message) {
- scoped_refptr<ChannelEndpointClient> client;
- unsigned client_port = 0;
-
- // This loop is to make |ReplaceClient()| work. We can't call the client's
- // |OnReadMessage()| under our lock, so by the time we do that, |client| may
- // no longer be our client.
- //
- // In that case, |client| must return false. We'll then yield, and retry with
- // the new client. (Theoretically, the client could be replaced again.)
- //
- // This solution isn't terribly elegant, but it's the least costly way of
- // handling/avoiding this (very unlikely) race. (Other solutions -- e.g.,
- // adding a client message queue, which the client only fetches messages from
- // -- impose significant cost in the common case.)
- for (;;) {
- {
- base::AutoLock locker(lock_);
- if (!channel_ || !client_) {
- // This isn't a failure per se. (It just means that, e.g., the other end
- // of the message point closed first.)
- return;
- }
-
- // If we get here in a second (third, etc.) iteration of the loop, it's
- // because |ReplaceClient()| was called.
- DCHECK(client_ != client || client_port_ != client_port);
-
- // Take a ref, and call |OnReadMessage()| outside the lock.
- client = client_;
- client_port = client_port_;
- }
+ if (message->type() == MessageInTransit::kTypeEndpointClient) {
+ OnReadMessageForClient(message.Pass());
+ return;
+ }
- if (client->OnReadMessage(client_port, message.get())) {
- ignore_result(message.release());
- break;
- }
+ DCHECK_EQ(message->type(), MessageInTransit::kTypeEndpoint);
- base::PlatformThread::YieldCurrentThread();
- }
+ // TODO(vtl)
+ // Note that this won't crash on Release builds, which is important (since the
+ // other side may be malicious). Doing nothing is safe and will dispose of the
+ // message.
+ NOTREACHED();
}
void ChannelEndpoint::DetachFromChannel() {
@@ -186,6 +159,51 @@ bool ChannelEndpoint::WriteMessageNoLock(scoped_ptr<MessageInTransit> message) {
return channel_->WriteMessage(message.Pass());
}
+void ChannelEndpoint::OnReadMessageForClient(
+ scoped_ptr<MessageInTransit> message) {
+ DCHECK_EQ(message->type(), MessageInTransit::kTypeEndpointClient);
+
+ scoped_refptr<ChannelEndpointClient> client;
+ unsigned client_port = 0;
+
+ // This loop is to make |ReplaceClient()| work. We can't call the client's
+ // |OnReadMessage()| under our lock, so by the time we do that, |client| may
+ // no longer be our client.
+ //
+ // In that case, |client| must return false. We'll then yield, and retry with
+ // the new client. (Theoretically, the client could be replaced again.)
+ //
+ // This solution isn't terribly elegant, but it's the least costly way of
+ // handling/avoiding this (very unlikely) race. (Other solutions -- e.g.,
+ // adding a client message queue, which the client only fetches messages from
+ // -- impose significant cost in the common case.)
+ for (;;) {
+ {
+ base::AutoLock locker(lock_);
+ if (!channel_ || !client_) {
+ // This isn't a failure per se. (It just means that, e.g., the other end
+ // of the message point closed first.)
+ return;
+ }
+
+ // If we get here in a second (third, etc.) iteration of the loop, it's
+ // because |ReplaceClient()| was called.
+ DCHECK(client_ != client || client_port_ != client_port);
+
+ // Take a ref, and call |OnReadMessage()| outside the lock.
+ client = client_;
+ client_port = client_port_;
+ }
+
+ if (client->OnReadMessage(client_port, message.get())) {
+ ignore_result(message.release());
+ break;
+ }
+
+ base::PlatformThread::YieldCurrentThread();
+ }
+}
+
void ChannelEndpoint::ResetChannelNoLock() {
DCHECK(channel_);
DCHECK(local_id_.is_valid());
« no previous file with comments | « third_party/mojo/src/mojo/edk/system/channel_endpoint.h ('k') | third_party/mojo/src/mojo/edk/system/connection_manager.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698