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 #include "mojo/system/raw_channel.h" | 5 #include "mojo/system/raw_channel.h" |
6 | 6 |
7 #include <errno.h> | 7 #include <errno.h> |
8 #include <string.h> | 8 #include <string.h> |
9 #include <unistd.h> | 9 #include <unistd.h> |
10 | 10 |
(...skipping 233 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
244 CallOnFatalError(Delegate::FATAL_ERROR_FAILED_READ); | 244 CallOnFatalError(Delegate::FATAL_ERROR_FAILED_READ); |
245 return; | 245 return; |
246 } | 246 } |
247 | 247 |
248 break; | 248 break; |
249 } | 249 } |
250 | 250 |
251 read_buffer_num_valid_bytes_ += static_cast<size_t>(bytes_read); | 251 read_buffer_num_valid_bytes_ += static_cast<size_t>(bytes_read); |
252 | 252 |
253 // Dispatch all the messages that we can. | 253 // Dispatch all the messages that we can. |
254 while (read_buffer_num_valid_bytes_ >= sizeof(MessageInTransit)) { | 254 size_t message_size; |
| 255 // Note that we rely on short-circuit evaluation here: |
| 256 // - |read_buffer_start| may be an invalid index into |read_buffer_| if |
| 257 // |read_buffer_num_valid_bytes_| is zero. |
| 258 // - |message_size| is only valid if |GetNextMessageSize()| returns true. |
| 259 // TODO(vtl): Use |message_size| more intelligently (e.g., to request the |
| 260 // next read). |
| 261 while (read_buffer_num_valid_bytes_ > 0 && |
| 262 MessageInTransit::GetNextMessageSize( |
| 263 &read_buffer_[read_buffer_start], read_buffer_num_valid_bytes_, |
| 264 &message_size) && |
| 265 read_buffer_num_valid_bytes_ >= message_size) { |
255 const MessageInTransit* message = | 266 const MessageInTransit* message = |
256 reinterpret_cast<const MessageInTransit*>( | 267 MessageInTransit::CreateReadOnlyFromBuffer( |
257 &read_buffer_[read_buffer_start]); | 268 &read_buffer_[read_buffer_start]); |
258 DCHECK_EQ(reinterpret_cast<size_t>(message) % | 269 DCHECK_EQ(message->main_buffer_size(), message_size); |
259 MessageInTransit::kMessageAlignment, 0u); | |
260 // If we have the header, not the whole message.... | |
261 if (read_buffer_num_valid_bytes_ < message->main_buffer_size()) | |
262 break; | |
263 | 270 |
264 // Dispatch the message. | 271 // Dispatch the message. |
265 delegate()->OnReadMessage(*message); | 272 delegate()->OnReadMessage(*message); |
266 if (!read_watcher_.get()) { | 273 if (!read_watcher_.get()) { |
267 // |Shutdown()| was called in |OnReadMessage()|. | 274 // |Shutdown()| was called in |OnReadMessage()|. |
268 // TODO(vtl): Add test for this case. | 275 // TODO(vtl): Add test for this case. |
269 return; | 276 return; |
270 } | 277 } |
271 did_dispatch_message = true; | 278 did_dispatch_message = true; |
272 | 279 |
273 // Update our state. | 280 // Update our state. |
274 read_buffer_start += message->main_buffer_size(); | 281 read_buffer_start += message_size; |
275 read_buffer_num_valid_bytes_ -= message->main_buffer_size(); | 282 read_buffer_num_valid_bytes_ -= message_size; |
276 } | 283 } |
277 | 284 |
278 // If we dispatched any messages, stop reading for now (and let the message | 285 // If we dispatched any messages, stop reading for now (and let the message |
279 // loop do its thing for another round). | 286 // loop do its thing for another round). |
280 // TODO(vtl): Is this the behavior we want? (Alternatives: i. Dispatch only | 287 // TODO(vtl): Is this the behavior we want? (Alternatives: i. Dispatch only |
281 // a single message. Risks: slower, more complex if we want to avoid lots of | 288 // a single message. Risks: slower, more complex if we want to avoid lots of |
282 // copying. ii. Keep reading until there's no more data and dispatch all the | 289 // copying. ii. Keep reading until there's no more data and dispatch all the |
283 // messages we can. Risks: starvation of other users of the message loop.) | 290 // messages we can. Risks: starvation of other users of the message loop.) |
284 if (did_dispatch_message) | 291 if (did_dispatch_message) |
285 break; | 292 break; |
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
406 // Static factory method declared in raw_channel.h. | 413 // Static factory method declared in raw_channel.h. |
407 // static | 414 // static |
408 RawChannel* RawChannel::Create(embedder::ScopedPlatformHandle handle, | 415 RawChannel* RawChannel::Create(embedder::ScopedPlatformHandle handle, |
409 Delegate* delegate, | 416 Delegate* delegate, |
410 base::MessageLoop* message_loop) { | 417 base::MessageLoop* message_loop) { |
411 return new RawChannelPosix(handle.Pass(), delegate, message_loop); | 418 return new RawChannelPosix(handle.Pass(), delegate, message_loop); |
412 } | 419 } |
413 | 420 |
414 } // namespace system | 421 } // namespace system |
415 } // namespace mojo | 422 } // namespace mojo |
OLD | NEW |