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

Side by Side Diff: mojo/system/raw_channel.h

Issue 169723004: RawChannel refactoring (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: support multi-segment write Created 6 years, 10 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
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 #ifndef MOJO_SYSTEM_RAW_CHANNEL_H_ 5 #ifndef MOJO_SYSTEM_RAW_CHANNEL_H_
6 #define MOJO_SYSTEM_RAW_CHANNEL_H_ 6 #define MOJO_SYSTEM_RAW_CHANNEL_H_
7 7
8 #include <deque>
9 #include <utility>
8 #include <vector> 10 #include <vector>
9 11
10 #include "base/macros.h" 12 #include "base/macros.h"
11 #include "base/memory/scoped_ptr.h" 13 #include "base/memory/scoped_ptr.h"
14 #include "base/memory/weak_ptr.h"
15 #include "base/synchronization/lock.h"
12 #include "mojo/system/constants.h" 16 #include "mojo/system/constants.h"
13 #include "mojo/system/embedder/scoped_platform_handle.h" 17 #include "mojo/system/embedder/scoped_platform_handle.h"
14 #include "mojo/system/system_impl_export.h" 18 #include "mojo/system/system_impl_export.h"
15 19
16 namespace base { 20 namespace base {
17 class MessageLoopForIO; 21 class MessageLoopForIO;
18 } 22 }
19 23
20 namespace mojo { 24 namespace mojo {
21 namespace system { 25 namespace system {
(...skipping 10 matching lines...) Expand all
32 // the aforementioned thread). 36 // the aforementioned thread).
33 // 37 //
34 // OS-specific implementation subclasses are to be instantiated using the 38 // OS-specific implementation subclasses are to be instantiated using the
35 // |Create()| static factory method. 39 // |Create()| static factory method.
36 // 40 //
37 // With the exception of |WriteMessage()|, this class is thread-unsafe (and in 41 // With the exception of |WriteMessage()|, this class is thread-unsafe (and in
38 // general its methods should only be used on the I/O thread, i.e., the thread 42 // general its methods should only be used on the I/O thread, i.e., the thread
39 // on which |Init()| is called). 43 // on which |Init()| is called).
40 class MOJO_SYSTEM_IMPL_EXPORT RawChannel { 44 class MOJO_SYSTEM_IMPL_EXPORT RawChannel {
41 public: 45 public:
42 virtual ~RawChannel() {} 46 virtual ~RawChannel();
43 47
44 // The |Delegate| is only accessed on the same thread as the message loop 48 // The |Delegate| is only accessed on the same thread as the message loop
45 // (passed in on creation). 49 // (passed in on creation).
46 class MOJO_SYSTEM_IMPL_EXPORT Delegate { 50 class MOJO_SYSTEM_IMPL_EXPORT Delegate {
47 public: 51 public:
48 enum FatalError { 52 enum FatalError {
49 FATAL_ERROR_UNKNOWN = 0, 53 FATAL_ERROR_UNKNOWN = 0,
50 FATAL_ERROR_FAILED_READ, 54 FATAL_ERROR_FAILED_READ,
51 FATAL_ERROR_FAILED_WRITE 55 FATAL_ERROR_FAILED_WRITE
52 }; 56 };
(...skipping 18 matching lines...) Expand all
71 // Static factory method. |handle| should be a handle to a 75 // Static factory method. |handle| should be a handle to a
72 // (platform-appropriate) bidirectional communication channel (e.g., a socket 76 // (platform-appropriate) bidirectional communication channel (e.g., a socket
73 // on POSIX, a named pipe on Windows). Does *not* take ownership of |delegate| 77 // on POSIX, a named pipe on Windows). Does *not* take ownership of |delegate|
74 // and |message_loop_for_io|, which must remain alive while this object does. 78 // and |message_loop_for_io|, which must remain alive while this object does.
75 static RawChannel* Create(embedder::ScopedPlatformHandle handle, 79 static RawChannel* Create(embedder::ScopedPlatformHandle handle,
76 Delegate* delegate, 80 Delegate* delegate,
77 base::MessageLoopForIO* message_loop_for_io); 81 base::MessageLoopForIO* message_loop_for_io);
78 82
79 // This must be called (on an I/O thread) before this object is used. Returns 83 // This must be called (on an I/O thread) before this object is used. Returns
80 // true on success. On failure, |Shutdown()| should *not* be called. 84 // true on success. On failure, |Shutdown()| should *not* be called.
81 virtual bool Init() = 0; 85 bool Init();
82 86
83 // This must be called (on the I/O thread) before this object is destroyed. 87 // This must be called (on the I/O thread) before this object is destroyed.
84 virtual void Shutdown() = 0; 88 void Shutdown();
85 89
86 // This is thread-safe. It takes ownership of |message| (always, even on 90 // This is thread-safe. It takes ownership of |message| (always, even on
87 // failure). Returns true on success. 91 // failure). Returns true on success.
88 virtual bool WriteMessage(scoped_ptr<MessageInTransit> message) = 0; 92 bool WriteMessage(scoped_ptr<MessageInTransit> message);
89 93
90 protected: 94 protected:
91 RawChannel(Delegate* delegate, base::MessageLoopForIO* message_loop_for_io) 95 // Return values of |[Schedule]Read()| and |[Schedule]WriteNoLock()|.
92 : delegate_(delegate), message_loop_for_io_(message_loop_for_io) {} 96 enum IOResult {
97 IO_SUCCEEDED,
98 IO_FAILED,
99 IO_PENDING
100 };
93 101
94 Delegate* delegate() { return delegate_; } 102 struct ReadBuffer {
103 public:
104 ReadBuffer();
105 ~ReadBuffer();
106
107 void GetBuffer(char** buffer, size_t* bytes_to_read);
108
109 private:
110 friend class RawChannel;
111
112 // We store data from |[Schedule]Read()|s in |buffer_|. The start of
113 // |buffer_| is always aligned with a message boundary (we will copy memory
114 // to ensure this), but |buffer_| may be larger than the actual number of
115 // bytes we have.
116 std::vector<char> buffer_;
117 size_t num_valid_bytes_;
118
119 DISALLOW_COPY_AND_ASSIGN(ReadBuffer);
120 };
121
122 struct WriteBuffer {
123 public:
124 typedef std::vector<std::pair<const char*, size_t> > BufferVector;
viettrungluu 2014/02/27 05:22:15 I'd generally prefer a struct Buffer { const vo
yzshen1 2014/02/27 06:56:18 Done.
125
126 WriteBuffer();
127 ~WriteBuffer();
128
129 void GetBuffers(BufferVector* buffers) const;
130 // Returns the total size of all buffers returned by |GetBuffers()|.
131 size_t GetTotalBytesToWrite() const;
132
133 private:
134 friend class RawChannel;
135
136 // TODO(vtl): When C++11 is available, switch this to a deque of
137 // |scoped_ptr|/|unique_ptr|s.
138 std::deque<MessageInTransit*> message_queue_;
139 // The first message may have been partially sent. |offset_| indicates the
140 // position in the first message where to start the next write.
141 size_t offset_;
142
143 DISALLOW_COPY_AND_ASSIGN(WriteBuffer);
144 };
145
146 RawChannel(Delegate* delegate, base::MessageLoopForIO* message_loop_for_io);
147
95 base::MessageLoopForIO* message_loop_for_io() { return message_loop_for_io_; } 148 base::MessageLoopForIO* message_loop_for_io() { return message_loop_for_io_; }
149 base::Lock& write_lock() { return write_lock_; }
150
151 // Only accessed on the I/O thread.
152 ReadBuffer* read_buffer();
153
154 // Only accessed under |write_lock_|.
155 WriteBuffer* write_buffer_no_lock();
156
157 // Reads into |read_buffer()|.
158 // This class guarantees that:
159 // - the area indicated by |GetBuffer()| will stay valid until read completion
160 // (but please also see the comments for |OnShutdownNoLock()|);
161 // - a second read is not started if there is a pending read;
162 // - the method is called on the I/O thread WITHOUT |write_lock_| held.
163 //
164 // The implementing subclass must guarantee that:
165 // - |bytes_read| is untouched if the method returns values other than
166 // IO_SUCCEEDED;
167 // - if the method returns IO_PENDING, |OnReadCompleted()| will be called on
168 // the I/O thread to report the result, unless |Shutdown()| is called.
169 virtual IOResult Read(size_t* bytes_read) = 0;
170 // Similar to |Read()|, except that the implementing subclass must also
171 // guarantee that the method doesn't succeed synchronously, i.e., it only
172 // returns IO_FAILED or IO_PENDING.
173 virtual IOResult ScheduleRead() = 0;
174
175 // Writes contents in |write_buffer_no_lock()|.
176 // This class guarantees that:
177 // - the area indicated by |GetBuffers()| will stay valid until write
178 // completion (but please also see the comments for |OnShutdownNoLock()|);
179 // - a second write is not started if there is a pending write;
180 // - the method is called under |write_lock_|.
181 //
182 // The implementing subclass must guarantee that:
183 // - |bytes_written| is untouched if the method returns values other than
184 // IO_SUCCEEDED;
185 // - if the method returns IO_PENDING, |OnWriteCompleted()| will be called on
186 // the I/O thread to report the result, unless |Shutdown()| is called.
187 virtual IOResult WriteNoLock(size_t* bytes_written) = 0;
188 // Similar to |WriteNoLock()|, except that the implementing subclass must also
189 // guarantee that the method doesn't succeed synchronously, i.e., it only
190 // returns IO_FAILED or IO_PENDING.
191 virtual IOResult ScheduleWriteNoLock() = 0;
192
193 // Must be called on the I/O thread WITHOUT |write_lock_| held.
194 virtual bool OnInit() = 0;
195 // On shutdown, passes the ownership of the buffers to subclasses, who may
196 // want to preserve them if there are pending read/write.
197 // Must be called on the I/O thread under |write_lock_|.
198 virtual void OnShutdownNoLock(
199 scoped_ptr<ReadBuffer> read_buffer,
200 scoped_ptr<WriteBuffer> write_buffer) = 0;
201
202 // Must be called on the I/O thread WITHOUT |write_lock_| held.
203 void OnReadCompleted(bool result, size_t bytes_read);
204 // Must be called on the I/O thread WITHOUT |write_lock_| held.
205 void OnWriteCompleted(bool result, size_t bytes_written);
96 206
97 private: 207 private:
208 // Calls |delegate_->OnFatalError(fatal_error)|. Must be called on the I/O
209 // thread WITHOUT |write_lock_| held.
210 void CallOnFatalError(Delegate::FatalError fatal_error);
211
212 // If |result| is true, updates the write buffer and schedules a write
213 // operation to run later if there are more contents to write. If |result| is
214 // false or any error occurs during the method execution, cancels pending
215 // writes and returns false.
216 // Must be called only if |write_stopped_| is false and under |write_lock_|.
217 bool OnWriteCompletedNoLock(bool result, size_t bytes_written);
218
98 Delegate* const delegate_; 219 Delegate* const delegate_;
99 base::MessageLoopForIO* const message_loop_for_io_; 220 base::MessageLoopForIO* const message_loop_for_io_;
100 221
222 // Only used on the I/O thread:
223 bool read_stopped_;
224 scoped_ptr<ReadBuffer> read_buffer_;
225
226 base::Lock write_lock_; // Protects the following members.
227 bool write_stopped_;
228 scoped_ptr<WriteBuffer> write_buffer_;
229
230 // This is used for posting tasks from write threads to the I/O thread. It
231 // must only be accessed under |write_lock_|. The weak pointers it produces
232 // are only used/invalidated on the I/O thread.
233 base::WeakPtrFactory<RawChannel> weak_ptr_factory_;
234
101 DISALLOW_COPY_AND_ASSIGN(RawChannel); 235 DISALLOW_COPY_AND_ASSIGN(RawChannel);
102 }; 236 };
103 237
104 } // namespace system 238 } // namespace system
105 } // namespace mojo 239 } // namespace mojo
106 240
107 #endif // MOJO_SYSTEM_RAW_CHANNEL_H_ 241 #endif // MOJO_SYSTEM_RAW_CHANNEL_H_
OLDNEW
« no previous file with comments | « mojo/mojo.gyp ('k') | mojo/system/raw_channel.cc » ('j') | mojo/system/raw_channel_posix.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698