Chromium Code Reviews| Index: ipc/ipc_channel_nacl.h |
| diff --git a/ipc/ipc_channel_nacl.h b/ipc/ipc_channel_nacl.h |
| index 274726393e5b7be88c4a31eec4343d39154fcefd..62337a66eb8a9872202c5eb4b685ba7685fc4619 100644 |
| --- a/ipc/ipc_channel_nacl.h |
| +++ b/ipc/ipc_channel_nacl.h |
| @@ -6,6 +6,13 @@ |
| #define IPC_IPC_CHANNEL_NACL_H_ |
| #pragma once |
| +#include <deque> |
| +#include <string> |
| + |
| +#include "base/memory/linked_ptr.h" |
| +#include "base/memory/scoped_ptr.h" |
| +#include "base/memory/weak_ptr.h" |
| +#include "base/threading/simple_thread.h" |
| #include "ipc/ipc_channel.h" |
| #include "ipc/ipc_channel_reader.h" |
| @@ -14,9 +21,12 @@ namespace IPC { |
| // Similar to the Posix version of ChannelImpl but for Native Client code. |
| // This is somewhat different because NaCl's send/recvmsg is slightly different |
| // and we don't need to worry about complicated set up and READWRITE mode for |
| -// sharing handles. |
| +// 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 { |
| public: |
| + // Mirror methods of Channel, see ipc_channel.h for description. |
| ChannelImpl(const IPC::ChannelHandle& channel_handle, |
| Mode mode, |
| Listener* listener); |
| @@ -26,14 +36,20 @@ class Channel::ChannelImpl : public internal::ChannelReader { |
| bool Connect(); |
| void Close(); |
| bool Send(Message* message); |
| - int GetClientFileDescriptor() const; |
| - int TakeClientFileDescriptor(); |
| - bool AcceptsConnections() const; |
| - bool HasAcceptedConnection() const; |
| - bool GetClientEuid(uid_t* client_euid) const; |
| - void ResetToAcceptingConnectionState(); |
| - static bool IsNamedServerInitialized(const std::string& channel_id); |
| + // Posted to the main thread by ReaderThreadRunner. |
| + void DidRecvMsg(scoped_ptr<std::vector<char> > buffer); |
| + void ReadDidFail(); |
| + |
| + private: |
| + class ReaderThreadRunner; |
| + |
| + bool CreatePipe(const IPC::ChannelHandle& channel_handle); |
| + bool ProcessOutgoingMessages(); |
| + int GetHelloMessageProcId(); |
| + void QueueHelloMessage(); |
| + |
| + // ChannelReader implementation. |
| virtual ReadState ReadData(char* buffer, |
| int buffer_len, |
| int* bytes_read) OVERRIDE; |
| @@ -41,7 +57,47 @@ class Channel::ChannelImpl : public internal::ChannelReader { |
| virtual bool DidEmptyInputBuffers() OVERRIDE; |
| virtual void HandleHelloMessage(const Message& msg) OVERRIDE; |
| - private: |
| + Mode mode_; |
| + base::ProcessId peer_pid_; |
| + bool waiting_connect_; |
| + |
| + // The pipe used for communication. |
| + int pipe_; |
| + |
| + // The "name" of our pipe. On Windows this is the global identifier for |
| + // the pipe. On POSIX it's used as a key in a local map of file descriptors. |
| + // For NaCl, we don't actually support looking up file descriptors by name, |
| + // and it's only used for debug information. |
| + std::string pipe_name_; |
| + |
| + // We use a thread for reading, so that we can simply block on reading and |
| + // post the received data back to the main thread to be properly interleaved |
| + // with other tasks in the MessagePump. |
| + // |
| + // imc_recvmsg supports non-blocking reads, but there's no easy way to be |
| + // informed when a write or read can be done without blocking (this is handled |
| + // by libevent in Posix). |
| + scoped_ptr<ReaderThreadRunner> reader_thread_runner_; |
| + scoped_ptr<base::DelegateSimpleThread> reader_thread_; |
| + // IPC::ChannelReader expects to be able to call ReadData on us to |
|
brettw
2012/05/01 22:29:48
Blank line before this.
|
| + // synchronously read data waiting in the pipe's buffer without blocking. |
| + // Since we can't do that (see 1 and 2 above), the reader thread does blocking |
| + // reads and posts the data over to the main thread in byte vectors. Each byte |
| + // vector is the result of one call to "recvmsg". When ReadData is called, it |
| + // pulls the bytes out of these vectors in order. |
| + // TODO(dmichael): There's probably a more efficient way to emulate this with |
| + // a circular buffer or something, so we don't have to do so |
| + // many heap allocations. But it maybe isn't worth |
| + // the trouble given that we probably want to implement 1 and |
| + // 2 above in NaCl eventually. |
| + std::deque<linked_ptr<std::vector<char> > > read_queue_; |
| + |
| + // This queue is used when a message is sent prior to Connect having been |
| + // called. Normally after we're connected, the queue is empty. |
| + std::deque<linked_ptr<Message> > output_queue_; |
| + |
| + base::WeakPtrFactory<ChannelImpl> weak_ptr_factory_; |
| + |
| DISALLOW_IMPLICIT_CONSTRUCTORS(ChannelImpl); |
| }; |