1/* 2 * Copyright (C) 2012 Apple Inc. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 1. Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * 2. Redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution. 12 * 13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' 14 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 15 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS 17 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 18 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 19 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 20 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 21 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 22 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 23 * THE POSSIBILITY OF SUCH DAMAGE. 24 */ 25 26#ifndef ChildProcessProxy_h 27#define ChildProcessProxy_h 28 29#include "Connection.h" 30#include "MessageReceiverMap.h" 31#include "ProcessLauncher.h" 32 33#include <wtf/ThreadSafeRefCounted.h> 34 35namespace WebKit { 36 37class ChildProcessProxy : ProcessLauncher::Client, public IPC::Connection::Client, public ThreadSafeRefCounted<ChildProcessProxy> { 38 WTF_MAKE_NONCOPYABLE(ChildProcessProxy); 39 40public: 41 ChildProcessProxy(); 42 virtual ~ChildProcessProxy(); 43 44 // FIXME: This function does an unchecked upcast, and it is only used in a deprecated code path. Would like to get rid of it. 45 static ChildProcessProxy* fromConnection(IPC::Connection*); 46 47 void connect(); 48 void terminate(); 49 50 template<typename T> bool send(T&& message, uint64_t destinationID, unsigned messageSendFlags = 0); 51 template<typename T> bool sendSync(T&& message, typename T::Reply&&, uint64_t destinationID, std::chrono::milliseconds timeout = std::chrono::seconds(1)); 52 53 IPC::Connection* connection() const 54 { 55 ASSERT(m_connection); 56 return m_connection.get(); 57 } 58 59 void addMessageReceiver(IPC::StringReference messageReceiverName, IPC::MessageReceiver&); 60 void addMessageReceiver(IPC::StringReference messageReceiverName, uint64_t destinationID, IPC::MessageReceiver&); 61 void removeMessageReceiver(IPC::StringReference messageReceiverName, uint64_t destinationID); 62 63 enum class State { 64 Launching, 65 Running, 66 Terminated, 67 }; 68 State state() const; 69 70 PlatformProcessIdentifier processIdentifier() const { return m_processLauncher->processIdentifier(); } 71 72 bool canSendMessage() const { return state() != State::Terminated;} 73 bool sendMessage(std::unique_ptr<IPC::MessageEncoder>, unsigned messageSendFlags); 74 75protected: 76 void clearConnection(); 77 void abortProcessLaunchIfNeeded(); 78 79 // ProcessLauncher::Client 80 virtual void didFinishLaunching(ProcessLauncher*, IPC::Connection::Identifier) override; 81 82 bool dispatchMessage(IPC::Connection*, IPC::MessageDecoder&); 83 bool dispatchSyncMessage(IPC::Connection*, IPC::MessageDecoder&, std::unique_ptr<IPC::MessageEncoder>&); 84 85private: 86 virtual void getLaunchOptions(ProcessLauncher::LaunchOptions&) = 0; 87 virtual void connectionWillOpen(IPC::Connection*); 88 virtual void connectionWillClose(IPC::Connection*); 89 90 Vector<std::pair<std::unique_ptr<IPC::MessageEncoder>, unsigned>> m_pendingMessages; 91 RefPtr<ProcessLauncher> m_processLauncher; 92 RefPtr<IPC::Connection> m_connection; 93 IPC::MessageReceiverMap m_messageReceiverMap; 94}; 95 96template<typename T> 97bool ChildProcessProxy::send(T&& message, uint64_t destinationID, unsigned messageSendFlags) 98{ 99 COMPILE_ASSERT(!T::isSync, AsyncMessageExpected); 100 101 auto encoder = std::make_unique<IPC::MessageEncoder>(T::receiverName(), T::name(), destinationID); 102 encoder->encode(message.arguments()); 103 104 return sendMessage(WTF::move(encoder), messageSendFlags); 105} 106 107template<typename U> 108bool ChildProcessProxy::sendSync(U&& message, typename U::Reply&& reply, uint64_t destinationID, std::chrono::milliseconds timeout) 109{ 110 COMPILE_ASSERT(U::isSync, SyncMessageExpected); 111 112 if (!m_connection) 113 return false; 114 115 return connection()->sendSync(std::forward<U>(message), WTF::move(reply), destinationID, timeout); 116} 117 118} // namespace WebKit 119 120#endif // ChildProcessProxy_h 121