| // Copyright 2018 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "mojo/core/invitation_dispatcher.h" |
| |
| #include "mojo/core/core.h" |
| |
| namespace mojo { |
| namespace core { |
| |
| InvitationDispatcher::InvitationDispatcher() = default; |
| |
| Dispatcher::Type InvitationDispatcher::GetType() const { |
| return Type::INVITATION; |
| } |
| |
| MojoResult InvitationDispatcher::Close() { |
| PortMapping attached_ports; |
| { |
| base::AutoLock lock(lock_); |
| if (is_closed_) |
| return MOJO_RESULT_INVALID_ARGUMENT; |
| is_closed_ = true; |
| std::swap(attached_ports, attached_ports_); |
| } |
| for (auto& entry : attached_ports) |
| Core::Get()->GetNodeController()->ClosePort(entry.second); |
| return MOJO_RESULT_OK; |
| } |
| |
| MojoResult InvitationDispatcher::AttachMessagePipe( |
| base::StringPiece name, |
| ports::PortRef remote_peer_port) { |
| base::AutoLock lock(lock_); |
| auto result = attached_ports_.emplace(name.as_string(), remote_peer_port); |
| if (!result.second) { |
| Core::Get()->GetNodeController()->ClosePort(remote_peer_port); |
| return MOJO_RESULT_ALREADY_EXISTS; |
| } |
| return MOJO_RESULT_OK; |
| } |
| |
| MojoResult InvitationDispatcher::ExtractMessagePipe( |
| base::StringPiece name, |
| MojoHandle* message_pipe_handle) { |
| ports::PortRef remote_peer_port; |
| { |
| base::AutoLock lock(lock_); |
| auto it = attached_ports_.find(name.as_string()); |
| if (it == attached_ports_.end()) |
| return MOJO_RESULT_NOT_FOUND; |
| remote_peer_port = std::move(it->second); |
| attached_ports_.erase(it); |
| } |
| |
| *message_pipe_handle = |
| Core::Get()->CreatePartialMessagePipe(remote_peer_port); |
| if (*message_pipe_handle == MOJO_HANDLE_INVALID) |
| return MOJO_RESULT_RESOURCE_EXHAUSTED; |
| return MOJO_RESULT_OK; |
| } |
| |
| InvitationDispatcher::PortMapping InvitationDispatcher::TakeAttachedPorts() { |
| PortMapping attached_ports; |
| { |
| base::AutoLock lock(lock_); |
| std::swap(attached_ports, attached_ports_); |
| } |
| return attached_ports; |
| } |
| |
| InvitationDispatcher::~InvitationDispatcher() { |
| DCHECK(is_closed_); |
| } |
| |
| } // namespace core |
| } // namespace mojo |