15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef IPC_IPC_CHANNEL_NACL_H_ 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define IPC_IPC_CHANNEL_NACL_H_ 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <deque> 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string> 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/linked_ptr.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_ptr.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/weak_ptr.h" 14a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch#include "base/process/process.h" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/threading/simple_thread.h" 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ipc/ipc_channel.h" 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ipc/ipc_channel_reader.h" 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace IPC { 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Contains the results from one call to imc_recvmsg (data and file 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// descriptors). 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct MessageContents; 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Similar to the Posix version of ChannelImpl but for Native Client code. 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This is somewhat different because sendmsg/recvmsg here do not follow POSIX 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// semantics. Instead, they are implemented by a custom embedding of 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// NaClDescCustom. See NaClIPCAdapter for the trusted-side implementation. 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// We don't need to worry about complicated set up and READWRITE mode for 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// sharing handles. We also currently do not support passing file descriptors or 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// named pipes, and we use background threads to emulate signaling when we can 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// read or write without blocking. 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class Channel::ChannelImpl : public internal::ChannelReader { 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Mirror methods of Channel, see ipc_channel.h for description. 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ChannelImpl(const IPC::ChannelHandle& channel_handle, 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Mode mode, 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Listener* listener); 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual ~ChannelImpl(); 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Channel implementation. 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool Connect(); 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void Close(); 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool Send(Message* message); 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Posted to the main thread by ReaderThreadRunner. 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void DidRecvMsg(scoped_ptr<MessageContents> contents); 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void ReadDidFail(); 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) class ReaderThreadRunner; 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool CreatePipe(const IPC::ChannelHandle& channel_handle); 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool ProcessOutgoingMessages(); 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // ChannelReader implementation. 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual ReadState ReadData(char* buffer, 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int buffer_len, 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int* bytes_read) OVERRIDE; 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual bool WillDispatchInputMessage(Message* msg) OVERRIDE; 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual bool DidEmptyInputBuffers() OVERRIDE; 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void HandleHelloMessage(const Message& msg) OVERRIDE; 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Mode mode_; 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool waiting_connect_; 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The pipe used for communication. 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int pipe_; 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The "name" of our pipe. On Windows this is the global identifier for 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the pipe. On POSIX it's used as a key in a local map of file descriptors. 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // For NaCl, we don't actually support looking up file descriptors by name, 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // and it's only used for debug information. 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string pipe_name_; 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We use a thread for reading, so that we can simply block on reading and 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // post the received data back to the main thread to be properly interleaved 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // with other tasks in the MessagePump. 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // imc_recvmsg supports non-blocking reads, but there's no easy way to be 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // informed when a write or read can be done without blocking (this is handled 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // by libevent in Posix). 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<ReaderThreadRunner> reader_thread_runner_; 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<base::DelegateSimpleThread> reader_thread_; 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // IPC::ChannelReader expects to be able to call ReadData on us to 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // synchronously read data waiting in the pipe's buffer without blocking. 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Since we can't do that (see 1 and 2 above), the reader thread does blocking 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // reads and posts the data over to the main thread in MessageContents. Each 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // MessageContents object is the result of one call to "imc_recvmsg". 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // DidRecvMsg breaks the MessageContents out in to the data and the file 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // descriptors, and puts them on these two queues. 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(dmichael): There's probably a more efficient way to emulate this with 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // a circular buffer or something, so we don't have to do so 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // many heap allocations. But it maybe isn't worth 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the trouble given that we probably want to implement 1 and 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 2 above in NaCl eventually. 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // When ReadData is called, it pulls the bytes out of this queue in order. 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::deque<linked_ptr<std::vector<char> > > read_queue_; 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Queue of file descriptors extracted from imc_recvmsg messages. 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // NOTE: The implementation assumes underlying storage here is contiguous, so 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // don't change to something like std::deque<> without changing the 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // implementation! 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<int> input_fds_; 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This queue is used when a message is sent prior to Connect having been 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // called. Normally after we're connected, the queue is empty. 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::deque<linked_ptr<Message> > output_queue_; 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::WeakPtrFactory<ChannelImpl> weak_ptr_factory_; 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DISALLOW_IMPLICIT_CONSTRUCTORS(ChannelImpl); 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace IPC 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif // IPC_IPC_CHANNEL_NACL_H_ 119