| Index: mojo/edk/system/endpoint_relayer.cc
 | 
| diff --git a/mojo/edk/system/endpoint_relayer.cc b/mojo/edk/system/endpoint_relayer.cc
 | 
| new file mode 100644
 | 
| index 0000000000000000000000000000000000000000..52faefa4c6e783aaea5f95afb1290e7779f0b3e6
 | 
| --- /dev/null
 | 
| +++ b/mojo/edk/system/endpoint_relayer.cc
 | 
| @@ -0,0 +1,70 @@
 | 
| +// Copyright 2014 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/edk/system/endpoint_relayer.h"
 | 
| +
 | 
| +#include "base/logging.h"
 | 
| +#include "mojo/edk/system/channel_endpoint.h"
 | 
| +#include "mojo/edk/system/message_in_transit.h"
 | 
| +
 | 
| +namespace mojo {
 | 
| +namespace system {
 | 
| +
 | 
| +EndpointRelayer::EndpointRelayer() {
 | 
| +}
 | 
| +
 | 
| +// static
 | 
| +unsigned EndpointRelayer::GetPeerPort(unsigned port) {
 | 
| +  DCHECK(port == 0 || port == 1);
 | 
| +  return port ^ 1;
 | 
| +}
 | 
| +
 | 
| +void EndpointRelayer::Init(ChannelEndpoint* endpoint0,
 | 
| +                           ChannelEndpoint* endpoint1) {
 | 
| +  DCHECK(endpoint0);
 | 
| +  DCHECK(endpoint1);
 | 
| +  DCHECK(!endpoints_[0]);
 | 
| +  DCHECK(!endpoints_[1]);
 | 
| +  endpoints_[0] = endpoint0;
 | 
| +  endpoints_[1] = endpoint1;
 | 
| +}
 | 
| +
 | 
| +bool EndpointRelayer::OnReadMessage(unsigned port, MessageInTransit* message) {
 | 
| +  DCHECK(message);
 | 
| +
 | 
| +  base::AutoLock locker(lock_);
 | 
| +
 | 
| +  // If we're no longer the client, then reject the message.
 | 
| +  if (!endpoints_[port])
 | 
| +    return false;
 | 
| +
 | 
| +  // Otherwise, consume it even if the peer port is closed.
 | 
| +  unsigned peer_port = GetPeerPort(port);
 | 
| +  if (endpoints_[peer_port])
 | 
| +    endpoints_[peer_port]->EnqueueMessage(make_scoped_ptr(message));
 | 
| +  return true;
 | 
| +}
 | 
| +
 | 
| +void EndpointRelayer::OnDetachFromChannel(unsigned port) {
 | 
| +  base::AutoLock locker(lock_);
 | 
| +
 | 
| +  if (endpoints_[port]) {
 | 
| +    endpoints_[port]->DetachFromClient();
 | 
| +    endpoints_[port] = nullptr;
 | 
| +  }
 | 
| +
 | 
| +  unsigned peer_port = GetPeerPort(port);
 | 
| +  if (endpoints_[peer_port]) {
 | 
| +    endpoints_[peer_port]->DetachFromClient();
 | 
| +    endpoints_[peer_port] = nullptr;
 | 
| +  }
 | 
| +}
 | 
| +
 | 
| +EndpointRelayer::~EndpointRelayer() {
 | 
| +  DCHECK(!endpoints_[0]);
 | 
| +  DCHECK(!endpoints_[1]);
 | 
| +}
 | 
| +
 | 
| +}  // namespace system
 | 
| +}  // namespace mojo
 | 
| 
 |