Commit 2f60c9b7 authored by morrita@chromium.org's avatar morrita@chromium.org

Make IPC::Channel polymorphic

This change makes each platform specific ChannelImpl into
a subclass of Channel: ChannelPosix, ChannelWin, ChannelNacl.
delegated functions are now virtual.

TEST=none
BUG=377980
R=darin@chromium.org, jam@chromium.org

Review URL: https://codereview.chromium.org/310293002

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@275505 0039d316-1c4b-4281-b951-d872f2087c98
parent 42dbdaa6
......@@ -86,7 +86,7 @@ class NPChannelBase : public IPC::Listener,
// IPC::Sender implementation:
virtual bool Send(IPC::Message* msg) OVERRIDE;
base::ProcessId peer_pid() { return channel_->peer_pid(); }
base::ProcessId peer_pid() { return channel_->GetPeerPID(); }
IPC::ChannelHandle channel_handle() const { return channel_handle_; }
// Returns the number of open NPObject channels in this process.
......
......@@ -266,7 +266,7 @@ base::SharedMemoryHandle GpuChannelHost::ShareToGpuProcess(
// Windows needs to explicitly duplicate the handle out to another process.
base::SharedMemoryHandle target_handle;
if (!BrokerDuplicateHandle(source_handle,
channel_->peer_pid(),
channel_->GetPeerPID(),
&target_handle,
FILE_GENERIC_READ | FILE_GENERIC_WRITE,
0)) {
......
......@@ -76,7 +76,7 @@ class GpuChannel : public IPC::Listener, public IPC::Sender {
int TakeRendererFileDescriptor();
#endif // defined(OS_POSIX)
base::ProcessId renderer_pid() const { return channel_->peer_pid(); }
base::ProcessId renderer_pid() const { return channel_->GetPeerPID(); }
int client_id() const { return client_id_; }
......
......@@ -176,7 +176,7 @@ blink::WebPluginContainer* RendererPpapiHostImpl::GetContainerForInstance(
base::ProcessId RendererPpapiHostImpl::GetPluginPID() const {
if (dispatcher_)
return dispatcher_->channel()->peer_pid();
return dispatcher_->channel()->GetPeerPID();
return base::kNullProcessId;
}
......
......@@ -117,8 +117,9 @@ class IPC_EXPORT Channel : public Sender {
//
// TODO(morrita): Replace CreateByModeForProxy() with one of above Create*().
//
static scoped_ptr<Channel> CreateByModeForProxy(
static scoped_ptr<Channel> Create(
const IPC::ChannelHandle &channel_handle, Mode mode,Listener* listener);
static scoped_ptr<Channel> CreateClient(
const IPC::ChannelHandle &channel_handle, Listener* listener);
......@@ -149,14 +150,14 @@ class IPC_EXPORT Channel : public Sender {
// connect to a pre-existing pipe. Note, calling Connect()
// will not block the calling thread and may complete
// asynchronously.
bool Connect() WARN_UNUSED_RESULT;
virtual bool Connect() WARN_UNUSED_RESULT = 0;
// Close this Channel explicitly. May be called multiple times.
// On POSIX calling close on an IPC channel that listens for connections will
// cause it to close any accepted connections, and it will stop listening for
// new connections. If you just want to close the currently accepted
// connection and listen for new ones, use ResetToAcceptingConnectionState.
void Close();
virtual void Close() = 0;
// Get the process ID for the connected peer.
//
......@@ -167,25 +168,25 @@ class IPC_EXPORT Channel : public Sender {
// in response to a message from the remote side (which guarantees that it's
// been connected), or you wait for the "connected" notification on the
// listener.
base::ProcessId peer_pid() const;
virtual base::ProcessId GetPeerPID() const = 0;
// Send a message over the Channel to the listener on the other end.
//
// |message| must be allocated using operator new. This object will be
// deleted once the contents of the Message have been sent.
virtual bool Send(Message* message) OVERRIDE;
virtual bool Send(Message* message) = 0;
#if defined(OS_POSIX)
#if defined(OS_POSIX) && !defined(OS_NACL)
// On POSIX an IPC::Channel wraps a socketpair(), this method returns the
// FD # for the client end of the socket.
// This method may only be called on the server side of a channel.
// This method can be called on any thread.
int GetClientFileDescriptor() const;
virtual int GetClientFileDescriptor() const = 0;
// Same as GetClientFileDescriptor, but transfers the ownership of the
// file descriptor to the caller.
// This method can be called on any thread.
int TakeClientFileDescriptor();
virtual int TakeClientFileDescriptor() = 0;
// On POSIX an IPC::Channel can either wrap an established socket, or it
// can wrap a socket that is listening for connections. Currently an
......@@ -193,19 +194,19 @@ class IPC_EXPORT Channel : public Sender {
// at a time.
// Returns true if the channel supports listening for connections.
bool AcceptsConnections() const;
virtual bool AcceptsConnections() const = 0;
// Returns true if the channel supports listening for connections and is
// currently connected.
bool HasAcceptedConnection() const;
virtual bool HasAcceptedConnection() const = 0;
// Returns true if the peer process' effective user id can be determined, in
// which case the supplied peer_euid is updated with it.
bool GetPeerEuid(uid_t* peer_euid) const;
virtual bool GetPeerEuid(uid_t* peer_euid) const = 0;
// Closes any currently connected socket, and returns to a listening state
// for more connections.
void ResetToAcceptingConnectionState();
virtual void ResetToAcceptingConnectionState() = 0;
#endif // defined(OS_POSIX) && !defined(OS_NACL)
// Returns true if a named server channel is initialized on the given channel
......@@ -238,20 +239,6 @@ class IPC_EXPORT Channel : public Sender {
static void NotifyProcessForkedForTesting();
#endif
protected:
// Used in Chrome by the TestSink to provide a dummy channel implementation
// for testing. TestSink overrides the "interesting" functions in Channel so
// no actual implementation is needed. This will cause un-overridden calls to
// segfault. Do not use outside of test code!
Channel() : channel_impl_(0) { }
private:
Channel(const IPC::ChannelHandle &channel_handle, Mode mode,
Listener* listener);
// PIMPL to which all channel calls are delegated.
class ChannelImpl;
ChannelImpl *channel_impl_;
};
#if defined(OS_POSIX)
......
......@@ -6,50 +6,42 @@
namespace IPC {
// static
scoped_ptr<Channel> Channel::CreateByModeForProxy(
const IPC::ChannelHandle &channel_handle, Mode mode, Listener* listener) {
return make_scoped_ptr(
new Channel(channel_handle, mode, listener));
}
// static
scoped_ptr<Channel> Channel::CreateClient(
const IPC::ChannelHandle &channel_handle, Listener* listener) {
return make_scoped_ptr(
new Channel(channel_handle, Channel::MODE_CLIENT, listener));
return Channel::Create(channel_handle, Channel::MODE_CLIENT, listener);
}
// static
scoped_ptr<Channel> Channel::CreateNamedServer(
const IPC::ChannelHandle &channel_handle, Listener* listener) {
return make_scoped_ptr(
new Channel(channel_handle, Channel::MODE_NAMED_SERVER, listener));
return Channel::Create(channel_handle, Channel::MODE_NAMED_SERVER, listener);
}
// static
scoped_ptr<Channel> Channel::CreateNamedClient(
const IPC::ChannelHandle &channel_handle, Listener* listener) {
return make_scoped_ptr(
new Channel(channel_handle, Channel::MODE_NAMED_CLIENT, listener));
return Channel::Create(channel_handle, Channel::MODE_NAMED_CLIENT, listener);
}
#if defined(OS_POSIX)
// static
scoped_ptr<Channel> Channel::CreateOpenNamedServer(
const IPC::ChannelHandle &channel_handle, Listener* listener) {
return make_scoped_ptr(
new Channel(channel_handle, Channel::MODE_OPEN_NAMED_SERVER, listener));
return Channel::Create(channel_handle,
Channel::MODE_OPEN_NAMED_SERVER,
listener);
}
#endif
// static
scoped_ptr<Channel> Channel::CreateServer(
const IPC::ChannelHandle &channel_handle, Listener* listener) {
return make_scoped_ptr(
new Channel(channel_handle, Channel::MODE_SERVER, listener));
return Channel::Create(channel_handle, Channel::MODE_SERVER, listener);
}
Channel::~Channel() {
}
} // namespace IPC
......@@ -62,7 +62,7 @@ bool ReadDataOnReaderThread(int pipe, MessageContents* contents) {
} // namespace
class Channel::ChannelImpl::ReaderThreadRunner
class ChannelNacl::ReaderThreadRunner
: public base::DelegateSimpleThread::Delegate {
public:
// |pipe|: A file descriptor from which we will read using imc_recvmsg.
......@@ -91,7 +91,7 @@ class Channel::ChannelImpl::ReaderThreadRunner
DISALLOW_COPY_AND_ASSIGN(ReaderThreadRunner);
};
Channel::ChannelImpl::ReaderThreadRunner::ReaderThreadRunner(
ChannelNacl::ReaderThreadRunner::ReaderThreadRunner(
int pipe,
base::Callback<void (scoped_ptr<MessageContents>)> data_read_callback,
base::Callback<void ()> failure_callback,
......@@ -102,7 +102,7 @@ Channel::ChannelImpl::ReaderThreadRunner::ReaderThreadRunner(
main_message_loop_(main_message_loop) {
}
void Channel::ChannelImpl::ReaderThreadRunner::Run() {
void ChannelNacl::ReaderThreadRunner::Run() {
while (true) {
scoped_ptr<MessageContents> msg_contents(new MessageContents);
bool success = ReadDataOnReaderThread(pipe_, msg_contents.get());
......@@ -118,9 +118,9 @@ void Channel::ChannelImpl::ReaderThreadRunner::Run() {
}
}
Channel::ChannelImpl::ChannelImpl(const IPC::ChannelHandle& channel_handle,
Mode mode,
Listener* listener)
ChannelNacl::ChannelNacl(const IPC::ChannelHandle& channel_handle,
Mode mode,
Listener* listener)
: ChannelReader(listener),
mode_(mode),
waiting_connect_(true),
......@@ -135,17 +135,17 @@ Channel::ChannelImpl::ChannelImpl(const IPC::ChannelHandle& channel_handle,
}
}
Channel::ChannelImpl::~ChannelImpl() {
ChannelNacl::~ChannelNacl() {
Close();
}
base::ProcessId Channel::ChannelImpl::peer_pid() const {
base::ProcessId ChannelNacl::GetPeerPID() const {
// This shouldn't actually get used in the untrusted side of the proxy, and we
// don't have the real pid anyway.
return -1;
}
bool Channel::ChannelImpl::Connect() {
bool ChannelNacl::Connect() {
if (pipe_ == -1) {
DLOG(WARNING) << "Channel creation failed: " << pipe_name_;
return false;
......@@ -159,9 +159,9 @@ bool Channel::ChannelImpl::Connect() {
reader_thread_runner_.reset(
new ReaderThreadRunner(
pipe_,
base::Bind(&Channel::ChannelImpl::DidRecvMsg,
base::Bind(&ChannelNacl::DidRecvMsg,
weak_ptr_factory_.GetWeakPtr()),
base::Bind(&Channel::ChannelImpl::ReadDidFail,
base::Bind(&ChannelNacl::ReadDidFail,
weak_ptr_factory_.GetWeakPtr()),
base::MessageLoopProxy::current()));
reader_thread_.reset(
......@@ -172,13 +172,13 @@ bool Channel::ChannelImpl::Connect() {
// If there were any messages queued before connection, send them.
ProcessOutgoingMessages();
base::MessageLoopProxy::current()->PostTask(FROM_HERE,
base::Bind(&Channel::ChannelImpl::CallOnChannelConnected,
base::Bind(&ChannelNacl::CallOnChannelConnected,
weak_ptr_factory_.GetWeakPtr()));
return true;
}
void Channel::ChannelImpl::Close() {
void ChannelNacl::Close() {
// For now, we assume that at shutdown, the reader thread will be woken with
// a failure (see NaClIPCAdapter::BlockingRead and CloseChannel). Or... we
// might simply be killed with no chance to clean up anyway :-).
......@@ -195,7 +195,7 @@ void Channel::ChannelImpl::Close() {
output_queue_.clear();
}
bool Channel::ChannelImpl::Send(Message* message) {
bool ChannelNacl::Send(Message* message) {
DVLOG(2) << "sending message @" << message << " on channel @" << this
<< " with type " << message->type();
scoped_ptr<Message> message_ptr(message);
......@@ -212,7 +212,7 @@ bool Channel::ChannelImpl::Send(Message* message) {
return true;
}
void Channel::ChannelImpl::DidRecvMsg(scoped_ptr<MessageContents> contents) {
void ChannelNacl::DidRecvMsg(scoped_ptr<MessageContents> contents) {
// Close sets the pipe to -1. It's possible we'll get a buffer sent to us from
// the reader thread after Close is called. If so, we ignore it.
if (pipe_ == -1)
......@@ -233,11 +233,11 @@ void Channel::ChannelImpl::DidRecvMsg(scoped_ptr<MessageContents> contents) {
ProcessIncomingMessages();
}
void Channel::ChannelImpl::ReadDidFail() {
void ChannelNacl::ReadDidFail() {
Close();
}
bool Channel::ChannelImpl::CreatePipe(
bool ChannelNacl::CreatePipe(
const IPC::ChannelHandle& channel_handle) {
DCHECK(pipe_ == -1);
......@@ -256,7 +256,7 @@ bool Channel::ChannelImpl::CreatePipe(
return true;
}
bool Channel::ChannelImpl::ProcessOutgoingMessages() {
bool ChannelNacl::ProcessOutgoingMessages() {
DCHECK(!waiting_connect_); // Why are we trying to send messages if there's
// no connection?
if (output_queue_.empty())
......@@ -304,11 +304,11 @@ bool Channel::ChannelImpl::ProcessOutgoingMessages() {
return true;
}
void Channel::ChannelImpl::CallOnChannelConnected() {
listener()->OnChannelConnected(peer_pid());
void ChannelNacl::CallOnChannelConnected() {
listener()->OnChannelConnected(GetPeerPID());
}
Channel::ChannelImpl::ReadState Channel::ChannelImpl::ReadData(
ChannelNacl::ReadState ChannelNacl::ReadData(
char* buffer,
int buffer_len,
int* bytes_read) {
......@@ -339,7 +339,7 @@ Channel::ChannelImpl::ReadState Channel::ChannelImpl::ReadData(
return READ_SUCCEEDED;
}
bool Channel::ChannelImpl::WillDispatchInputMessage(Message* msg) {
bool ChannelNacl::WillDispatchInputMessage(Message* msg) {
uint16 header_fds = msg->header()->num_fds;
CHECK(header_fds == input_fds_.size());
if (header_fds == 0)
......@@ -354,44 +354,24 @@ bool Channel::ChannelImpl::WillDispatchInputMessage(Message* msg) {
return true;
}
bool Channel::ChannelImpl::DidEmptyInputBuffers() {
bool ChannelNacl::DidEmptyInputBuffers() {
// When the input data buffer is empty, the fds should be too.
return input_fds_.empty();
}
void Channel::ChannelImpl::HandleInternalMessage(const Message& msg) {
void ChannelNacl::HandleInternalMessage(const Message& msg) {
// The trusted side IPC::Channel should handle the "hello" handshake; we
// should not receive the "Hello" message.
NOTREACHED();
}
//------------------------------------------------------------------------------
// Channel's methods simply call through to ChannelImpl.
// Channel's methods
Channel::Channel(const IPC::ChannelHandle& channel_handle,
Mode mode,
Listener* listener)
: channel_impl_(new ChannelImpl(channel_handle, mode, listener)) {
}
Channel::~Channel() {
delete channel_impl_;
}
bool Channel::Connect() {
return channel_impl_->Connect();
}
void Channel::Close() {
channel_impl_->Close();
}
base::ProcessId Channel::peer_pid() const {
return channel_impl_->peer_pid();
}
bool Channel::Send(Message* message) {
return channel_impl_->Send(message);
// static
scoped_ptr<Channel> Channel::Create(
const IPC::ChannelHandle &channel_handle, Mode mode, Listener* listener) {
return scoped_ptr<Channel>(
new ChannelNacl(channel_handle, mode, listener));
}
} // namespace IPC
......@@ -22,7 +22,7 @@ namespace IPC {
// descriptors).
struct MessageContents;
// Similar to the Posix version of ChannelImpl but for Native Client code.
// Similar to the ChannelPosix but for Native Client code.
// This is somewhat different because sendmsg/recvmsg here do not follow POSIX
// semantics. Instead, they are implemented by a custom embedding of
// NaClDescCustom. See NaClIPCAdapter for the trusted-side implementation.
......@@ -31,19 +31,20 @@ struct MessageContents;
// sharing handles. We also currently do not support passing file descriptors or
// named pipes, and we use background threads to emulate signaling when we can
// read or write without blocking.
class Channel::ChannelImpl : public internal::ChannelReader {
class ChannelNacl : public Channel,
public internal::ChannelReader {
public:
// Mirror methods of Channel, see ipc_channel.h for description.
ChannelImpl(const IPC::ChannelHandle& channel_handle,
ChannelNacl(const IPC::ChannelHandle& channel_handle,
Mode mode,
Listener* listener);
virtual ~ChannelImpl();
virtual ~ChannelNacl();
// Channel implementation.
base::ProcessId peer_pid() const;
bool Connect();
void Close();
bool Send(Message* message);
virtual base::ProcessId GetPeerPID() const OVERRIDE;
virtual bool Connect() OVERRIDE;
virtual void Close() OVERRIDE;
virtual bool Send(Message* message) OVERRIDE;
// Posted to the main thread by ReaderThreadRunner.
void DidRecvMsg(scoped_ptr<MessageContents> contents);
......@@ -110,9 +111,9 @@ class Channel::ChannelImpl : public internal::ChannelReader {
// called. Normally after we're connected, the queue is empty.
std::deque<linked_ptr<Message> > output_queue_;
base::WeakPtrFactory<ChannelImpl> weak_ptr_factory_;
base::WeakPtrFactory<ChannelNacl> weak_ptr_factory_;
DISALLOW_IMPLICIT_CONSTRUCTORS(ChannelImpl);
DISALLOW_IMPLICIT_CONSTRUCTORS(ChannelNacl);
};
} // namespace IPC
......
This diff is collapsed.
......@@ -49,24 +49,29 @@
namespace IPC {
class Channel::ChannelImpl : public internal::ChannelReader,
public base::MessageLoopForIO::Watcher {
class ChannelPosix : public Channel,
public internal::ChannelReader,
public base::MessageLoopForIO::Watcher {
public:
// Mirror methods of Channel, see ipc_channel.h for description.
ChannelImpl(const IPC::ChannelHandle& channel_handle, Mode mode,
Listener* listener);
virtual ~ChannelImpl();
bool Connect();
void Close();
bool Send(Message* message);
int GetClientFileDescriptor();
int TakeClientFileDescriptor();
ChannelPosix(const IPC::ChannelHandle& channel_handle, Mode mode,
Listener* listener);
virtual ~ChannelPosix();
// Channel implementation
virtual bool Connect() OVERRIDE;
virtual void Close() OVERRIDE;
virtual bool Send(Message* message) OVERRIDE;
virtual base::ProcessId GetPeerPID() const OVERRIDE;
virtual int GetClientFileDescriptor() const OVERRIDE;
virtual int TakeClientFileDescriptor() OVERRIDE;
virtual bool AcceptsConnections() const OVERRIDE;
virtual bool HasAcceptedConnection() const OVERRIDE;
virtual bool GetPeerEuid(uid_t* peer_euid) const OVERRIDE;
virtual void ResetToAcceptingConnectionState() OVERRIDE;
void CloseClientFileDescriptor();
bool AcceptsConnections() const;
bool HasAcceptedConnection() const;
bool GetPeerEuid(uid_t* peer_euid) const;
void ResetToAcceptingConnectionState();
base::ProcessId peer_pid() const { return peer_pid_; }
static bool IsNamedServerInitialized(const std::string& channel_id);
#if defined(OS_LINUX)
static void SetGlobalPid(int pid);
......@@ -144,7 +149,7 @@ class Channel::ChannelImpl : public internal::ChannelReader,
// For a server, the client end of our socketpair() -- the other end of our
// pipe_ that is passed to the client.
int client_pipe_;
base::Lock client_pipe_lock_; // Lock that protects |client_pipe_|.
mutable base::Lock client_pipe_lock_; // Lock that protects |client_pipe_|.
#if defined(IPC_USES_READWRITE)
// Linux/BSD use a dedicated socketpair() for passing file descriptors.
......@@ -202,7 +207,7 @@ class Channel::ChannelImpl : public internal::ChannelReader,
static int global_pid_;
#endif // OS_LINUX
DISALLOW_IMPLICIT_CONSTRUCTORS(ChannelImpl);
DISALLOW_IMPLICIT_CONSTRUCTORS(ChannelPosix);
};
} // namespace IPC
......
......@@ -245,7 +245,8 @@ TEST_F(IPCChannelPosixTest, SendHangTest) {
IPC::ChannelHandle in_handle("IN");
scoped_ptr<IPC::Channel> in_chan(
IPC::Channel::CreateServer(in_handle, &in_listener));
base::FileDescriptor out_fd(in_chan->TakeClientFileDescriptor(), false);
base::FileDescriptor out_fd(
in_chan->TakeClientFileDescriptor(), false);
IPC::ChannelHandle out_handle("OUT", out_fd);
scoped_ptr<IPC::Channel> out_chan(
IPC::Channel::CreateClient(out_handle, &out_listener));
......@@ -270,7 +271,8 @@ TEST_F(IPCChannelPosixTest, AcceptHangTest) {
IPC::ChannelHandle in_handle("IN");
scoped_ptr<IPC::Channel> in_chan(
IPC::Channel::CreateServer(in_handle, &in_listener));
base::FileDescriptor out_fd(in_chan->TakeClientFileDescriptor(), false);
base::FileDescriptor out_fd(
in_chan->TakeClientFileDescriptor(), false);
IPC::ChannelHandle out_handle("OUT", out_fd);
scoped_ptr<IPC::Channel> out_chan(
IPC::Channel::CreateClient(out_handle, &out_listener));
......@@ -423,7 +425,7 @@ TEST_F(IPCChannelPosixTest, BadMode) {
// Test setting up two servers with a bad mode.
IPCChannelPosixTestListener listener(false);
IPC::ChannelHandle chan_handle(GetConnectionSocketName());
scoped_ptr<IPC::Channel> channel(IPC::Channel::CreateByModeForProxy(
scoped_ptr<IPC::Channel> channel(IPC::Channel::Create(
chan_handle, IPC::Channel::MODE_NONE, &listener));
ASSERT_FALSE(channel->Connect());
}
......
......@@ -52,7 +52,7 @@ void ChannelProxy::Context::CreateChannel(const IPC::ChannelHandle& handle,
const Channel::Mode& mode) {
DCHECK(!channel_);
channel_id_ = handle.name;
channel_ = Channel::CreateByModeForProxy(handle, mode, this);
channel_ = Channel::Create(handle, mode, this);
}
bool ChannelProxy::Context::TryFilters(const Message& message) {
......@@ -95,7 +95,7 @@ bool ChannelProxy::Context::OnMessageReceivedNoFilter(const Message& message) {
// Called on the IPC::Channel thread
void ChannelProxy::Context::OnChannelConnected(int32 peer_pid) {
// We cache off the peer_pid so it can be safely accessed from both threads.
peer_pid_ = channel_->peer_pid();
peer_pid_ = channel_->GetPeerPID();
// Add any pending filters. This avoids a race condition where someone
// creates a ChannelProxy, calls AddFilter, and then right after starts the
......
......@@ -110,7 +110,7 @@ class IPC_EXPORT ChannelProxy : public Sender, public base::NonThreadSafe {
// Get the process ID for the connected peer.
// Returns base::kNullProcessId if the peer is not connected yet.
base::ProcessId peer_pid() const { return context_->peer_pid_; }
base::ProcessId GetPeerPID() const { return context_->peer_pid_; }
#if defined(OS_POSIX) && !defined(OS_NACL)
// Calls through to the underlying channel's methods.
......
......@@ -23,17 +23,17 @@
namespace IPC {
Channel::ChannelImpl::State::State(ChannelImpl* channel) : is_pending(false) {
ChannelWin::State::State(ChannelWin* channel) : is_pending(false) {
memset(&context.overlapped, 0, sizeof(context.overlapped));
context.handler = channel;
}
Channel::ChannelImpl::State::~State() {
COMPILE_ASSERT(!offsetof(Channel::ChannelImpl::State, context),
ChannelWin::State::~State() {
COMPILE_ASSERT(!offsetof(ChannelWin::State, context),
starts_with_io_context);
}
Channel::ChannelImpl::ChannelImpl(const IPC::ChannelHandle &channel_handle,
ChannelWin::ChannelWin(const IPC::ChannelHandle &channel_handle,
Mode mode, Listener* listener)
: ChannelReader(listener),
input_state_(this),
......@@ -48,11 +48,11 @@ Channel::ChannelImpl::ChannelImpl(const IPC::ChannelHandle &channel_handle,
CreatePipe(channel_handle, mode);
}
Channel::ChannelImpl::~ChannelImpl() {
ChannelWin::~ChannelWin() {
Close();
}
void Channel::ChannelImpl::Close() {
void ChannelWin::Close() {
if (thread_check_.get()) {
DCHECK(thread_check_->CalledOnValidThread());
}
......@@ -80,7 +80,7 @@ void Channel::ChannelImpl::Close() {
}
}
bool Channel::ChannelImpl::Send(Message* message) {
bool ChannelWin::Send(Message* message) {
DCHECK(thread_check_->CalledOnValidThread());
DVLOG(2) << "sending message @" << message << " on channel @" << this
<< " with type " << message->type()
......@@ -103,8 +103,12 @@ bool Channel::ChannelImpl::Send(Message* message) {
return true;
}
base::ProcessId ChannelWin::GetPeerPID() const {
return peer_pid_;
}
// static
bool Channel::ChannelImpl::IsNamedServerInitialized(
bool ChannelWin::IsNamedServerInitialized(
const std::string& channel_id) {
if (WaitNamedPipe(PipeName(channel_id, NULL).c_str(), 1))
return true;
......@@ -113,7 +117,7 @@ bool Channel::ChannelImpl::IsNamedServerInitialized(
return GetLastError() == ERROR_SEM_TIMEOUT;
}
Channel::ChannelImpl::ReadState Channel::ChannelImpl::ReadData(
ChannelWin::ReadState ChannelWin::ReadData(
char* buffer,
int buffer_len,
int* /* bytes_read */) {
......@@ -145,14 +149,14 @@ Channel::ChannelImpl::ReadState Channel::ChannelImpl::ReadData(
return READ_PENDING;
}
bool Channel::ChannelImpl::WillDispatchInputMessage(Message* msg) {
bool ChannelWin::WillDispatchInputMessage(Message* msg) {
// Make sure we get a hello when client validation is required.
if (validate_client_)
return IsHelloMessage(*msg);
return true;
}
void Channel::ChannelImpl::HandleInternalMessage(const Message& msg) {
void ChannelWin::HandleInternalMessage(const Message& msg) {
DCHECK_EQ(msg.type(), static_cast<unsigned>(Channel::HELLO_MESSAGE_TYPE));
// The hello message contains one parameter containing the PID.
PickleIterator it(msg);
......@@ -177,13 +181,13 @@ void Channel::ChannelImpl::HandleInternalMessage(const Message& msg) {
listener()->OnChannelConnected(claimed_pid);
}
bool Channel::ChannelImpl::DidEmptyInputBuffers() {
bool ChannelWin::DidEmptyInputBuffers() {
// We don't need to do anything here.
return true;
}
// static
const base::string16 Channel::ChannelImpl::PipeName(
const base::string16 ChannelWin::PipeName(
const std::string& channel_id, int32* secret) {
std::string name("\\\\.\\pipe\\chrome.");
......@@ -201,7 +205,7 @@ const base::string16 Channel::ChannelImpl::PipeName(
return base::ASCIIToWide(name.append(channel_id));
}
bool Channel::ChannelImpl::CreatePipe(const IPC::ChannelHandle &channel_handle,
bool ChannelWin::CreatePipe(const IPC::ChannelHandle &channel_handle,
Mode mode) {
DCHECK_EQ(INVALID_HANDLE_VALUE, pipe_);
base::string16 pipe_name;
......@@ -286,7 +290,7 @@ bool Channel::ChannelImpl::CreatePipe(const IPC::ChannelHandle &channel_handle,
return true;
}
bool Channel::ChannelImpl::Connect() {
bool ChannelWin::Connect() {
DLOG_IF(WARNING, thread_check_.get()) << "Connect called more than once";
if (!thread_check_.get())
......@@ -307,7 +311,7 @@ bool Channel::ChannelImpl::Connect() {
// initialization signal.
base::MessageLoopForIO::current()->PostTask(
FROM_HERE,
base::Bind(&Channel::ChannelImpl::OnIOCompleted,
base::Bind(&ChannelWin::OnIOCompleted,
weak_factory_.GetWeakPtr(),
&input_state_.context,
0,
......@@ -319,7 +323,7 @@ bool Channel::ChannelImpl::Connect() {
return true;
}
bool Channel::ChannelImpl::ProcessConnection() {
bool ChannelWin::ProcessConnection() {
DCHECK(thread_check_->CalledOnValidThread());
if (input_state_.is_pending)
input_state_.is_pending = false;
......@@ -356,7 +360,7 @@ bool Channel::ChannelImpl::ProcessConnection() {
return true;
}
bool Channel::ChannelImpl::ProcessOutgoingMessages(
bool ChannelWin::ProcessOutgoingMessages(
base::MessageLoopForIO::IOContext* context,
DWORD bytes_written) {
DCHECK(!waiting_connect_); // Why are we trying to send messages if there's
......@@ -413,7 +417,7 @@ bool Channel::ChannelImpl::ProcessOutgoingMessages(
return true;
}
void Channel::ChannelImpl::OnIOCompleted(
void ChannelWin::OnIOCompleted(
base::MessageLoopForIO::IOContext* context,
DWORD bytes_transfered,
DWORD error) {
......@@ -463,36 +467,18 @@ void Channel::ChannelImpl::OnIOCompleted(
}
//------------------------------------------------------------------------------
// Channel's methods simply call through to ChannelImpl.
Channel::Channel(const IPC::ChannelHandle &channel_handle, Mode mode,
Listener* listener)
: channel_impl_(new ChannelImpl(channel_handle, mode, listener)) {
}
Channel::~Channel() {
delete channel_impl_;
}
bool Channel::Connect() {
return channel_impl_->Connect();
}
void Channel::Close() {
if (channel_impl_)
channel_impl_->Close();
}
// Channel's methods
base::ProcessId Channel::peer_pid() const {
return channel_impl_->peer_pid();
}
bool Channel::Send(Message* message) {
return channel_impl_->Send(message);
// static
scoped_ptr<Channel> Channel::Create(
const IPC::ChannelHandle &channel_handle, Mode mode, Listener* listener) {
return scoped_ptr<Channel>(
new ChannelWin(channel_handle, mode, listener));
}
// static
bool Channel::IsNamedServerInitialized(const std::string& channel_id) {
return ChannelImpl::IsNamedServerInitialized(channel_id);
return ChannelWin::IsNamedServerInitialized(channel_id);
}
// static
......
......@@ -21,18 +21,23 @@ class ThreadChecker;
namespace IPC {
class Channel::ChannelImpl : public internal::ChannelReader,
public base::MessageLoopForIO::IOHandler {
class ChannelWin : public Channel,
public internal::ChannelReader,
public base::MessageLoopForIO::IOHandler {
public:
// Mirror methods of Channel, see ipc_channel.h for description.
ChannelImpl(const IPC::ChannelHandle &channel_handle, Mode mode,
Listener* listener);
~ChannelImpl();
bool Connect();
void Close();
bool Send(Message* message);
ChannelWin(const IPC::ChannelHandle &channel_handle, Mode mode,
Listener* listener);
~ChannelWin();
// Channel implementation
virtual bool Connect() OVERRIDE;
virtual void Close() OVERRIDE;
virtual bool Send(Message* message) OVERRIDE;
virtual base::ProcessId GetPeerPID() const OVERRIDE;
static bool IsNamedServerInitialized(const std::string& channel_id);
base::ProcessId peer_pid() const { return peer_pid_; }
private:
// ChannelReader implementation.
......@@ -58,7 +63,7 @@ class Channel::ChannelImpl : public internal::ChannelReader,
private:
struct State {
explicit State(ChannelImpl* channel);
explicit State(ChannelWin* channel);
~State();
base::MessageLoopForIO::IOContext context;
bool is_pending;
......@@ -94,11 +99,11 @@ class Channel::ChannelImpl : public internal::ChannelReader,
int32 client_secret_;
base::WeakPtrFactory<ChannelImpl> weak_factory_;
base::WeakPtrFactory<ChannelWin> weak_factory_;
scoped_ptr<base::ThreadChecker> thread_check_;
DISALLOW_COPY_AND_ASSIGN(ChannelImpl);
DISALLOW_COPY_AND_ASSIGN(ChannelWin);
};
} // namespace IPC
......
......@@ -222,6 +222,9 @@ class IPC_EXPORT Message : public Pickle {
protected:
friend class Channel;
friend class ChannelNacl;
friend class ChannelPosix;
friend class ChannelWin;
friend class MessageReplyDeserializer;
friend class SyncMessage;
......
......@@ -234,7 +234,8 @@ class PipeChannelHelper {
void Init() {
IPC::ChannelHandle in_handle("IN");
in = IPC::Channel::CreateServer(in_handle, &null_listener_);
base::FileDescriptor out_fd(in->TakeClientFileDescriptor(), false);
base::FileDescriptor out_fd(
in->TakeClientFileDescriptor(), false);
IPC::ChannelHandle out_handle("OUT", out_fd);
out = IPC::Channel::CreateClient(out_handle, &cb_listener_);
// PostTask the connect calls to make sure the callbacks happens
......
......@@ -1722,7 +1722,7 @@ class VerifiedServer : public Worker {
VLOG(1) << __FUNCTION__ << " Sending reply: " << reply_text_;
SyncChannelNestedTestMsg_String::WriteReplyParams(reply_msg, reply_text_);
Send(reply_msg);
ASSERT_EQ(channel()->peer_pid(), base::GetCurrentProcId());
ASSERT_EQ(channel()->GetPeerPID(), base::GetCurrentProcId());
Done();
}
......@@ -1751,7 +1751,7 @@ class VerifiedClient : public Worker {
(void)expected_text_;
VLOG(1) << __FUNCTION__ << " Received reply: " << response;
ASSERT_EQ(channel()->peer_pid(), base::GetCurrentProcId());
ASSERT_EQ(channel()->GetPeerPID(), base::GetCurrentProcId());
Done();
}
......
......@@ -97,8 +97,9 @@ bool IPCTestBase::StartClient() {
client_process_ = SpawnChild(test_main);
#elif defined(OS_POSIX)
base::FileHandleMappingVector fds_to_map;
const int ipcfd = channel_.get() ? channel_->GetClientFileDescriptor() :
channel_proxy_->GetClientFileDescriptor();
const int ipcfd = channel_.get()
? channel_->GetClientFileDescriptor()
: channel_proxy_->GetClientFileDescriptor();
if (ipcfd > -1)
fds_to_map.push_back(std::pair<int, int>(ipcfd,
kPrimaryIPCChannel + base::GlobalDescriptors::kBaseDescriptor));
......
......@@ -21,6 +21,21 @@ bool TestSink::Send(Message* message) {
return true;
}
bool TestSink::Connect() {
NOTIMPLEMENTED();
return false;
}
void TestSink::Close() {
NOTIMPLEMENTED();
}
base::ProcessId TestSink::GetPeerPID() const {
NOTIMPLEMENTED();
return base::ProcessId();
}
bool TestSink::OnMessageReceived(const Message& msg) {
ObserverListBase<Listener>::Iterator it(filter_list_);
Listener* observer;
......@@ -74,4 +89,37 @@ void TestSink::RemoveFilter(Listener* filter) {
filter_list_.RemoveObserver(filter);
}
#if defined(OS_POSIX) && !defined(OS_NACL)
int TestSink::GetClientFileDescriptor() const {
NOTREACHED();
return -1;
}
int TestSink::TakeClientFileDescriptor() {
NOTREACHED();
return -1;
}
bool TestSink::AcceptsConnections() const {
NOTREACHED();
return false;
}
bool TestSink::HasAcceptedConnection() const {
NOTREACHED();
return false;
}
bool TestSink::GetPeerEuid(uid_t* peer_euid) const {
NOTREACHED();
return false;
}
void TestSink::ResetToAcceptingConnectionState() {
NOTREACHED();
}
#endif // defined(OS_POSIX) && !defined(OS_NACL)
} // namespace IPC
......@@ -78,6 +78,18 @@ class TestSink : public Channel {
// Interface in IPC::Channel. This copies the message to the sink and then
// deletes it.
virtual bool Send(IPC::Message* message) OVERRIDE;
virtual bool Connect() WARN_UNUSED_RESULT OVERRIDE;
virtual void Close() OVERRIDE;
virtual base::ProcessId GetPeerPID() const OVERRIDE;
#if defined(OS_POSIX) && !defined(OS_NACL)
virtual int GetClientFileDescriptor() const OVERRIDE;
virtual int TakeClientFileDescriptor() OVERRIDE;
virtual bool AcceptsConnections() const OVERRIDE;
virtual bool HasAcceptedConnection() const OVERRIDE;
virtual bool GetPeerEuid(uid_t* peer_euid) const OVERRIDE;
virtual void ResetToAcceptingConnectionState() OVERRIDE;
#endif // defined(OS_POSIX) && !defined(OS_NACL)
// Used by the source of the messages to send the message to the sink. This
// will make a copy of the message and store it in the list.
......
......@@ -85,13 +85,13 @@ MetroViewerProcessHost::~MetroViewerProcessHost() {
base::ProcessId MetroViewerProcessHost::GetViewerProcessId() {
if (channel_)
return channel_->peer_pid();
return channel_->GetPeerPID();
return base::kNullProcessId;
}
bool MetroViewerProcessHost::LaunchViewerAndWaitForConnection(
const base::string16& app_user_model_id) {
DCHECK_EQ(base::kNullProcessId, channel_->peer_pid());
DCHECK_EQ(base::kNullProcessId, channel_->GetPeerPID());
channel_connected_event_.reset(new base::WaitableEvent(false, false));
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment