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

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: 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
« no previous file with comments | « mojo/mojo.gyp ('k') | mojo/system/raw_channel.cc » ('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 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>
8 #include <vector> 9 #include <vector>
9 10
10 #include "base/macros.h" 11 #include "base/macros.h"
11 #include "base/memory/scoped_ptr.h" 12 #include "base/memory/scoped_ptr.h"
13 #include "base/memory/weak_ptr.h"
14 #include "base/synchronization/lock.h"
12 #include "mojo/system/constants.h" 15 #include "mojo/system/constants.h"
13 #include "mojo/system/embedder/scoped_platform_handle.h" 16 #include "mojo/system/embedder/scoped_platform_handle.h"
14 #include "mojo/system/system_impl_export.h" 17 #include "mojo/system/system_impl_export.h"
15 18
16 namespace base { 19 namespace base {
17 class MessageLoopForIO; 20 class MessageLoopForIO;
18 } 21 }
19 22
20 namespace mojo { 23 namespace mojo {
21 namespace system { 24 namespace system {
(...skipping 10 matching lines...) Expand all
32 // the aforementioned thread). 35 // the aforementioned thread).
33 // 36 //
34 // OS-specific implementation subclasses are to be instantiated using the 37 // OS-specific implementation subclasses are to be instantiated using the
35 // |Create()| static factory method. 38 // |Create()| static factory method.
36 // 39 //
37 // With the exception of |WriteMessage()|, this class is thread-unsafe (and in 40 // 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 41 // general its methods should only be used on the I/O thread, i.e., the thread
39 // on which |Init()| is called). 42 // on which |Init()| is called).
40 class MOJO_SYSTEM_IMPL_EXPORT RawChannel { 43 class MOJO_SYSTEM_IMPL_EXPORT RawChannel {
41 public: 44 public:
42 virtual ~RawChannel() {} 45 virtual ~RawChannel();
43 46
44 // The |Delegate| is only accessed on the same thread as the message loop 47 // The |Delegate| is only accessed on the same thread as the message loop
45 // (passed in on creation). 48 // (passed in on creation).
46 class MOJO_SYSTEM_IMPL_EXPORT Delegate { 49 class MOJO_SYSTEM_IMPL_EXPORT Delegate {
47 public: 50 public:
48 enum FatalError { 51 enum FatalError {
49 FATAL_ERROR_UNKNOWN = 0, 52 FATAL_ERROR_UNKNOWN = 0,
50 FATAL_ERROR_FAILED_READ, 53 FATAL_ERROR_FAILED_READ,
51 FATAL_ERROR_FAILED_WRITE 54 FATAL_ERROR_FAILED_WRITE
52 }; 55 };
(...skipping 18 matching lines...) Expand all
71 // Static factory method. |handle| should be a handle to a 74 // Static factory method. |handle| should be a handle to a
72 // (platform-appropriate) bidirectional communication channel (e.g., a socket 75 // (platform-appropriate) bidirectional communication channel (e.g., a socket
73 // on POSIX, a named pipe on Windows). Does *not* take ownership of |delegate| 76 // 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. 77 // and |message_loop_for_io|, which must remain alive while this object does.
75 static RawChannel* Create(embedder::ScopedPlatformHandle handle, 78 static RawChannel* Create(embedder::ScopedPlatformHandle handle,
76 Delegate* delegate, 79 Delegate* delegate,
77 base::MessageLoopForIO* message_loop_for_io); 80 base::MessageLoopForIO* message_loop_for_io);
78 81
79 // This must be called (on an I/O thread) before this object is used. Returns 82 // 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. 83 // true on success. On failure, |Shutdown()| should *not* be called.
81 virtual bool Init() = 0; 84 bool Init();
82 85
83 // This must be called (on the I/O thread) before this object is destroyed. 86 // This must be called (on the I/O thread) before this object is destroyed.
84 virtual void Shutdown() = 0; 87 void Shutdown();
85 88
86 // This is thread-safe. It takes ownership of |message| (always, even on 89 // This is thread-safe. It takes ownership of |message| (always, even on
87 // failure). Returns true on success. 90 // failure). Returns true on success.
88 virtual bool WriteMessage(scoped_ptr<MessageInTransit> message) = 0; 91 bool WriteMessage(scoped_ptr<MessageInTransit> message);
89 92
90 protected: 93 protected:
91 RawChannel(Delegate* delegate, base::MessageLoopForIO* message_loop_for_io) 94 // Return values of |Read()| and |WriteNoLock()|.
92 : delegate_(delegate), message_loop_for_io_(message_loop_for_io) {} 95 enum IOResult {
96 IO_SUCCEEDED,
97 IO_FAILED,
98 IO_PENDING
99 };
93 100
94 Delegate* delegate() { return delegate_; } 101 // The buffer passed to |Read()| or |WriteNoLock()| must remain valid while
102 // the operation is pending. On some platforms (e.g., Windows), however, it
103 // may be costly if RawChannel shutdown or destruction has to wait for I/O
104 // completion.
105 // In order to solve the problem, when RawChannel is shutdown, an
106 // IOBufferPreserver object is created to manage the lifespan of the I/O
107 // buffers currently being used. As long as it stays alive, the buffers remain
108 // valid. RawChannel subclasses receive this object via |OnShutdownNoLock()|
109 // and determine when to destroy it.
110 class IOBufferPreserver {
viettrungluu 2014/02/25 01:30:06 I think I'd move this to the Windows-specific clas
yzshen1 2014/02/25 05:16:34 (Maybe I haven't fully understood your idea.) IMO,
viettrungluu 2014/02/25 16:37:07 I like the encapsulation too, but I have to weight
yzshen1 2014/02/26 21:47:10 Done.
111 public:
112 IOBufferPreserver(scoped_ptr<std::vector<char> > read_buffer,
113 scoped_ptr<MessageInTransit> write_buffer);
114
115 ~IOBufferPreserver();
116
117 private:
118 scoped_ptr<std::vector<char> > read_buffer_;
119 scoped_ptr<MessageInTransit> write_buffer_;
120 DISALLOW_COPY_AND_ASSIGN(IOBufferPreserver);
121 };
122
123 RawChannel(Delegate* delegate, base::MessageLoopForIO* message_loop_for_io);
124
95 base::MessageLoopForIO* message_loop_for_io() { return message_loop_for_io_; } 125 base::MessageLoopForIO* message_loop_for_io() { return message_loop_for_io_; }
126 base::Lock& write_lock() { return write_lock_; }
127
128 // If |schedule_for_later| is true, this method won't succeed synchronously,
129 // i.e., it is guaranteed to only return IO_FAILED or IO_PENDING. |buffer|
130 // must stay valid until read completion. |bytes_read| is untouched if the
131 // method returns values other than IO_SUCCEEDED.
132 // If the method returns IO_PENDING, |OnReadCompleted()| will be called on the
133 // I/O thread to report the result, unless |Shutdown()| happens.
134 // A second read shouldn't be started if there is a pending read.
135 // Must be called on the I/O thread WITHOUT |write_lock_| held.
136 virtual IOResult Read(bool schedule_for_later,
viettrungluu 2014/02/25 01:30:06 I think it may be better to split this apart into
yzshen1 2014/02/25 05:16:34 After the split, Read() can still return IO_PENDIN
viettrungluu 2014/02/25 16:37:07 Yes, that's fine. (The main reason for having "Sch
yzshen1 2014/02/26 21:47:10 Done.
137 char* buffer,
138 size_t bytes_to_read,
139 size_t* bytes_read) = 0;
140
141 // If |schedule_for_later| is true, this method won't succeed synchronously,
142 // i.e., it is guaranteed to only returns IO_FAILED or IO_PENDING. |buffer|
143 // must stay valid until write completion. |bytes_written| is untouched if the
144 // method returns values other than IO_SUCCEEDED.
145 // If the method returns IO_PENDING, |OnWriteCompleted()| will be called on
146 // the I/O thread to report the result, unless |Shutdown()| happens.
147 // A second write shouldn't be started if there is a pending write.
148 // Must be called under |write_lock_|.
149 virtual IOResult WriteNoLock(bool schedule_for_later,
viettrungluu 2014/02/25 01:30:06 (ditto)
yzshen1 2014/02/26 21:47:10 Done.
150 const char* buffer,
151 size_t bytes_to_write,
152 size_t* bytes_written) = 0;
153
154 // Must be called on the I/O thread WITHOUT |write_lock_| held.
155 virtual bool OnInit() = 0;
156 // Must be called on the I/O thread under |write_lock_|.
157 virtual void OnShutdownNoLock(
158 scoped_ptr<IOBufferPreserver> buffer_preserver) = 0;
159
160 // Must be called on the I/O thread WITHOUT |write_lock_| held.
161 void OnReadCompleted(bool result, size_t bytes_read);
162 // Must be called on the I/O thread WITHOUT |write_lock_| held.
163 void OnWriteCompleted(bool result, size_t bytes_written);
96 164
97 private: 165 private:
166 // Calls |delegate_->OnFatalError(fatal_error)|. Must be called on the I/O
167 // thread WITHOUT |write_lock_| held.
168 void CallOnFatalError(Delegate::FatalError fatal_error);
169
170 // If |result| is true, updates the write buffer and schedules a write
171 // operation to run later if there are more contents to write. If |result| is
172 // false or any error occurs during the method execution, cancels pending
173 // writes and returns false.
174 // Must be called only if |write_stopped_| is false and under |write_lock_|.
175 bool OnWriteCompletedNoLock(bool result, size_t bytes_written);
176
177 // The following members are only used on the I/O thread:
98 Delegate* const delegate_; 178 Delegate* const delegate_;
179
180 bool read_stopped_;
181
182 // We store data from |Read()|s in |read_buffer_|. The start of |read_buffer_|
183 // is always aligned with a message boundary (we will copy memory to ensure
184 // this), but |read_buffer_| may be larger than the actual number of bytes we
185 // have.
186 std::vector<char> read_buffer_;
187 size_t read_buffer_num_valid_bytes_;
188
189 // The following members are used on mutiple threads:
99 base::MessageLoopForIO* const message_loop_for_io_; 190 base::MessageLoopForIO* const message_loop_for_io_;
100 191
192 base::Lock write_lock_; // Protects the following members.
193 bool write_stopped_;
194
195 // TODO(vtl): When C++11 is available, switch this to a deque of
196 // |scoped_ptr|/|unique_ptr|s.
197 std::deque<MessageInTransit*> write_message_queue_;
198 size_t write_message_offset_;
199 // This is used for posting tasks from write threads to the I/O thread. It
200 // must only be accessed under |write_lock_|. The weak pointers it produces
201 // are only used/invalidated on the I/O thread.
202 base::WeakPtrFactory<RawChannel> weak_ptr_factory_;
203
101 DISALLOW_COPY_AND_ASSIGN(RawChannel); 204 DISALLOW_COPY_AND_ASSIGN(RawChannel);
102 }; 205 };
103 206
104 } // namespace system 207 } // namespace system
105 } // namespace mojo 208 } // namespace mojo
106 209
107 #endif // MOJO_SYSTEM_RAW_CHANNEL_H_ 210 #endif // MOJO_SYSTEM_RAW_CHANNEL_H_
OLDNEW
« no previous file with comments | « mojo/mojo.gyp ('k') | mojo/system/raw_channel.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698