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/edk/system/raw_channel.h" | 5 #include "mojo/edk/system/raw_channel.h" |
6 | 6 |
7 #include <errno.h> | 7 #include <errno.h> |
8 #include <sys/uio.h> | 8 #include <sys/uio.h> |
9 #include <unistd.h> | 9 #include <unistd.h> |
10 | 10 |
(...skipping 338 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
349 DCHECK_EQ(base::MessageLoop::current(), message_loop_for_io()); | 349 DCHECK_EQ(base::MessageLoop::current(), message_loop_for_io()); |
350 | 350 |
351 if (!pending_read_) { | 351 if (!pending_read_) { |
352 NOTREACHED(); | 352 NOTREACHED(); |
353 return; | 353 return; |
354 } | 354 } |
355 | 355 |
356 pending_read_ = false; | 356 pending_read_ = false; |
357 size_t bytes_read = 0; | 357 size_t bytes_read = 0; |
358 IOResult io_result = Read(&bytes_read); | 358 IOResult io_result = Read(&bytes_read); |
359 if (io_result != IO_PENDING) | 359 if (io_result != IO_PENDING) { |
360 OnReadCompleted(io_result, bytes_read); | 360 OnReadCompleted(io_result, bytes_read); |
| 361 // TODO(vtl): If we weren't destroyed, we'd like to do |
| 362 // |
| 363 // DCHECK(!read_watcher_ || pending_read_); |
| 364 // |
| 365 // On failure, |read_watcher_| must have been reset; on success, we assume |
| 366 // that |OnReadCompleted()| always schedules another read. Otherwise, we |
| 367 // could end up spinning -- getting |OnFileCanReadWithoutBlocking()| again |
| 368 // and again but not doing any actual read. |
| 369 // TODO(yzshen): An alternative is to stop watching if RawChannel doesn't |
| 370 // schedule a new read. But that code won't be reached under the current |
| 371 // RawChannel implementation. |
| 372 return; // |this| may have been destroyed in |OnReadCompleted()|. |
| 373 } |
361 | 374 |
362 // On failure, |read_watcher_| must have been reset; on success, | 375 DCHECK(pending_read_); |
363 // we assume that |OnReadCompleted()| always schedules another read. | |
364 // Otherwise, we could end up spinning -- getting | |
365 // |OnFileCanReadWithoutBlocking()| again and again but not doing any actual | |
366 // read. | |
367 // TODO(yzshen): An alternative is to stop watching if RawChannel doesn't | |
368 // schedule a new read. But that code won't be reached under the current | |
369 // RawChannel implementation. | |
370 DCHECK(!read_watcher_ || pending_read_); | |
371 } | 376 } |
372 | 377 |
373 void RawChannelPosix::OnFileCanWriteWithoutBlocking(int fd) { | 378 void RawChannelPosix::OnFileCanWriteWithoutBlocking(int fd) { |
374 DCHECK_EQ(fd, fd_.get().fd); | 379 DCHECK_EQ(fd, fd_.get().fd); |
375 DCHECK_EQ(base::MessageLoop::current(), message_loop_for_io()); | 380 DCHECK_EQ(base::MessageLoop::current(), message_loop_for_io()); |
376 | 381 |
377 IOResult io_result; | 382 IOResult io_result; |
378 size_t platform_handles_written = 0; | 383 size_t platform_handles_written = 0; |
379 size_t bytes_written = 0; | 384 size_t bytes_written = 0; |
380 { | 385 { |
381 base::AutoLock locker(write_lock()); | 386 base::AutoLock locker(write_lock()); |
382 | 387 |
383 DCHECK(pending_write_); | 388 DCHECK(pending_write_); |
384 | 389 |
385 pending_write_ = false; | 390 pending_write_ = false; |
386 io_result = WriteNoLock(&platform_handles_written, &bytes_written); | 391 io_result = WriteNoLock(&platform_handles_written, &bytes_written); |
387 } | 392 } |
388 | 393 |
389 if (io_result != IO_PENDING) | 394 if (io_result != IO_PENDING) { |
390 OnWriteCompleted(io_result, platform_handles_written, bytes_written); | 395 OnWriteCompleted(io_result, platform_handles_written, bytes_written); |
| 396 return; // |this| may have been destroyed in |OnWriteCompleted()|. |
| 397 } |
391 } | 398 } |
392 | 399 |
393 RawChannel::IOResult RawChannelPosix::ReadImpl(size_t* bytes_read) { | 400 RawChannel::IOResult RawChannelPosix::ReadImpl(size_t* bytes_read) { |
394 char* buffer = nullptr; | 401 char* buffer = nullptr; |
395 size_t bytes_to_read = 0; | 402 size_t bytes_to_read = 0; |
396 read_buffer()->GetBuffer(&buffer, &bytes_to_read); | 403 read_buffer()->GetBuffer(&buffer, &bytes_to_read); |
397 | 404 |
398 size_t old_num_platform_handles = read_platform_handles_.size(); | 405 size_t old_num_platform_handles = read_platform_handles_.size(); |
399 ssize_t read_result = embedder::PlatformChannelRecvmsg( | 406 ssize_t read_result = embedder::PlatformChannelRecvmsg( |
400 fd_.get(), buffer, bytes_to_read, &read_platform_handles_); | 407 fd_.get(), buffer, bytes_to_read, &read_platform_handles_); |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
444 if (!message_loop_for_io()->WatchFileDescriptor( | 451 if (!message_loop_for_io()->WatchFileDescriptor( |
445 fd_.get().fd, false, base::MessageLoopForIO::WATCH_WRITE, | 452 fd_.get().fd, false, base::MessageLoopForIO::WATCH_WRITE, |
446 write_watcher_.get(), this)) { | 453 write_watcher_.get(), this)) { |
447 { | 454 { |
448 base::AutoLock locker(write_lock()); | 455 base::AutoLock locker(write_lock()); |
449 | 456 |
450 DCHECK(pending_write_); | 457 DCHECK(pending_write_); |
451 pending_write_ = false; | 458 pending_write_ = false; |
452 } | 459 } |
453 OnWriteCompleted(IO_FAILED_UNKNOWN, 0, 0); | 460 OnWriteCompleted(IO_FAILED_UNKNOWN, 0, 0); |
| 461 return; // |this| may have been destroyed in |OnWriteCompleted()|. |
454 } | 462 } |
455 } | 463 } |
456 | 464 |
457 } // namespace | 465 } // namespace |
458 | 466 |
459 // ----------------------------------------------------------------------------- | 467 // ----------------------------------------------------------------------------- |
460 | 468 |
461 // Static factory method declared in raw_channel.h. | 469 // Static factory method declared in raw_channel.h. |
462 // static | 470 // static |
463 scoped_ptr<RawChannel> RawChannel::Create( | 471 scoped_ptr<RawChannel> RawChannel::Create( |
464 embedder::ScopedPlatformHandle handle) { | 472 embedder::ScopedPlatformHandle handle) { |
465 return make_scoped_ptr(new RawChannelPosix(handle.Pass())); | 473 return make_scoped_ptr(new RawChannelPosix(handle.Pass())); |
466 } | 474 } |
467 | 475 |
468 } // namespace system | 476 } // namespace system |
469 } // namespace mojo | 477 } // namespace mojo |
OLD | NEW |