Branch data 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