]> git.proxmox.com Git - ceph.git/blob - ceph/src/test/crimson/seastar_runner.h
import quincy beta 17.1.0
[ceph.git] / ceph / src / test / crimson / seastar_runner.h
1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
3
4 #pragma once
5
6 #include <stdio.h>
7 #include <signal.h>
8 #include <thread>
9
10 #include <seastar/core/app-template.hh>
11 #include <seastar/core/future-util.hh>
12 #include <seastar/core/reactor.hh>
13 #include <seastar/core/alien.hh>
14 #include <seastar/core/thread.hh>
15
16 struct SeastarRunner {
17 static constexpr eventfd_t APP_RUNNING = 1;
18 static constexpr eventfd_t APP_NOT_RUN = 2;
19
20 seastar::app_template app;
21 seastar::file_desc begin_fd;
22 std::unique_ptr<seastar::readable_eventfd> on_end;
23
24 std::thread thread;
25
26 bool begin_signaled = false;
27
28 SeastarRunner() :
29 begin_fd{seastar::file_desc::eventfd(0, 0)} {}
30
31 ~SeastarRunner() {}
32
33 bool is_running() const {
34 return !!on_end;
35 }
36
37 int init(int argc, char **argv)
38 {
39 thread = std::thread([argc, argv, this] { reactor(argc, argv); });
40 eventfd_t result;
41 if (int r = ::eventfd_read(begin_fd.get(), &result); r < 0) {
42 std::cerr << "unable to eventfd_read():" << errno << std::endl;
43 return r;
44 }
45 assert(begin_signaled == true);
46 if (result == APP_RUNNING) {
47 assert(is_running());
48 return 0;
49 } else {
50 assert(result == APP_NOT_RUN);
51 assert(!is_running());
52 return 1;
53 }
54 }
55
56 void stop()
57 {
58 if (is_running()) {
59 run([this] {
60 on_end->write_side().signal(1);
61 return seastar::now();
62 });
63 }
64 thread.join();
65 }
66
67 void reactor(int argc, char **argv)
68 {
69 auto ret = app.run(argc, argv, [this] {
70 on_end.reset(new seastar::readable_eventfd);
71 return seastar::now().then([this] {
72 begin_signaled = true;
73 auto r = ::eventfd_write(begin_fd.get(), APP_RUNNING);
74 assert(r == 0);
75 return seastar::now();
76 }).then([this] {
77 return on_end->wait().then([](size_t){});
78 }).handle_exception([](auto ep) {
79 std::cerr << "Error: " << ep << std::endl;
80 }).finally([this] {
81 on_end.reset();
82 });
83 });
84 if (ret != 0) {
85 std::cerr << "Seastar app returns " << ret << std::endl;
86 }
87 if (!begin_signaled) {
88 begin_signaled = true;
89 ::eventfd_write(begin_fd.get(), APP_NOT_RUN);
90 }
91 }
92
93 template <typename Func>
94 void run(Func &&func) {
95 assert(is_running());
96 auto fut = seastar::alien::submit_to(app.alien(), 0,
97 std::forward<Func>(func));
98 fut.get();
99 }
100 };
101
102