Bitcoin Core  31.0.0
P2P Digital Currency
example.cpp
Go to the documentation of this file.
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 }
path & append(const char *c)
Definition: fs.h:51
static auto Spawn(mp::EventLoop &loop, const std::string &process_argv0, const std::string &new_exe_name)
Definition: example.cpp:26
std::string string() const =delete
int SpawnProcess(int &pid, FdToArgsFn &&fd_to_args)
Spawn a new process that communicates with the current process over a socket pair.
Definition: util.cpp:119
Event loop implementation.
Definition: proxy-io.h:238
std::string message
Message to be logged.
Definition: proxy-io.h:141
int main(int argc, char **argv)
Definition: example.cpp:44
Log level
The severity level of this message.
Definition: proxy-io.h:144
int WaitProcess(int pid)
Wait for a process to exit and return its exit code.
Definition: util.cpp:186
static void LogPrint(mp::LogMessage log_data)
Definition: example.cpp:38
Path class wrapper to block calls to the fs::path(std::string) implicit constructor and the fs::path:...
Definition: fs.h:33
void loop()
Run event loop.
Definition: proxy.cpp:227