| 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 |