app_list: Change touch drag start delay to 200ms.
[chromium-blink-merge.git] / chrome / nacl / nacl_ipc_adapter.h
blob5b323e308efcac37d0710d12abc213725cab0cc8
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #ifndef CHROME_NACL_NACL_IPC_ADAPTER_H_
6 #define CHROME_NACL_NACL_IPC_ADAPTER_H_
8 #include <map>
9 #include <queue>
10 #include <string>
12 #include "base/basictypes.h"
13 #include "base/memory/ref_counted.h"
14 #include "base/memory/scoped_ptr.h"
15 #include "base/memory/scoped_vector.h"
16 #include "base/shared_memory.h"
17 #include "base/synchronization/condition_variable.h"
18 #include "base/synchronization/lock.h"
19 #include "base/task_runner.h"
20 #include "ipc/ipc_channel.h"
21 #include "ipc/ipc_message.h"
23 struct NaClDesc;
24 struct NaClImcTypedMsgHdr;
25 struct PP_Size;
27 namespace IPC {
28 class Message;
31 namespace nacl {
32 class DescWrapper;
35 namespace ppapi {
36 class HostResource;
39 // Adapts a Chrome IPC channel to an IPC channel that we expose to Native
40 // Client. This provides a mapping in both directions, so when IPC messages
41 // come in from another process, we rewrite them and allow them to be received
42 // via a recvmsg-like interface in the NaCl code. When NaCl code calls sendmsg,
43 // we implement that as sending IPC messages on the channel.
45 // This object also provides the necessary logic for rewriting IPC messages.
46 // NaCl code is platform-independent and runs in a Posix-like enviroment, but
47 // some formatting in the message and the way handles are transferred varies
48 // by platform. This class bridges that gap to provide what looks like a
49 // normal platform-specific IPC implementation to Chrome, and a Posix-like
50 // version on every platform to NaCl.
52 // This object must be threadsafe since the nacl environment determines which
53 // thread every function is called on.
54 class NaClIPCAdapter : public base::RefCountedThreadSafe<NaClIPCAdapter>,
55 public IPC::Listener {
56 public:
57 // Chrome's IPC message format varies by platform, NaCl's does not. In
58 // particular, the header has some extra fields on Posix platforms. Since
59 // NaCl is a Posix environment, it gets that version of the header. This
60 // header is duplicated here so we have a cross-platform definition of the
61 // header we're exposing to NaCl.
62 #pragma pack(push, 4)
63 struct NaClMessageHeader : public Pickle::Header {
64 int32 routing;
65 uint32 type;
66 uint32 flags;
67 uint16 num_fds;
68 uint16 pad;
70 #pragma pack(pop)
72 // Creates an adapter, using the thread associated with the given task
73 // runner for posting messages. In normal use, the task runner will post to
74 // the I/O thread of the process.
75 NaClIPCAdapter(const IPC::ChannelHandle& handle, base::TaskRunner* runner);
77 // Initializes with a given channel that's already created for testing
78 // purposes. This function will take ownership of the given channel.
79 NaClIPCAdapter(scoped_ptr<IPC::Channel> channel, base::TaskRunner* runner);
81 // Implementation of sendmsg. Returns the number of bytes written or -1 on
82 // failure.
83 int Send(const NaClImcTypedMsgHdr* msg);
85 // Implementation of recvmsg. Returns the number of bytes read or -1 on
86 // failure. This will block until there's an error or there is data to
87 // read.
88 int BlockingReceive(NaClImcTypedMsgHdr* msg);
90 // Closes the IPC channel.
91 void CloseChannel();
93 // Make a NaClDesc that refers to this NaClIPCAdapter. Note that the returned
94 // NaClDesc is reference-counted, and a reference is returned.
95 NaClDesc* MakeNaClDesc();
97 #if defined(OS_POSIX)
98 int TakeClientFileDescriptor();
99 #endif
101 // Listener implementation.
102 virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE;
103 virtual void OnChannelConnected(int32 peer_pid) OVERRIDE;
104 virtual void OnChannelError() OVERRIDE;
106 private:
107 friend class base::RefCountedThreadSafe<NaClIPCAdapter>;
109 class RewrittenMessage;
111 // This is the data that must only be accessed inside the lock. This struct
112 // just separates it so it's easier to see.
113 struct LockedData {
114 LockedData();
115 ~LockedData();
117 // Messages that we have read off of the Chrome IPC channel that are waiting
118 // to be received by the plugin.
119 std::queue< scoped_refptr<RewrittenMessage> > to_be_received_;
121 // When we send a synchronous message (from untrusted to trusted), we store
122 // its type here, so that later we can associate the reply with its type
123 // and potentially translate handles in the message.
124 typedef std::map<int, uint32> PendingSyncMsgMap;
125 PendingSyncMsgMap pending_sync_msgs_;
127 // Data that we've queued from the plugin to send, but doesn't consist of a
128 // full message yet. The calling code can break apart the message into
129 // smaller pieces, and we need to send the message to the other process in
130 // one chunk.
132 // The IPC channel always starts a new send() at the beginning of each
133 // message, so we don't need to worry about arbitrary message boundaries.
134 std::string to_be_sent_;
136 bool channel_closed_;
139 // This is the data that must only be accessed on the I/O thread (as defined
140 // by TaskRunner). This struct just separates it so it's easier to see.
141 struct IOThreadData {
142 IOThreadData();
143 ~IOThreadData();
145 scoped_ptr<IPC::Channel> channel_;
148 virtual ~NaClIPCAdapter();
150 // Returns 0 if nothing is waiting.
151 int LockedReceive(NaClImcTypedMsgHdr* msg);
153 // Sends a message that we know has been completed to the Chrome process.
154 bool SendCompleteMessage(const char* buffer, size_t buffer_len);
156 // Clears the LockedData.to_be_sent_ structure in a way to make sure that
157 // the memory is deleted. std::string can sometimes hold onto the buffer
158 // for future use which we don't want.
159 void ClearToBeSent();
161 void ConnectChannelOnIOThread();
162 void CloseChannelOnIOThread();
163 void SendMessageOnIOThread(scoped_ptr<IPC::Message> message);
165 // Saves the message to forward to NaCl. This method assumes that the caller
166 // holds the lock for locked_data_.
167 void SaveMessage(const IPC::Message& message,
168 RewrittenMessage* rewritten_message);
170 base::Lock lock_;
171 base::ConditionVariable cond_var_;
173 scoped_refptr<base::TaskRunner> task_runner_;
175 // To be accessed inside of lock_ only.
176 LockedData locked_data_;
178 // To be accessed on the I/O thread (via task runner) only.
179 IOThreadData io_thread_data_;
181 DISALLOW_COPY_AND_ASSIGN(NaClIPCAdapter);
184 #endif // CHROME_NACL_NACL_IPC_ADAPTER_H_