Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(285)

Unified Diff: ipc/ipc_channel_nacl.h

Issue 10174048: PPAPI/NaCl: Speculative implementation for ipc_channel_nacl.cc (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: eliminate writer thread, make reading loop tighter Created 8 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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);
};

Powered by Google App Engine
This is Rietveld 408576698