| OLD | NEW |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 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/message_pipe_dispatcher.h" | 5 #include "mojo/edk/system/message_pipe_dispatcher.h" |
| 6 | 6 |
| 7 #include <limits> | 7 #include <limits> |
| 8 #include <memory> | 8 #include <memory> |
| 9 | 9 |
| 10 #include "base/logging.h" | 10 #include "base/logging.h" |
| (...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 176 | 176 |
| 177 bool MessagePipeDispatcher::Fuse(MessagePipeDispatcher* other) { | 177 bool MessagePipeDispatcher::Fuse(MessagePipeDispatcher* other) { |
| 178 node_controller_->SetPortObserver(port_, nullptr); | 178 node_controller_->SetPortObserver(port_, nullptr); |
| 179 node_controller_->SetPortObserver(other->port_, nullptr); | 179 node_controller_->SetPortObserver(other->port_, nullptr); |
| 180 | 180 |
| 181 ports::PortRef port0; | 181 ports::PortRef port0; |
| 182 { | 182 { |
| 183 base::AutoLock lock(signal_lock_); | 183 base::AutoLock lock(signal_lock_); |
| 184 port0 = port_; | 184 port0 = port_; |
| 185 port_closed_.Set(true); | 185 port_closed_.Set(true); |
| 186 awakables_.CancelAll(); | |
| 187 watchers_.NotifyClosed(); | 186 watchers_.NotifyClosed(); |
| 188 } | 187 } |
| 189 | 188 |
| 190 ports::PortRef port1; | 189 ports::PortRef port1; |
| 191 { | 190 { |
| 192 base::AutoLock lock(other->signal_lock_); | 191 base::AutoLock lock(other->signal_lock_); |
| 193 port1 = other->port_; | 192 port1 = other->port_; |
| 194 other->port_closed_.Set(true); | 193 other->port_closed_.Set(true); |
| 195 other->awakables_.CancelAll(); | |
| 196 other->watchers_.NotifyClosed(); | 194 other->watchers_.NotifyClosed(); |
| 197 } | 195 } |
| 198 | 196 |
| 199 // Both ports are always closed by this call. | 197 // Both ports are always closed by this call. |
| 200 int rv = node_controller_->MergeLocalPorts(port0, port1); | 198 int rv = node_controller_->MergeLocalPorts(port0, port1); |
| 201 return rv == ports::OK; | 199 return rv == ports::OK; |
| 202 } | 200 } |
| 203 | 201 |
| 204 Dispatcher::Type MessagePipeDispatcher::GetType() const { | 202 Dispatcher::Type MessagePipeDispatcher::GetType() const { |
| 205 return Type::MESSAGE_PIPE; | 203 return Type::MESSAGE_PIPE; |
| (...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 401 } | 399 } |
| 402 | 400 |
| 403 MojoResult MessagePipeDispatcher::RemoveWatcherRef(WatcherDispatcher* watcher, | 401 MojoResult MessagePipeDispatcher::RemoveWatcherRef(WatcherDispatcher* watcher, |
| 404 uintptr_t context) { | 402 uintptr_t context) { |
| 405 base::AutoLock lock(signal_lock_); | 403 base::AutoLock lock(signal_lock_); |
| 406 if (port_closed_ || in_transit_) | 404 if (port_closed_ || in_transit_) |
| 407 return MOJO_RESULT_INVALID_ARGUMENT; | 405 return MOJO_RESULT_INVALID_ARGUMENT; |
| 408 return watchers_.Remove(watcher, context); | 406 return watchers_.Remove(watcher, context); |
| 409 } | 407 } |
| 410 | 408 |
| 411 MojoResult MessagePipeDispatcher::AddAwakable( | |
| 412 Awakable* awakable, | |
| 413 MojoHandleSignals signals, | |
| 414 uintptr_t context, | |
| 415 HandleSignalsState* signals_state) { | |
| 416 base::AutoLock lock(signal_lock_); | |
| 417 | |
| 418 if (port_closed_ || in_transit_) { | |
| 419 if (signals_state) | |
| 420 *signals_state = HandleSignalsState(); | |
| 421 return MOJO_RESULT_INVALID_ARGUMENT; | |
| 422 } | |
| 423 | |
| 424 HandleSignalsState state = GetHandleSignalsStateNoLock(); | |
| 425 | |
| 426 DVLOG(2) << "Getting signal state for pipe " << pipe_id_ << " endpoint " | |
| 427 << endpoint_ << " [awakable=" << awakable << "; port=" | |
| 428 << port_.name() << "; signals=" << signals << "; satisfied=" | |
| 429 << state.satisfied_signals << "; satisfiable=" | |
| 430 << state.satisfiable_signals << "]"; | |
| 431 | |
| 432 if (state.satisfies(signals)) { | |
| 433 if (signals_state) | |
| 434 *signals_state = state; | |
| 435 DVLOG(2) << "Signals already set for " << port_.name(); | |
| 436 return MOJO_RESULT_ALREADY_EXISTS; | |
| 437 } | |
| 438 if (!state.can_satisfy(signals)) { | |
| 439 if (signals_state) | |
| 440 *signals_state = state; | |
| 441 DVLOG(2) << "Signals impossible to satisfy for " << port_.name(); | |
| 442 return MOJO_RESULT_FAILED_PRECONDITION; | |
| 443 } | |
| 444 | |
| 445 DVLOG(2) << "Adding awakable to pipe " << pipe_id_ << " endpoint " | |
| 446 << endpoint_ << " [awakable=" << awakable << "; port=" | |
| 447 << port_.name() << "; signals=" << signals << "]"; | |
| 448 | |
| 449 awakables_.Add(awakable, signals, context); | |
| 450 return MOJO_RESULT_OK; | |
| 451 } | |
| 452 | |
| 453 void MessagePipeDispatcher::RemoveAwakable(Awakable* awakable, | |
| 454 HandleSignalsState* signals_state) { | |
| 455 base::AutoLock lock(signal_lock_); | |
| 456 if (port_closed_ || in_transit_) { | |
| 457 if (signals_state) | |
| 458 *signals_state = HandleSignalsState(); | |
| 459 } else if (signals_state) { | |
| 460 *signals_state = GetHandleSignalsStateNoLock(); | |
| 461 } | |
| 462 | |
| 463 DVLOG(2) << "Removing awakable from pipe " << pipe_id_ << " endpoint " | |
| 464 << endpoint_ << " [awakable=" << awakable << "; port=" | |
| 465 << port_.name() << "]"; | |
| 466 | |
| 467 awakables_.Remove(awakable); | |
| 468 } | |
| 469 | |
| 470 void MessagePipeDispatcher::StartSerialize(uint32_t* num_bytes, | 409 void MessagePipeDispatcher::StartSerialize(uint32_t* num_bytes, |
| 471 uint32_t* num_ports, | 410 uint32_t* num_ports, |
| 472 uint32_t* num_handles) { | 411 uint32_t* num_handles) { |
| 473 *num_bytes = static_cast<uint32_t>(sizeof(SerializedState)); | 412 *num_bytes = static_cast<uint32_t>(sizeof(SerializedState)); |
| 474 *num_ports = 1; | 413 *num_ports = 1; |
| 475 *num_handles = 0; | 414 *num_handles = 0; |
| 476 } | 415 } |
| 477 | 416 |
| 478 bool MessagePipeDispatcher::EndSerialize(void* destination, | 417 bool MessagePipeDispatcher::EndSerialize(void* destination, |
| 479 ports::PortName* ports, | 418 ports::PortName* ports, |
| (...skipping 21 matching lines...) Expand all Loading... |
| 501 port_transferred_ = true; | 440 port_transferred_ = true; |
| 502 in_transit_.Set(false); | 441 in_transit_.Set(false); |
| 503 CloseNoLock(); | 442 CloseNoLock(); |
| 504 } | 443 } |
| 505 | 444 |
| 506 void MessagePipeDispatcher::CancelTransit() { | 445 void MessagePipeDispatcher::CancelTransit() { |
| 507 base::AutoLock lock(signal_lock_); | 446 base::AutoLock lock(signal_lock_); |
| 508 in_transit_.Set(false); | 447 in_transit_.Set(false); |
| 509 | 448 |
| 510 // Something may have happened while we were waiting for potential transit. | 449 // Something may have happened while we were waiting for potential transit. |
| 511 HandleSignalsState state = GetHandleSignalsStateNoLock(); | 450 watchers_.NotifyState(GetHandleSignalsStateNoLock()); |
| 512 awakables_.AwakeForStateChange(state); | |
| 513 watchers_.NotifyState(state); | |
| 514 } | 451 } |
| 515 | 452 |
| 516 // static | 453 // static |
| 517 scoped_refptr<Dispatcher> MessagePipeDispatcher::Deserialize( | 454 scoped_refptr<Dispatcher> MessagePipeDispatcher::Deserialize( |
| 518 const void* data, | 455 const void* data, |
| 519 size_t num_bytes, | 456 size_t num_bytes, |
| 520 const ports::PortName* ports, | 457 const ports::PortName* ports, |
| 521 size_t num_ports, | 458 size_t num_ports, |
| 522 PlatformHandle* handles, | 459 PlatformHandle* handles, |
| 523 size_t num_handles) { | 460 size_t num_handles) { |
| (...skipping 14 matching lines...) Expand all Loading... |
| 538 MessagePipeDispatcher::~MessagePipeDispatcher() { | 475 MessagePipeDispatcher::~MessagePipeDispatcher() { |
| 539 DCHECK(port_closed_ && !in_transit_); | 476 DCHECK(port_closed_ && !in_transit_); |
| 540 } | 477 } |
| 541 | 478 |
| 542 MojoResult MessagePipeDispatcher::CloseNoLock() { | 479 MojoResult MessagePipeDispatcher::CloseNoLock() { |
| 543 signal_lock_.AssertAcquired(); | 480 signal_lock_.AssertAcquired(); |
| 544 if (port_closed_ || in_transit_) | 481 if (port_closed_ || in_transit_) |
| 545 return MOJO_RESULT_INVALID_ARGUMENT; | 482 return MOJO_RESULT_INVALID_ARGUMENT; |
| 546 | 483 |
| 547 port_closed_.Set(true); | 484 port_closed_.Set(true); |
| 548 awakables_.CancelAll(); | |
| 549 watchers_.NotifyClosed(); | 485 watchers_.NotifyClosed(); |
| 550 | 486 |
| 551 if (!port_transferred_) { | 487 if (!port_transferred_) { |
| 552 base::AutoUnlock unlock(signal_lock_); | 488 base::AutoUnlock unlock(signal_lock_); |
| 553 node_controller_->ClosePort(port_); | 489 node_controller_->ClosePort(port_); |
| 554 } | 490 } |
| 555 | 491 |
| 556 return MOJO_RESULT_OK; | 492 return MOJO_RESULT_OK; |
| 557 } | 493 } |
| 558 | 494 |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 604 << " endpoint " << endpoint_ << " [port=" << port_.name() | 540 << " endpoint " << endpoint_ << " [port=" << port_.name() |
| 605 << "; size=" << filter.message_size() << "]"; | 541 << "; size=" << filter.message_size() << "]"; |
| 606 } | 542 } |
| 607 if (port_status.peer_closed) { | 543 if (port_status.peer_closed) { |
| 608 DVLOG(2) << "Peer closure detected on message pipe " << pipe_id_ | 544 DVLOG(2) << "Peer closure detected on message pipe " << pipe_id_ |
| 609 << " endpoint " << endpoint_ << " [port=" << port_.name() << "]"; | 545 << " endpoint " << endpoint_ << " [port=" << port_.name() << "]"; |
| 610 } | 546 } |
| 611 } | 547 } |
| 612 #endif | 548 #endif |
| 613 | 549 |
| 614 HandleSignalsState state = GetHandleSignalsStateNoLock(); | 550 watchers_.NotifyState(GetHandleSignalsStateNoLock()); |
| 615 awakables_.AwakeForStateChange(state); | |
| 616 watchers_.NotifyState(state); | |
| 617 } | 551 } |
| 618 | 552 |
| 619 } // namespace edk | 553 } // namespace edk |
| 620 } // namespace mojo | 554 } // namespace mojo |
| OLD | NEW |