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

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

Issue 277083003: Mojo: (Theoretically) implement the read side of platform handle passing. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: 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
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 12
13 #include "base/basictypes.h" 13 #include "base/basictypes.h"
14 #include "base/bind.h" 14 #include "base/bind.h"
15 #include "base/compiler_specific.h" 15 #include "base/compiler_specific.h"
16 #include "base/location.h" 16 #include "base/location.h"
17 #include "base/logging.h" 17 #include "base/logging.h"
18 #include "base/memory/scoped_ptr.h" 18 #include "base/memory/scoped_ptr.h"
19 #include "base/memory/weak_ptr.h" 19 #include "base/memory/weak_ptr.h"
20 #include "base/message_loop/message_loop.h" 20 #include "base/message_loop/message_loop.h"
21 #include "base/synchronization/lock.h" 21 #include "base/synchronization/lock.h"
22 #include "mojo/embedder/platform_channel_utils_posix.h" 22 #include "mojo/embedder/platform_channel_utils_posix.h"
23 #include "mojo/embedder/platform_handle.h" 23 #include "mojo/embedder/platform_handle.h"
24 #include "mojo/embedder/platform_handle_vector.h"
25 #include "mojo/system/transport_data.h"
24 26
25 namespace mojo { 27 namespace mojo {
26 namespace system { 28 namespace system {
27 29
28 namespace { 30 namespace {
29 31
30 class RawChannelPosix : public RawChannel, 32 class RawChannelPosix : public RawChannel,
31 public base::MessageLoopForIO::Watcher { 33 public base::MessageLoopForIO::Watcher {
32 public: 34 public:
33 RawChannelPosix(embedder::ScopedPlatformHandle handle); 35 RawChannelPosix(embedder::ScopedPlatformHandle handle);
34 virtual ~RawChannelPosix(); 36 virtual ~RawChannelPosix();
35 37
36 // |RawChannel| public methods: 38 // |RawChannel| public methods:
37 virtual size_t GetSerializedPlatformHandleSize() const OVERRIDE; 39 virtual size_t GetSerializedPlatformHandleSize() const OVERRIDE;
38 40
39 private: 41 private:
40 // |RawChannel| protected methods: 42 // |RawChannel| protected methods:
41 virtual IOResult Read(size_t* bytes_read) OVERRIDE; 43 virtual IOResult Read(size_t* bytes_read) OVERRIDE;
42 virtual IOResult ScheduleRead() OVERRIDE; 44 virtual IOResult ScheduleRead() OVERRIDE;
45 virtual scoped_ptr<embedder::PlatformHandleVector> GetReadPlatformHandles(
46 size_t num_platform_handles,
47 const void* platform_handle_table) OVERRIDE;
43 virtual IOResult WriteNoLock(size_t* platform_handles_written, 48 virtual IOResult WriteNoLock(size_t* platform_handles_written,
44 size_t* bytes_written) OVERRIDE; 49 size_t* bytes_written) OVERRIDE;
45 virtual IOResult ScheduleWriteNoLock() OVERRIDE; 50 virtual IOResult ScheduleWriteNoLock() OVERRIDE;
46 virtual bool OnInit() OVERRIDE; 51 virtual bool OnInit() OVERRIDE;
47 virtual void OnShutdownNoLock( 52 virtual void OnShutdownNoLock(
48 scoped_ptr<ReadBuffer> read_buffer, 53 scoped_ptr<ReadBuffer> read_buffer,
49 scoped_ptr<WriteBuffer> write_buffer) OVERRIDE; 54 scoped_ptr<WriteBuffer> write_buffer) OVERRIDE;
50 55
51 // |base::MessageLoopForIO::Watcher| implementation: 56 // |base::MessageLoopForIO::Watcher| implementation:
52 virtual void OnFileCanReadWithoutBlocking(int fd) OVERRIDE; 57 virtual void OnFileCanReadWithoutBlocking(int fd) OVERRIDE;
53 virtual void OnFileCanWriteWithoutBlocking(int fd) OVERRIDE; 58 virtual void OnFileCanWriteWithoutBlocking(int fd) OVERRIDE;
54 59
55 // Watches for |fd_| to become writable. Must be called on the I/O thread. 60 // Watches for |fd_| to become writable. Must be called on the I/O thread.
56 void WaitToWrite(); 61 void WaitToWrite();
57 62
58 embedder::ScopedPlatformHandle fd_; 63 embedder::ScopedPlatformHandle fd_;
59 64
60 // The following members are only used on the I/O thread: 65 // The following members are only used on the I/O thread:
61 scoped_ptr<base::MessageLoopForIO::FileDescriptorWatcher> read_watcher_; 66 scoped_ptr<base::MessageLoopForIO::FileDescriptorWatcher> read_watcher_;
62 scoped_ptr<base::MessageLoopForIO::FileDescriptorWatcher> write_watcher_; 67 scoped_ptr<base::MessageLoopForIO::FileDescriptorWatcher> write_watcher_;
63 68
64 bool pending_read_; 69 bool pending_read_;
65 70
71 scoped_ptr<embedder::PlatformHandleVector> read_platform_handles_;
72
66 // The following members are used on multiple threads and protected by 73 // The following members are used on multiple threads and protected by
67 // |write_lock()|: 74 // |write_lock()|:
68 bool pending_write_; 75 bool pending_write_;
69 76
70 // This is used for posting tasks from write threads to the I/O thread. It 77 // This is used for posting tasks from write threads to the I/O thread. It
71 // must only be accessed under |write_lock_|. The weak pointers it produces 78 // must only be accessed under |write_lock_|. The weak pointers it produces
72 // are only used/invalidated on the I/O thread. 79 // are only used/invalidated on the I/O thread.
73 base::WeakPtrFactory<RawChannelPosix> weak_ptr_factory_; 80 base::WeakPtrFactory<RawChannelPosix> weak_ptr_factory_;
74 81
75 DISALLOW_COPY_AND_ASSIGN(RawChannelPosix); 82 DISALLOW_COPY_AND_ASSIGN(RawChannelPosix);
(...skipping 27 matching lines...) Expand all
103 } 110 }
104 111
105 RawChannel::IOResult RawChannelPosix::Read(size_t* bytes_read) { 112 RawChannel::IOResult RawChannelPosix::Read(size_t* bytes_read) {
106 DCHECK_EQ(base::MessageLoop::current(), message_loop_for_io()); 113 DCHECK_EQ(base::MessageLoop::current(), message_loop_for_io());
107 DCHECK(!pending_read_); 114 DCHECK(!pending_read_);
108 115
109 char* buffer = NULL; 116 char* buffer = NULL;
110 size_t bytes_to_read = 0; 117 size_t bytes_to_read = 0;
111 read_buffer()->GetBuffer(&buffer, &bytes_to_read); 118 read_buffer()->GetBuffer(&buffer, &bytes_to_read);
112 119
113 scoped_ptr<embedder::PlatformHandleVector> handles; 120 size_t old_num_platform_handles =
114 ssize_t read_result = embedder::PlatformChannelRecvmsg(fd_.get(), 121 read_platform_handles_ ? read_platform_handles_->size() : 0;
115 buffer, 122 ssize_t read_result =
116 bytes_to_read, 123 embedder::PlatformChannelRecvmsg(fd_.get(),
117 &handles); 124 buffer,
125 bytes_to_read,
126 &read_platform_handles_);
118 if (read_result > 0) { 127 if (read_result > 0) {
119 *bytes_read = static_cast<size_t>(read_result); 128 *bytes_read = static_cast<size_t>(read_result);
120 return IO_SUCCEEDED; 129 return IO_SUCCEEDED;
121 } 130 }
122 131
123 if (handles) { 132 if (read_platform_handles_ &&
133 read_platform_handles_->size() > old_num_platform_handles) {
124 if (read_result != 1) { 134 if (read_result != 1) {
125 LOG(WARNING) << "Invalid control message with handles"; 135 LOG(WARNING) << "Invalid control message with platform handles";
126 return IO_FAILED; 136 return IO_FAILED;
127 } 137 }
128 138
129 // TODO(vtl): Implement this ("buffer" received handles). For now, just drop 139 if (read_platform_handles_->size() > TransportData::kMaxPlatformHandles) {
130 // them on the floor. (Discard this message entirely.) 140 LOG(WARNING) << "Received too many platform handles";
131 NOTIMPLEMENTED(); 141 read_platform_handles_.reset();
yzshen1 2014/05/11 07:16:59 The handles need to be closed? (here and line 176)
viettrungluu 2014/05/12 17:33:28 Done.
132 for (size_t i = 0; i < handles->size(); i++) 142 return IO_FAILED;
133 (*handles)[i].CloseIfNecessary(); 143 }
134 return ScheduleRead();
135 } 144 }
136 145
137 // |read_result == 0| means "end of file". 146 // |read_result == 0| means "end of file".
138 if (read_result == 0 || (errno != EAGAIN && errno != EWOULDBLOCK)) { 147 if (read_result == 0 || (errno != EAGAIN && errno != EWOULDBLOCK)) {
139 PLOG_IF(ERROR, read_result != 0) << "recvmsg"; 148 PLOG_IF(ERROR, read_result != 0) << "recvmsg";
140 149
141 // Make sure that |OnFileCanReadWithoutBlocking()| won't be called again. 150 // Make sure that |OnFileCanReadWithoutBlocking()| won't be called again.
142 read_watcher_.reset(); 151 read_watcher_.reset();
143 152
144 return IO_FAILED; 153 return IO_FAILED;
145 } 154 }
146 155
147 return ScheduleRead(); 156 return ScheduleRead();
148 } 157 }
149 158
150 RawChannel::IOResult RawChannelPosix::ScheduleRead() { 159 RawChannel::IOResult RawChannelPosix::ScheduleRead() {
151 DCHECK_EQ(base::MessageLoop::current(), message_loop_for_io()); 160 DCHECK_EQ(base::MessageLoop::current(), message_loop_for_io());
152 DCHECK(!pending_read_); 161 DCHECK(!pending_read_);
153 162
154 pending_read_ = true; 163 pending_read_ = true;
155 164
156 return IO_PENDING; 165 return IO_PENDING;
157 } 166 }
158 167
168 scoped_ptr<embedder::PlatformHandleVector>
169 RawChannelPosix::GetReadPlatformHandles(
170 size_t num_platform_handles,
171 const void* /*platform_handle_table*/) {
172 DCHECK_GT(num_platform_handles, 0u);
173
174 if (!read_platform_handles_ ||
175 read_platform_handles_->size() != num_platform_handles) {
176 read_platform_handles_.reset();
177 return scoped_ptr<embedder::PlatformHandleVector>();
178 }
179
180 return read_platform_handles_.Pass();
181 }
182
159 RawChannel::IOResult RawChannelPosix::WriteNoLock( 183 RawChannel::IOResult RawChannelPosix::WriteNoLock(
160 size_t* platform_handles_written, 184 size_t* platform_handles_written,
161 size_t* bytes_written) { 185 size_t* bytes_written) {
162 write_lock().AssertAcquired(); 186 write_lock().AssertAcquired();
163 187
164 DCHECK(!pending_write_); 188 DCHECK(!pending_write_);
165 189
166 if (write_buffer_no_lock()->HavePlatformHandlesToSend()) { 190 if (write_buffer_no_lock()->HavePlatformHandlesToSend()) {
167 size_t num_platform_handles; 191 size_t num_platform_handles;
168 embedder::PlatformHandle* platform_handles; 192 embedder::PlatformHandle* platform_handles;
(...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after
359 383
360 // Static factory method declared in raw_channel.h. 384 // Static factory method declared in raw_channel.h.
361 // static 385 // static
362 scoped_ptr<RawChannel> RawChannel::Create( 386 scoped_ptr<RawChannel> RawChannel::Create(
363 embedder::ScopedPlatformHandle handle) { 387 embedder::ScopedPlatformHandle handle) {
364 return scoped_ptr<RawChannel>(new RawChannelPosix(handle.Pass())); 388 return scoped_ptr<RawChannel>(new RawChannelPosix(handle.Pass()));
365 } 389 }
366 390
367 } // namespace system 391 } // namespace system
368 } // namespace mojo 392 } // namespace mojo
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698