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 : : void addCleanup(Interface& iface, std::function<void()> cleanup) # 61 : 0 : { # 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