example.cpp
1 // Copyright (c) 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 #include <init.capnp.h> 6 #include <init.capnp.proxy.h> 7 8 #include <cstring> // IWYU pragma: keep 9 #include <filesystem> 10 #include <fstream> 11 #include <future> 12 #include <iostream> 13 #include <kj/async.h> 14 #include <kj/common.h> 15 #include <memory> 16 #include <mp/proxy-io.h> 17 #include <mp/util.h> 18 #include <stdexcept> 19 #include <string> 20 #include <thread> 21 #include <tuple> 22 #include <vector> 23 24 namespace fs = std::filesystem; 25 26 static auto Spawn(mp::EventLoop& loop, const std::string& process_argv0, const std::string& new_exe_name) 27 { 28 int pid; 29 const int fd = mp::SpawnProcess(pid, [&](int fd) -> std::vector<std::string> { 30 fs::path path = process_argv0; 31 path.remove_filename(); 32 path.append(new_exe_name); 33 return {path.string(), std::to_string(fd)}; 34 }); 35 return std::make_tuple(mp::ConnectStream<InitInterface>(loop, fd), pid); 36 } 37 38 static void LogPrint(mp::LogMessage log_data) 39 { 40 if (log_data.level == mp::Log::Raise) throw std::runtime_error(log_data.message); 41 std::ofstream("debug.log", std::ios_base::app) << log_data.message << std::endl; 42 } 43 44 int main(int argc, char** argv) 45 { 46 if (argc != 1) { 47 std::cout << "Usage: mpexample\n"; 48 return 1; 49 } 50 51 std::promise<mp::EventLoop*> promise; 52 std::thread loop_thread([&] { 53 mp::EventLoop loop("mpexample", LogPrint); 54 promise.set_value(&loop); 55 loop.loop(); 56 }); 57 mp::EventLoop* loop = promise.get_future().get(); 58 59 auto [printer_init, printer_pid] = Spawn(*loop, argv[0], "mpprinter"); 60 auto [calc_init, calc_pid] = Spawn(*loop, argv[0], "mpcalculator"); 61 auto calc = calc_init->makeCalculator(printer_init->makePrinter()); 62 while (true) { 63 std::string eqn; 64 std::cout << "Enter the equation, or \"exit\" to quit: "; 65 std::getline(std::cin, eqn); 66 if (eqn == "exit") break; 67 calc->solveEquation(eqn); 68 } 69 calc.reset(); 70 calc_init.reset(); 71 mp::WaitProcess(calc_pid); 72 printer_init.reset(); 73 mp::WaitProcess(printer_pid); 74 loop_thread.join(); 75 std::cout << "Bye!" << std::endl; 76 return 0; 77 }