| 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 <windows.h> | 7 #include <windows.h> |
| 8 | 8 |
| 9 #include "base/bind.h" | 9 #include "base/bind.h" |
| 10 #include "base/lazy_instance.h" | 10 #include "base/lazy_instance.h" |
| (...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 218 | 218 |
| 219 void RawChannelWin::RawChannelIOHandler::OnPendingReadStarted() { | 219 void RawChannelWin::RawChannelIOHandler::OnPendingReadStarted() { |
| 220 DCHECK(owner_); | 220 DCHECK(owner_); |
| 221 DCHECK_EQ(base::MessageLoop::current(), owner_->message_loop_for_io()); | 221 DCHECK_EQ(base::MessageLoop::current(), owner_->message_loop_for_io()); |
| 222 DCHECK(!pending_read_); | 222 DCHECK(!pending_read_); |
| 223 pending_read_ = true; | 223 pending_read_ = true; |
| 224 } | 224 } |
| 225 | 225 |
| 226 bool RawChannelWin::RawChannelIOHandler::pending_write_no_lock() const { | 226 bool RawChannelWin::RawChannelIOHandler::pending_write_no_lock() const { |
| 227 DCHECK(owner_); | 227 DCHECK(owner_); |
| 228 owner_->write_lock().AssertAcquired(); | 228 owner_->write_mutex().AssertHeld(); |
| 229 return pending_write_; | 229 return pending_write_; |
| 230 } | 230 } |
| 231 | 231 |
| 232 base::MessageLoopForIO::IOContext* | 232 base::MessageLoopForIO::IOContext* |
| 233 RawChannelWin::RawChannelIOHandler::write_context_no_lock() { | 233 RawChannelWin::RawChannelIOHandler::write_context_no_lock() { |
| 234 DCHECK(owner_); | 234 DCHECK(owner_); |
| 235 owner_->write_lock().AssertAcquired(); | 235 owner_->write_mutex().AssertHeld(); |
| 236 return &write_context_; | 236 return &write_context_; |
| 237 } | 237 } |
| 238 | 238 |
| 239 void RawChannelWin::RawChannelIOHandler::OnPendingWriteStartedNoLock( | 239 void RawChannelWin::RawChannelIOHandler::OnPendingWriteStartedNoLock( |
| 240 size_t platform_handles_written) { | 240 size_t platform_handles_written) { |
| 241 DCHECK(owner_); | 241 DCHECK(owner_); |
| 242 owner_->write_lock().AssertAcquired(); | 242 owner_->write_mutex().AssertHeld(); |
| 243 DCHECK(!pending_write_); | 243 DCHECK(!pending_write_); |
| 244 pending_write_ = true; | 244 pending_write_ = true; |
| 245 platform_handles_written_ = platform_handles_written; | 245 platform_handles_written_ = platform_handles_written; |
| 246 } | 246 } |
| 247 | 247 |
| 248 void RawChannelWin::RawChannelIOHandler::OnIOCompleted( | 248 void RawChannelWin::RawChannelIOHandler::OnIOCompleted( |
| 249 base::MessageLoopForIO::IOContext* context, | 249 base::MessageLoopForIO::IOContext* context, |
| 250 DWORD bytes_transferred, | 250 DWORD bytes_transferred, |
| 251 DWORD error) { | 251 DWORD error) { |
| 252 DCHECK(!owner_ || | 252 DCHECK(!owner_ || |
| (...skipping 16 matching lines...) Expand all Loading... |
| 269 | 269 |
| 270 if (ShouldSelfDestruct()) | 270 if (ShouldSelfDestruct()) |
| 271 delete this; | 271 delete this; |
| 272 } | 272 } |
| 273 | 273 |
| 274 void RawChannelWin::RawChannelIOHandler::DetachFromOwnerNoLock( | 274 void RawChannelWin::RawChannelIOHandler::DetachFromOwnerNoLock( |
| 275 scoped_ptr<ReadBuffer> read_buffer, | 275 scoped_ptr<ReadBuffer> read_buffer, |
| 276 scoped_ptr<WriteBuffer> write_buffer) { | 276 scoped_ptr<WriteBuffer> write_buffer) { |
| 277 DCHECK(owner_); | 277 DCHECK(owner_); |
| 278 DCHECK_EQ(base::MessageLoop::current(), owner_->message_loop_for_io()); | 278 DCHECK_EQ(base::MessageLoop::current(), owner_->message_loop_for_io()); |
| 279 owner_->write_lock().AssertAcquired(); | 279 owner_->write_mutex().AssertHeld(); |
| 280 | 280 |
| 281 // If read/write is pending, we have to retain the corresponding buffer. | 281 // If read/write is pending, we have to retain the corresponding buffer. |
| 282 if (pending_read_) | 282 if (pending_read_) |
| 283 preserved_read_buffer_after_detach_ = read_buffer.Pass(); | 283 preserved_read_buffer_after_detach_ = read_buffer.Pass(); |
| 284 if (pending_write_) | 284 if (pending_write_) |
| 285 preserved_write_buffer_after_detach_ = write_buffer.Pass(); | 285 preserved_write_buffer_after_detach_ = write_buffer.Pass(); |
| 286 | 286 |
| 287 owner_ = nullptr; | 287 owner_ = nullptr; |
| 288 if (ShouldSelfDestruct()) | 288 if (ShouldSelfDestruct()) |
| 289 delete this; | 289 delete this; |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 329 DCHECK(suppress_self_destruct_); | 329 DCHECK(suppress_self_destruct_); |
| 330 | 330 |
| 331 if (!owner_) { | 331 if (!owner_) { |
| 332 // No lock needed. | 332 // No lock needed. |
| 333 CHECK(pending_write_); | 333 CHECK(pending_write_); |
| 334 pending_write_ = false; | 334 pending_write_ = false; |
| 335 return; | 335 return; |
| 336 } | 336 } |
| 337 | 337 |
| 338 { | 338 { |
| 339 base::AutoLock locker(owner_->write_lock()); | 339 MutexLocker locker(&owner_->write_mutex()); |
| 340 CHECK(pending_write_); | 340 CHECK(pending_write_); |
| 341 pending_write_ = false; | 341 pending_write_ = false; |
| 342 } | 342 } |
| 343 | 343 |
| 344 // Note: |OnWriteCompleted()| may detach us from |owner_|. | 344 // Note: |OnWriteCompleted()| may detach us from |owner_|. |
| 345 if (error == ERROR_SUCCESS) { | 345 if (error == ERROR_SUCCESS) { |
| 346 // Reset |platform_handles_written_| before calling |OnWriteCompleted()| | 346 // Reset |platform_handles_written_| before calling |OnWriteCompleted()| |
| 347 // since that function may call back to this class and set it again. | 347 // since that function may call back to this class and set it again. |
| 348 size_t local_platform_handles_written_ = platform_handles_written_; | 348 size_t local_platform_handles_written_ = platform_handles_written_; |
| 349 platform_handles_written_ = 0; | 349 platform_handles_written_ = 0; |
| (...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 475 FALSE, DUPLICATE_SAME_ACCESS | DUPLICATE_CLOSE_SOURCE); | 475 FALSE, DUPLICATE_SAME_ACCESS | DUPLICATE_CLOSE_SOURCE); |
| 476 DCHECK(dup_result); | 476 DCHECK(dup_result); |
| 477 rv->push_back(embedder::PlatformHandle(target_handle)); | 477 rv->push_back(embedder::PlatformHandle(target_handle)); |
| 478 } | 478 } |
| 479 return rv.Pass(); | 479 return rv.Pass(); |
| 480 } | 480 } |
| 481 | 481 |
| 482 RawChannel::IOResult RawChannelWin::WriteNoLock( | 482 RawChannel::IOResult RawChannelWin::WriteNoLock( |
| 483 size_t* platform_handles_written, | 483 size_t* platform_handles_written, |
| 484 size_t* bytes_written) { | 484 size_t* bytes_written) { |
| 485 write_lock().AssertAcquired(); | 485 write_mutex().AssertHeld(); |
| 486 | 486 |
| 487 DCHECK(io_handler_); | 487 DCHECK(io_handler_); |
| 488 DCHECK(!io_handler_->pending_write_no_lock()); | 488 DCHECK(!io_handler_->pending_write_no_lock()); |
| 489 | 489 |
| 490 size_t num_platform_handles = 0; | 490 size_t num_platform_handles = 0; |
| 491 if (write_buffer_no_lock()->HavePlatformHandlesToSend()) { | 491 if (write_buffer_no_lock()->HavePlatformHandlesToSend()) { |
| 492 // Since we're not sure which process might ultimately deserialize this | 492 // Since we're not sure which process might ultimately deserialize this |
| 493 // message, we can't duplicate the handle now. Instead, write the process ID | 493 // message, we can't duplicate the handle now. Instead, write the process ID |
| 494 // and handle now and let the receiver duplicate it. | 494 // and handle now and let the receiver duplicate it. |
| 495 embedder::PlatformHandle* platform_handles; | 495 embedder::PlatformHandle* platform_handles; |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 544 // TODO(yzshen): it seems there isn't document saying that all error cases | 544 // TODO(yzshen): it seems there isn't document saying that all error cases |
| 545 // (other than ERROR_IO_PENDING) are guaranteed to *not* queue a completion | 545 // (other than ERROR_IO_PENDING) are guaranteed to *not* queue a completion |
| 546 // packet. If we do get one for errors, |RawChannelIOHandler::OnIOCompleted()| | 546 // packet. If we do get one for errors, |RawChannelIOHandler::OnIOCompleted()| |
| 547 // will crash so we will learn about it. | 547 // will crash so we will learn about it. |
| 548 | 548 |
| 549 io_handler_->OnPendingWriteStartedNoLock(num_platform_handles); | 549 io_handler_->OnPendingWriteStartedNoLock(num_platform_handles); |
| 550 return IO_PENDING; | 550 return IO_PENDING; |
| 551 } | 551 } |
| 552 | 552 |
| 553 RawChannel::IOResult RawChannelWin::ScheduleWriteNoLock() { | 553 RawChannel::IOResult RawChannelWin::ScheduleWriteNoLock() { |
| 554 write_lock().AssertAcquired(); | 554 write_mutex().AssertHeld(); |
| 555 | 555 |
| 556 DCHECK(io_handler_); | 556 DCHECK(io_handler_); |
| 557 DCHECK(!io_handler_->pending_write_no_lock()); | 557 DCHECK(!io_handler_->pending_write_no_lock()); |
| 558 | 558 |
| 559 size_t platform_handles_written = 0; | 559 size_t platform_handles_written = 0; |
| 560 size_t bytes_written = 0; | 560 size_t bytes_written = 0; |
| 561 IOResult io_result = WriteNoLock(&platform_handles_written, &bytes_written); | 561 IOResult io_result = WriteNoLock(&platform_handles_written, &bytes_written); |
| 562 if (io_result == IO_SUCCEEDED) { | 562 if (io_result == IO_SUCCEEDED) { |
| 563 DCHECK(skip_completion_port_on_success_); | 563 DCHECK(skip_completion_port_on_success_); |
| 564 | 564 |
| (...skipping 26 matching lines...) Expand all Loading... |
| 591 | 591 |
| 592 DCHECK(!io_handler_); | 592 DCHECK(!io_handler_); |
| 593 io_handler_ = new RawChannelIOHandler(this, handle_.Pass()); | 593 io_handler_ = new RawChannelIOHandler(this, handle_.Pass()); |
| 594 } | 594 } |
| 595 | 595 |
| 596 void RawChannelWin::OnShutdownNoLock(scoped_ptr<ReadBuffer> read_buffer, | 596 void RawChannelWin::OnShutdownNoLock(scoped_ptr<ReadBuffer> read_buffer, |
| 597 scoped_ptr<WriteBuffer> write_buffer) { | 597 scoped_ptr<WriteBuffer> write_buffer) { |
| 598 DCHECK_EQ(base::MessageLoop::current(), message_loop_for_io()); | 598 DCHECK_EQ(base::MessageLoop::current(), message_loop_for_io()); |
| 599 DCHECK(io_handler_); | 599 DCHECK(io_handler_); |
| 600 | 600 |
| 601 write_lock().AssertAcquired(); | 601 write_mutex().AssertHeld(); |
| 602 | 602 |
| 603 if (io_handler_->pending_read() || io_handler_->pending_write_no_lock()) { | 603 if (io_handler_->pending_read() || io_handler_->pending_write_no_lock()) { |
| 604 // |io_handler_| will be alive until pending read/write (if any) completes. | 604 // |io_handler_| will be alive until pending read/write (if any) completes. |
| 605 // Call |CancelIoEx()| or |CancelIo()| so that resources can be freed up as | 605 // Call |CancelIoEx()| or |CancelIo()| so that resources can be freed up as |
| 606 // soon as possible. | 606 // soon as possible. |
| 607 // Note: |CancelIo()| only cancels read/write requests started from this | 607 // Note: |CancelIo()| only cancels read/write requests started from this |
| 608 // thread. | 608 // thread. |
| 609 if (g_vista_or_higher_functions.Get().is_vista_or_higher()) { | 609 if (g_vista_or_higher_functions.Get().is_vista_or_higher()) { |
| 610 g_vista_or_higher_functions.Get().CancelIoEx(io_handler_->handle(), | 610 g_vista_or_higher_functions.Get().CancelIoEx(io_handler_->handle(), |
| 611 nullptr); | 611 nullptr); |
| (...skipping 12 matching lines...) Expand all Loading... |
| 624 | 624 |
| 625 // Static factory method declared in raw_channel.h. | 625 // Static factory method declared in raw_channel.h. |
| 626 // static | 626 // static |
| 627 scoped_ptr<RawChannel> RawChannel::Create( | 627 scoped_ptr<RawChannel> RawChannel::Create( |
| 628 embedder::ScopedPlatformHandle handle) { | 628 embedder::ScopedPlatformHandle handle) { |
| 629 return make_scoped_ptr(new RawChannelWin(handle.Pass())); | 629 return make_scoped_ptr(new RawChannelWin(handle.Pass())); |
| 630 } | 630 } |
| 631 | 631 |
| 632 } // namespace system | 632 } // namespace system |
| 633 } // namespace mojo | 633 } // namespace mojo |
| OLD | NEW |