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 // TODO(vtl): I currently potentially overflow in doing index calculations. | 5 // TODO(vtl): I currently potentially overflow in doing index calculations. |
6 // E.g., |start_index_| and |current_num_bytes_| fit into a |uint32_t|, but | 6 // E.g., |start_index_| and |current_num_bytes_| fit into a |uint32_t|, but |
7 // their sum may not. This is bad and poses a security risk. (We're currently | 7 // their sum may not. This is bad and poses a security risk. (We're currently |
8 // saved by the limit on capacity -- the maximum size of the buffer, checked in | 8 // saved by the limit on capacity -- the maximum size of the buffer, checked in |
9 // |DataPipe::ValidateOptions()|, is currently sufficiently small. | 9 // |DataPipe::ValidateOptions()|, is currently sufficiently small. |
10 | 10 |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
94 num_bytes_to_write - num_bytes_to_write_first); | 94 num_bytes_to_write - num_bytes_to_write_first); |
95 } | 95 } |
96 | 96 |
97 current_num_bytes_ += num_bytes_to_write; | 97 current_num_bytes_ += num_bytes_to_write; |
98 DCHECK_LE(current_num_bytes_, capacity_num_bytes()); | 98 DCHECK_LE(current_num_bytes_, capacity_num_bytes()); |
99 *num_bytes = static_cast<uint32_t>(num_bytes_to_write); | 99 *num_bytes = static_cast<uint32_t>(num_bytes_to_write); |
100 return MOJO_RESULT_OK; | 100 return MOJO_RESULT_OK; |
101 } | 101 } |
102 | 102 |
103 MojoResult LocalDataPipe::ProducerBeginWriteDataImplNoLock( | 103 MojoResult LocalDataPipe::ProducerBeginWriteDataImplNoLock( |
104 void** buffer, | 104 UserPointer<void*> buffer, |
105 uint32_t* buffer_num_bytes, | 105 UserPointer<uint32_t> buffer_num_bytes, |
106 bool all_or_none) { | 106 uint32_t min_num_bytes_to_write) { |
107 DCHECK(consumer_open_no_lock()); | 107 DCHECK(consumer_open_no_lock()); |
108 | 108 |
109 // The index we need to start writing at. | 109 // The index we need to start writing at. |
110 size_t write_index = | 110 size_t write_index = |
111 (start_index_ + current_num_bytes_) % capacity_num_bytes(); | 111 (start_index_ + current_num_bytes_) % capacity_num_bytes(); |
112 | 112 |
113 size_t max_num_bytes_to_write = GetMaxNumBytesToWriteNoLock(); | 113 size_t max_num_bytes_to_write = GetMaxNumBytesToWriteNoLock(); |
114 if (all_or_none && *buffer_num_bytes > max_num_bytes_to_write) { | 114 if (min_num_bytes_to_write > max_num_bytes_to_write) { |
115 // In "may discard" mode, we can always write from the write index to the | 115 // In "may discard" mode, we can always write from the write index to the |
116 // end of the buffer. | 116 // end of the buffer. |
117 if (may_discard() && | 117 if (may_discard() && |
118 *buffer_num_bytes <= capacity_num_bytes() - write_index) { | 118 min_num_bytes_to_write <= capacity_num_bytes() - write_index) { |
119 // To do so, we need to discard an appropriate amount of data. | 119 // To do so, we need to discard an appropriate amount of data. |
120 // We should only reach here if the start index is after the write index! | 120 // We should only reach here if the start index is after the write index! |
121 DCHECK_GE(start_index_, write_index); | 121 DCHECK_GE(start_index_, write_index); |
122 DCHECK_GT(*buffer_num_bytes - max_num_bytes_to_write, 0u); | 122 DCHECK_GT(min_num_bytes_to_write - max_num_bytes_to_write, 0u); |
123 MarkDataAsConsumedNoLock(*buffer_num_bytes - max_num_bytes_to_write); | 123 MarkDataAsConsumedNoLock(min_num_bytes_to_write - max_num_bytes_to_write); |
124 max_num_bytes_to_write = *buffer_num_bytes; | 124 max_num_bytes_to_write = min_num_bytes_to_write; |
125 } else { | 125 } else { |
126 // Don't return "should wait" since you can't wait for a specified amount | 126 // Don't return "should wait" since you can't wait for a specified amount |
127 // of data. | 127 // of data. |
128 return MOJO_RESULT_OUT_OF_RANGE; | 128 return MOJO_RESULT_OUT_OF_RANGE; |
129 } | 129 } |
130 } | 130 } |
131 | 131 |
132 // Don't go into a two-phase write if there's no room. | 132 // Don't go into a two-phase write if there's no room. |
133 if (max_num_bytes_to_write == 0) | 133 if (max_num_bytes_to_write == 0) |
134 return MOJO_RESULT_SHOULD_WAIT; | 134 return MOJO_RESULT_SHOULD_WAIT; |
135 | 135 |
136 EnsureBufferNoLock(); | 136 EnsureBufferNoLock(); |
137 *buffer = buffer_.get() + write_index; | 137 buffer.Put(buffer_.get() + write_index); |
138 *buffer_num_bytes = static_cast<uint32_t>(max_num_bytes_to_write); | 138 buffer_num_bytes.Put(static_cast<uint32_t>(max_num_bytes_to_write)); |
139 set_producer_two_phase_max_num_bytes_written_no_lock( | 139 set_producer_two_phase_max_num_bytes_written_no_lock( |
140 static_cast<uint32_t>(max_num_bytes_to_write)); | 140 static_cast<uint32_t>(max_num_bytes_to_write)); |
141 return MOJO_RESULT_OK; | 141 return MOJO_RESULT_OK; |
142 } | 142 } |
143 | 143 |
144 MojoResult LocalDataPipe::ProducerEndWriteDataImplNoLock( | 144 MojoResult LocalDataPipe::ProducerEndWriteDataImplNoLock( |
145 uint32_t num_bytes_written) { | 145 uint32_t num_bytes_written) { |
146 DCHECK_LE(num_bytes_written, | 146 DCHECK_LE(num_bytes_written, |
147 producer_two_phase_max_num_bytes_written_no_lock()); | 147 producer_two_phase_max_num_bytes_written_no_lock()); |
148 current_num_bytes_ += num_bytes_written; | 148 current_num_bytes_ += num_bytes_written; |
(...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
323 | 323 |
324 void LocalDataPipe::MarkDataAsConsumedNoLock(size_t num_bytes) { | 324 void LocalDataPipe::MarkDataAsConsumedNoLock(size_t num_bytes) { |
325 DCHECK_LE(num_bytes, current_num_bytes_); | 325 DCHECK_LE(num_bytes, current_num_bytes_); |
326 start_index_ += num_bytes; | 326 start_index_ += num_bytes; |
327 start_index_ %= capacity_num_bytes(); | 327 start_index_ %= capacity_num_bytes(); |
328 current_num_bytes_ -= num_bytes; | 328 current_num_bytes_ -= num_bytes; |
329 } | 329 } |
330 | 330 |
331 } // namespace system | 331 } // namespace system |
332 } // namespace mojo | 332 } // namespace mojo |
OLD | NEW |