OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #ifndef IPC_IPC_CHANNEL_NACL_H_ | 5 #ifndef IPC_IPC_CHANNEL_NACL_H_ |
6 #define IPC_IPC_CHANNEL_NACL_H_ | 6 #define IPC_IPC_CHANNEL_NACL_H_ |
7 #pragma once | 7 #pragma once |
8 | 8 |
9 #include <deque> | 9 #include <deque> |
10 #include <string> | 10 #include <string> |
11 | 11 |
12 #include "base/memory/linked_ptr.h" | 12 #include "base/memory/linked_ptr.h" |
13 #include "base/memory/scoped_ptr.h" | 13 #include "base/memory/scoped_ptr.h" |
14 #include "base/memory/weak_ptr.h" | 14 #include "base/memory/weak_ptr.h" |
15 #include "base/process.h" | 15 #include "base/process.h" |
16 #include "base/threading/simple_thread.h" | 16 #include "base/threading/simple_thread.h" |
17 #include "ipc/ipc_channel.h" | 17 #include "ipc/ipc_channel.h" |
18 #include "ipc/ipc_channel_reader.h" | 18 #include "ipc/ipc_channel_reader.h" |
19 | 19 |
20 namespace IPC { | 20 namespace IPC { |
21 | 21 |
| 22 // Contains the results from one call to imc_recvmsg (data and file |
| 23 // descriptors). |
| 24 struct MessageContents; |
| 25 |
22 // Similar to the Posix version of ChannelImpl but for Native Client code. | 26 // Similar to the Posix version of ChannelImpl but for Native Client code. |
23 // This is somewhat different because sendmsg/recvmsg here do not follow POSIX | 27 // This is somewhat different because sendmsg/recvmsg here do not follow POSIX |
24 // semantics. Instead, they are implemented by a custom embedding of | 28 // semantics. Instead, they are implemented by a custom embedding of |
25 // NaClDescCustom. See NaClIPCAdapter for the trusted-side implementation. | 29 // NaClDescCustom. See NaClIPCAdapter for the trusted-side implementation. |
26 // | 30 // |
27 // We don't need to worry about complicated set up and READWRITE mode for | 31 // We don't need to worry about complicated set up and READWRITE mode for |
28 // sharing handles. We also currently do not support passing file descriptors or | 32 // sharing handles. We also currently do not support passing file descriptors or |
29 // named pipes, and we use background threads to emulate signaling when we can | 33 // named pipes, and we use background threads to emulate signaling when we can |
30 // read or write without blocking. | 34 // read or write without blocking. |
31 class Channel::ChannelImpl : public internal::ChannelReader { | 35 class Channel::ChannelImpl : public internal::ChannelReader { |
32 public: | 36 public: |
33 // Mirror methods of Channel, see ipc_channel.h for description. | 37 // Mirror methods of Channel, see ipc_channel.h for description. |
34 ChannelImpl(const IPC::ChannelHandle& channel_handle, | 38 ChannelImpl(const IPC::ChannelHandle& channel_handle, |
35 Mode mode, | 39 Mode mode, |
36 Listener* listener); | 40 Listener* listener); |
37 virtual ~ChannelImpl(); | 41 virtual ~ChannelImpl(); |
38 | 42 |
39 // Channel implementation. | 43 // Channel implementation. |
40 bool Connect(); | 44 bool Connect(); |
41 void Close(); | 45 void Close(); |
42 bool Send(Message* message); | 46 bool Send(Message* message); |
43 | 47 |
44 // Posted to the main thread by ReaderThreadRunner. | 48 // Posted to the main thread by ReaderThreadRunner. |
45 void DidRecvMsg(scoped_ptr<std::vector<char> > buffer); | 49 void DidRecvMsg(scoped_ptr<MessageContents> contents); |
46 void ReadDidFail(); | 50 void ReadDidFail(); |
47 | 51 |
48 private: | 52 private: |
49 class ReaderThreadRunner; | 53 class ReaderThreadRunner; |
50 | 54 |
51 bool CreatePipe(const IPC::ChannelHandle& channel_handle); | 55 bool CreatePipe(const IPC::ChannelHandle& channel_handle); |
52 bool ProcessOutgoingMessages(); | 56 bool ProcessOutgoingMessages(); |
53 | 57 |
54 // ChannelReader implementation. | 58 // ChannelReader implementation. |
55 virtual ReadState ReadData(char* buffer, | 59 virtual ReadState ReadData(char* buffer, |
(...skipping 21 matching lines...) Expand all Loading... |
77 // | 81 // |
78 // imc_recvmsg supports non-blocking reads, but there's no easy way to be | 82 // imc_recvmsg supports non-blocking reads, but there's no easy way to be |
79 // informed when a write or read can be done without blocking (this is handled | 83 // informed when a write or read can be done without blocking (this is handled |
80 // by libevent in Posix). | 84 // by libevent in Posix). |
81 scoped_ptr<ReaderThreadRunner> reader_thread_runner_; | 85 scoped_ptr<ReaderThreadRunner> reader_thread_runner_; |
82 scoped_ptr<base::DelegateSimpleThread> reader_thread_; | 86 scoped_ptr<base::DelegateSimpleThread> reader_thread_; |
83 | 87 |
84 // IPC::ChannelReader expects to be able to call ReadData on us to | 88 // IPC::ChannelReader expects to be able to call ReadData on us to |
85 // synchronously read data waiting in the pipe's buffer without blocking. | 89 // synchronously read data waiting in the pipe's buffer without blocking. |
86 // Since we can't do that (see 1 and 2 above), the reader thread does blocking | 90 // Since we can't do that (see 1 and 2 above), the reader thread does blocking |
87 // reads and posts the data over to the main thread in byte vectors. Each byte | 91 // reads and posts the data over to the main thread in MessageContents. Each |
88 // vector is the result of one call to "recvmsg". When ReadData is called, it | 92 // MessageContents object is the result of one call to "imc_recvmsg". |
89 // pulls the bytes out of these vectors in order. | 93 // DidRecvMsg breaks the MessageContents out in to the data and the file |
| 94 // descriptors, and puts them on these two queues. |
90 // TODO(dmichael): There's probably a more efficient way to emulate this with | 95 // TODO(dmichael): There's probably a more efficient way to emulate this with |
91 // a circular buffer or something, so we don't have to do so | 96 // a circular buffer or something, so we don't have to do so |
92 // many heap allocations. But it maybe isn't worth | 97 // many heap allocations. But it maybe isn't worth |
93 // the trouble given that we probably want to implement 1 and | 98 // the trouble given that we probably want to implement 1 and |
94 // 2 above in NaCl eventually. | 99 // 2 above in NaCl eventually. |
| 100 // When ReadData is called, it pulls the bytes out of this queue in order. |
95 std::deque<linked_ptr<std::vector<char> > > read_queue_; | 101 std::deque<linked_ptr<std::vector<char> > > read_queue_; |
| 102 // Queue of file descriptors extracted from imc_recvmsg messages. |
| 103 // NOTE: The implementation assumes underlying storage here is contiguous, so |
| 104 // don't change to something like std::deque<> without changing the |
| 105 // implementation! |
| 106 std::vector<int> input_fds_; |
96 | 107 |
97 // This queue is used when a message is sent prior to Connect having been | 108 // This queue is used when a message is sent prior to Connect having been |
98 // called. Normally after we're connected, the queue is empty. | 109 // called. Normally after we're connected, the queue is empty. |
99 std::deque<linked_ptr<Message> > output_queue_; | 110 std::deque<linked_ptr<Message> > output_queue_; |
100 | 111 |
101 base::WeakPtrFactory<ChannelImpl> weak_ptr_factory_; | 112 base::WeakPtrFactory<ChannelImpl> weak_ptr_factory_; |
102 | 113 |
103 DISALLOW_IMPLICIT_CONSTRUCTORS(ChannelImpl); | 114 DISALLOW_IMPLICIT_CONSTRUCTORS(ChannelImpl); |
104 }; | 115 }; |
105 | 116 |
106 } // namespace IPC | 117 } // namespace IPC |
107 | 118 |
108 #endif // IPC_IPC_CHANNEL_NACL_H_ | 119 #endif // IPC_IPC_CHANNEL_NACL_H_ |
OLD | NEW |