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

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

Issue 292983007: Mojo: Make PlatformChannelRecvmsg() append handles to a deque instead. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: review comments Created 6 years, 7 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/mojo.gyp ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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/raw_channel.h" 5 #include "mojo/system/raw_channel.h"
6 6
7 #include <errno.h> 7 #include <errno.h>
8 #include <sys/uio.h> 8 #include <sys/uio.h>
9 #include <unistd.h> 9 #include <unistd.h>
10 10
11 #include <algorithm> 11 #include <algorithm>
12 #include <deque>
12 13
13 #include "base/basictypes.h" 14 #include "base/basictypes.h"
14 #include "base/bind.h" 15 #include "base/bind.h"
15 #include "base/compiler_specific.h" 16 #include "base/compiler_specific.h"
16 #include "base/location.h" 17 #include "base/location.h"
17 #include "base/logging.h" 18 #include "base/logging.h"
18 #include "base/memory/scoped_ptr.h" 19 #include "base/memory/scoped_ptr.h"
19 #include "base/memory/weak_ptr.h" 20 #include "base/memory/weak_ptr.h"
20 #include "base/message_loop/message_loop.h" 21 #include "base/message_loop/message_loop.h"
21 #include "base/synchronization/lock.h" 22 #include "base/synchronization/lock.h"
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
61 void WaitToWrite(); 62 void WaitToWrite();
62 63
63 embedder::ScopedPlatformHandle fd_; 64 embedder::ScopedPlatformHandle fd_;
64 65
65 // The following members are only used on the I/O thread: 66 // The following members are only used on the I/O thread:
66 scoped_ptr<base::MessageLoopForIO::FileDescriptorWatcher> read_watcher_; 67 scoped_ptr<base::MessageLoopForIO::FileDescriptorWatcher> read_watcher_;
67 scoped_ptr<base::MessageLoopForIO::FileDescriptorWatcher> write_watcher_; 68 scoped_ptr<base::MessageLoopForIO::FileDescriptorWatcher> write_watcher_;
68 69
69 bool pending_read_; 70 bool pending_read_;
70 71
71 embedder::ScopedPlatformHandleVectorPtr read_platform_handles_; 72 std::deque<embedder::PlatformHandle> read_platform_handles_;
72 73
73 // The following members are used on multiple threads and protected by 74 // The following members are used on multiple threads and protected by
74 // |write_lock()|: 75 // |write_lock()|:
75 bool pending_write_; 76 bool pending_write_;
76 77
77 // This is used for posting tasks from write threads to the I/O thread. It 78 // This is used for posting tasks from write threads to the I/O thread. It
78 // must only be accessed under |write_lock_|. The weak pointers it produces 79 // must only be accessed under |write_lock_|. The weak pointers it produces
79 // are only used/invalidated on the I/O thread. 80 // are only used/invalidated on the I/O thread.
80 base::WeakPtrFactory<RawChannelPosix> weak_ptr_factory_; 81 base::WeakPtrFactory<RawChannelPosix> weak_ptr_factory_;
81 82
(...skipping 13 matching lines...) Expand all
95 DCHECK(!pending_write_); 96 DCHECK(!pending_write_);
96 97
97 // No need to take the |write_lock()| here -- if there are still weak pointers 98 // No need to take the |write_lock()| here -- if there are still weak pointers
98 // outstanding, then we're hosed anyway (since we wouldn't be able to 99 // outstanding, then we're hosed anyway (since we wouldn't be able to
99 // invalidate them cleanly, since we might not be on the I/O thread). 100 // invalidate them cleanly, since we might not be on the I/O thread).
100 DCHECK(!weak_ptr_factory_.HasWeakPtrs()); 101 DCHECK(!weak_ptr_factory_.HasWeakPtrs());
101 102
102 // These must have been shut down/destroyed on the I/O thread. 103 // These must have been shut down/destroyed on the I/O thread.
103 DCHECK(!read_watcher_.get()); 104 DCHECK(!read_watcher_.get());
104 DCHECK(!write_watcher_.get()); 105 DCHECK(!write_watcher_.get());
106
107 embedder::CloseAllPlatformHandles(&read_platform_handles_);
105 } 108 }
106 109
107 size_t RawChannelPosix::GetSerializedPlatformHandleSize() const { 110 size_t RawChannelPosix::GetSerializedPlatformHandleSize() const {
108 // We don't actually need any space on POSIX (since we just send FDs). 111 // We don't actually need any space on POSIX (since we just send FDs).
109 return 0; 112 return 0;
110 } 113 }
111 114
112 RawChannel::IOResult RawChannelPosix::Read(size_t* bytes_read) { 115 RawChannel::IOResult RawChannelPosix::Read(size_t* bytes_read) {
113 DCHECK_EQ(base::MessageLoop::current(), message_loop_for_io()); 116 DCHECK_EQ(base::MessageLoop::current(), message_loop_for_io());
114 DCHECK(!pending_read_); 117 DCHECK(!pending_read_);
115 118
116 char* buffer = NULL; 119 char* buffer = NULL;
117 size_t bytes_to_read = 0; 120 size_t bytes_to_read = 0;
118 read_buffer()->GetBuffer(&buffer, &bytes_to_read); 121 read_buffer()->GetBuffer(&buffer, &bytes_to_read);
119 122
120 size_t old_num_platform_handles = 123 size_t old_num_platform_handles = read_platform_handles_.size();
121 read_platform_handles_ ? read_platform_handles_->size() : 0;
122 ssize_t read_result = 124 ssize_t read_result =
123 embedder::PlatformChannelRecvmsg(fd_.get(), 125 embedder::PlatformChannelRecvmsg(fd_.get(),
124 buffer, 126 buffer,
125 bytes_to_read, 127 bytes_to_read,
126 &read_platform_handles_); 128 &read_platform_handles_);
127 if (read_platform_handles_ && 129 if (read_platform_handles_.size() > old_num_platform_handles) {
128 read_platform_handles_->size() > old_num_platform_handles) { 130 DCHECK_LE(read_platform_handles_.size() - old_num_platform_handles,
131 embedder::kPlatformChannelMaxNumHandles);
132
129 if (read_result != 1) { 133 if (read_result != 1) {
130 LOG(WARNING) << "Invalid control message with platform handles"; 134 LOG(WARNING) << "Invalid control message with platform handles";
131 return IO_FAILED; 135 return IO_FAILED;
132 } 136 }
133 137
134 if (read_platform_handles_->size() > TransportData::kMaxPlatformHandles) { 138 // We should never accumulate more than |TransportData::kMaxPlatformHandles
139 // + embedder::kPlatformChannelMaxNumHandles| handles. (The latter part is
140 // possible because we could have accumulated all the handles for a message,
141 // then received the message data plus the first set of handles for the next
142 // message in the subsequent |recvmsg()|.)
143 if (read_platform_handles_.size() > (TransportData::kMaxPlatformHandles +
144 embedder::kPlatformChannelMaxNumHandles)) {
135 LOG(WARNING) << "Received too many platform handles"; 145 LOG(WARNING) << "Received too many platform handles";
136 read_platform_handles_.reset(); 146 embedder::CloseAllPlatformHandles(&read_platform_handles_);
147 read_platform_handles_.clear();
137 return IO_FAILED; 148 return IO_FAILED;
138 } 149 }
139 150
140 // This wasn't a data read (platform handles just get stashed). 151 // This wasn't a data read (platform handles just get stashed).
141 return ScheduleRead(); 152 return ScheduleRead();
142 } 153 }
143 154
144 if (read_result > 0) { 155 if (read_result > 0) {
145 *bytes_read = static_cast<size_t>(read_result); 156 *bytes_read = static_cast<size_t>(read_result);
146 return IO_SUCCEEDED; 157 return IO_SUCCEEDED;
(...skipping 19 matching lines...) Expand all
166 pending_read_ = true; 177 pending_read_ = true;
167 178
168 return IO_PENDING; 179 return IO_PENDING;
169 } 180 }
170 181
171 embedder::ScopedPlatformHandleVectorPtr RawChannelPosix::GetReadPlatformHandles( 182 embedder::ScopedPlatformHandleVectorPtr RawChannelPosix::GetReadPlatformHandles(
172 size_t num_platform_handles, 183 size_t num_platform_handles,
173 const void* /*platform_handle_table*/) { 184 const void* /*platform_handle_table*/) {
174 DCHECK_GT(num_platform_handles, 0u); 185 DCHECK_GT(num_platform_handles, 0u);
175 186
176 if (!read_platform_handles_ || 187 if (read_platform_handles_.size() < num_platform_handles) {
177 read_platform_handles_->size() != num_platform_handles) { 188 embedder::CloseAllPlatformHandles(&read_platform_handles_);
178 read_platform_handles_.reset(); 189 read_platform_handles_.clear();
179 return embedder::ScopedPlatformHandleVectorPtr(); 190 return embedder::ScopedPlatformHandleVectorPtr();
180 } 191 }
181 192
182 return read_platform_handles_.Pass(); 193 embedder::ScopedPlatformHandleVectorPtr rv(
194 new embedder::PlatformHandleVector(num_platform_handles));
195 rv->assign(read_platform_handles_.begin(),
196 read_platform_handles_.begin() + num_platform_handles);
197 read_platform_handles_.erase(
198 read_platform_handles_.begin(),
199 read_platform_handles_.begin() + num_platform_handles);
200 return rv.Pass();
183 } 201 }
184 202
185 RawChannel::IOResult RawChannelPosix::WriteNoLock( 203 RawChannel::IOResult RawChannelPosix::WriteNoLock(
186 size_t* platform_handles_written, 204 size_t* platform_handles_written,
187 size_t* bytes_written) { 205 size_t* bytes_written) {
188 write_lock().AssertAcquired(); 206 write_lock().AssertAcquired();
189 207
190 DCHECK(!pending_write_); 208 DCHECK(!pending_write_);
191 209
192 if (write_buffer_no_lock()->HavePlatformHandlesToSend()) { 210 if (write_buffer_no_lock()->HavePlatformHandlesToSend()) {
(...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after
385 403
386 // Static factory method declared in raw_channel.h. 404 // Static factory method declared in raw_channel.h.
387 // static 405 // static
388 scoped_ptr<RawChannel> RawChannel::Create( 406 scoped_ptr<RawChannel> RawChannel::Create(
389 embedder::ScopedPlatformHandle handle) { 407 embedder::ScopedPlatformHandle handle) {
390 return scoped_ptr<RawChannel>(new RawChannelPosix(handle.Pass())); 408 return scoped_ptr<RawChannel>(new RawChannelPosix(handle.Pass()));
391 } 409 }
392 410
393 } // namespace system 411 } // namespace system
394 } // namespace mojo 412 } // namespace mojo
OLDNEW
« no previous file with comments | « mojo/mojo.gyp ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698