OLD | NEW |
---|---|
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" | |
12 #include "mojo/system/constants.h" | 14 #include "mojo/system/constants.h" |
13 #include "mojo/system/embedder/scoped_platform_handle.h" | 15 #include "mojo/system/embedder/scoped_platform_handle.h" |
14 #include "mojo/system/system_impl_export.h" | 16 #include "mojo/system/system_impl_export.h" |
15 | 17 |
16 namespace base { | 18 namespace base { |
17 class MessageLoopForIO; | 19 class MessageLoopForIO; |
18 } | 20 } |
19 | 21 |
20 namespace mojo { | 22 namespace mojo { |
21 namespace system { | 23 namespace system { |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
81 virtual bool Init() = 0; | 83 virtual bool Init() = 0; |
82 | 84 |
83 // This must be called (on the I/O thread) before this object is destroyed. | 85 // This must be called (on the I/O thread) before this object is destroyed. |
84 virtual void Shutdown() = 0; | 86 virtual void Shutdown() = 0; |
85 | 87 |
86 // This is thread-safe. It takes ownership of |message| (always, even on | 88 // This is thread-safe. It takes ownership of |message| (always, even on |
87 // failure). Returns true on success. | 89 // failure). Returns true on success. |
88 virtual bool WriteMessage(scoped_ptr<MessageInTransit> message) = 0; | 90 virtual bool WriteMessage(scoped_ptr<MessageInTransit> message) = 0; |
89 | 91 |
90 protected: | 92 protected: |
93 // Return values of |Read()| and |WriteNoLock()|. | |
94 enum IOResult { | |
95 IO_SUCCEEDED, | |
96 IO_FAILED, | |
97 IO_PENDING | |
98 }; | |
99 | |
100 // The buffer passed to |Read()| or |WriteNoLock()| must remain valid while | |
101 // the operation is pending. On some platforms (e.g., Windows), however, it | |
102 // may be costly if RawChannel shutdown or destruction has to wait for I/O | |
103 // completion. | |
104 // In order to solve the problem, when RawChannel is shutdown, an | |
105 // IOBufferPreserver object is created to manage the lifespan of the I/O | |
106 // buffers currently being used. As long as it stays alive, the buffers remain | |
107 // valid. RawChannel subclasses receive this object via |OnShutdownNoLock()| | |
108 // and determine when to destroy it. | |
109 class IOBufferPreserver { | |
yzshen1
2014/02/22 23:49:06
I created this opaque object so that subclasses ca
| |
110 public: | |
111 IOBufferPreserver(scoped_ptr<vector<char> > read_buffer, | |
112 scoped_ptr<MessageInTransit> write_buffer); | |
113 private: | |
114 scoped_ptr<MessageInTransit> write_buffer; | |
115 scoped_ptr<vector<char> > read_buffer; | |
116 DISALLOW_COPY_AND_ASSIGN(IOBufferPreserver); | |
117 }; | |
118 | |
91 RawChannel(Delegate* delegate, base::MessageLoopForIO* message_loop_for_io) | 119 RawChannel(Delegate* delegate, base::MessageLoopForIO* message_loop_for_io) |
92 : delegate_(delegate), message_loop_for_io_(message_loop_for_io) {} | 120 : delegate_(delegate), message_loop_for_io_(message_loop_for_io) {} |
93 | 121 |
94 Delegate* delegate() { return delegate_; } | |
95 base::MessageLoopForIO* message_loop_for_io() { return message_loop_for_io_; } | 122 base::MessageLoopForIO* message_loop_for_io() { return message_loop_for_io_; } |
123 base::Lock& write_lock() { return write_lock_; } | |
124 | |
125 // If |schedule_for_later| is true, this method only returns IO_FAILED or | |
126 // IO_PENDING. |buffer| must stay valid until read completion. | |
127 // If the method returns IO_PENDING, |OnReadCompleted()| will be called on the | |
128 // I/O thread to report the result, unless |Shutdown()| happens. | |
129 // A second read shouldn't be started if there is a pending read. | |
130 // Must be called on the I/O thread WITHOUT |write_lock_| held. | |
131 virtual IOResult Read(bool schedule_for_later, | |
132 char* buffer, | |
133 size_t bytes_to_read, | |
134 size_t* byte_read) = 0; | |
135 | |
136 // If |schedule_for_later| is true, this method only returns IO_FAILED or | |
137 // IO_PENDING. |buffer| must stay valid until write completion. | |
138 // If the method returns IO_PENDING, |OnWriteCompleted()| will be called on | |
139 // the I/O thread to report the result, unless |Shutdown()| happens. | |
140 // A second write shouldn't be started if there is a pending write. | |
141 // Must be called under |write_lock_|. | |
142 virtual IOResult WriteNoLock(bool delayed, | |
143 const char* buffer, | |
144 size_t bytes_to_write, | |
145 size_t* bytes_written) = 0; | |
146 // Must be called on the I/O thread WITHOUT |write_lock_| held. | |
147 virtual bool OnInit() = 0; | |
148 // Must be called on the I/O thread under |write_lock_|. | |
149 virtual void OnShutdownNoLock( | |
150 scoped_ptr<IOBufferPreserver> buffer_preserver) = 0; | |
151 | |
152 // Must be called on the I/O thread WITHOUT |write_lock_| held. | |
153 void OnReadCompleted(bool result, size_t bytes_read); | |
154 // Must be called on the I/O thread WITHOUT |write_lock_| held. | |
155 void OnWriteCompleted(bool result, size_t bytes_written); | |
96 | 156 |
97 private: | 157 private: |
158 // TODO(yzshen): Other private methods... | |
159 | |
160 // Only used on the I/O thread: ---------------------------------------------- | |
161 | |
98 Delegate* const delegate_; | 162 Delegate* const delegate_; |
163 | |
164 bool read_stopped_; | |
165 | |
166 // We store data from |Read()|s in |read_buffer_|. The start of |read_buffer_| | |
167 // is always aligned with a message boundary (we will copy memory to ensure | |
168 // this), but |read_buffer_| may be larger than the actual number of bytes we | |
169 // have. | |
170 std::vector<char> read_buffer_; | |
171 size_t read_buffer_num_valid_bytes_; | |
172 | |
173 // Used on mutiple threads: -------------------------------------------------- | |
174 | |
99 base::MessageLoopForIO* const message_loop_for_io_; | 175 base::MessageLoopForIO* const message_loop_for_io_; |
100 | 176 |
177 base::Lock write_lock_; // Protects the following members. | |
178 bool write_stopped_; | |
179 | |
180 // TODO(vtl): When C++11 is available, switch this to a deque of | |
181 // |scoped_ptr|/|unique_ptr|s. | |
182 std::deque<MessageInTransit*> write_message_queue_; | |
183 size_t write_message_offset_; | |
184 // This is used for posting tasks from write threads to the I/O thread. It | |
185 // must only be accessed under |write_lock_|. The weak pointers it produces | |
186 // are only used/invalidated on the I/O thread. | |
187 base::WeakPtrFactory<RawChannelPosix> weak_ptr_factory_; | |
188 | |
101 DISALLOW_COPY_AND_ASSIGN(RawChannel); | 189 DISALLOW_COPY_AND_ASSIGN(RawChannel); |
102 }; | 190 }; |
103 | 191 |
104 } // namespace system | 192 } // namespace system |
105 } // namespace mojo | 193 } // namespace mojo |
106 | 194 |
107 #endif // MOJO_SYSTEM_RAW_CHANNEL_H_ | 195 #endif // MOJO_SYSTEM_RAW_CHANNEL_H_ |
OLD | NEW |