Chromium Code Reviews| 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 |