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 |