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