example.cpp raw

   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  }
  78