Line data Source code
1 : // Copyright (c) 2021 The Bitcoin Core developers 2 : // Distributed under the MIT software license, see the accompanying 3 : // file COPYING or http://www.opensource.org/licenses/mit-license.php. 4 : 5 : #ifndef BITCOIN_INTERFACES_IPC_H 6 : #define BITCOIN_INTERFACES_IPC_H 7 : 8 : #include <functional> 9 : #include <memory> 10 : #include <typeindex> 11 : 12 : namespace ipc { 13 : struct Context; 14 : } // namespace ipc 15 : 16 : namespace interfaces { 17 : class Init; 18 : 19 : //! Interface providing access to interprocess-communication (IPC) 20 : //! functionality. The IPC implementation is responsible for establishing 21 : //! connections between a controlling process and a process being controlled. 22 : //! When a connection is established, the process being controlled returns an 23 : //! interfaces::Init pointer to the controlling process, which the controlling 24 : //! process can use to get access to other interfaces and functionality. 25 : //! 26 : //! When spawning a new process, the steps are: 27 : //! 28 : //! 1. The controlling process calls interfaces::Ipc::spawnProcess(), which 29 : //! calls ipc::Process::spawn(), which spawns a new process and returns a 30 : //! socketpair file descriptor for communicating with it. 31 : //! interfaces::Ipc::spawnProcess() then calls ipc::Protocol::connect() 32 : //! passing the socketpair descriptor, which returns a local proxy 33 : //! interfaces::Init implementation calling remote interfaces::Init methods. 34 : //! 2. The spawned process calls interfaces::Ipc::startSpawnProcess(), which 35 : //! calls ipc::Process::checkSpawned() to read command line arguments and 36 : //! determine whether it is a spawned process and what socketpair file 37 : //! descriptor it should use. It then calls ipc::Protocol::serve() to handle 38 : //! incoming requests from the socketpair and invoke interfaces::Init 39 : //! interface methods, and exit when the socket is closed. 40 : //! 3. The controlling process calls local proxy interfaces::Init object methods 41 : //! to make other proxy objects calling other remote interfaces. It can also 42 : //! destroy the initial interfaces::Init object to close the connection and 43 : //! shut down the spawned process. 44 : class Ipc 45 : { 46 : public: 47 : virtual ~Ipc() = default; 48 : 49 : //! Spawn a child process returning pointer to its Init interface. 50 : virtual std::unique_ptr<Init> spawnProcess(const char* exe_name) = 0; 51 : 52 : //! If this is a spawned process, block and handle requests from the parent 53 : //! process by forwarding them to this process's Init interface, then return 54 : //! true. If this is not a spawned child process, return false. 55 : virtual bool startSpawnedProcess(int argc, char* argv[], int& exit_status) = 0; 56 : 57 : //! Add cleanup callback to remote interface that will run when the 58 : //! interface is deleted. 59 : template<typename Interface> 60 0 : void addCleanup(Interface& iface, std::function<void()> cleanup) 61 : { 62 0 : addCleanup(typeid(Interface), &iface, std::move(cleanup)); 63 0 : } 64 : 65 : //! IPC context struct accessor (see struct definition for more description). 66 : virtual ipc::Context& context() = 0; 67 : 68 : protected: 69 : //! Internal implementation of public addCleanup method (above) as a 70 : //! type-erased virtual function, since template functions can't be virtual. 71 : virtual void addCleanup(std::type_index type, void* iface, std::function<void()> cleanup) = 0; 72 : }; 73 : 74 : //! Return implementation of Ipc interface. 75 : std::unique_ptr<Ipc> MakeIpc(const char* exe_name, const char* process_argv0, Init& init); 76 : } // namespace interfaces 77 : 78 : #endif // BITCOIN_INTERFACES_IPC_H