]> git.proxmox.com Git - ceph.git/blob - ceph/src/seastar/tests/unit/alien_test.cc
import quincy beta 17.1.0
[ceph.git] / ceph / src / seastar / tests / unit / alien_test.cc
1 // -*- mode:C++; tab-width:4; c-basic-offset:4; indent-tabs-mode:nil -*-
2 /*
3 * This file is open source software, licensed to you under the terms
4 * of the Apache License, Version 2.0 (the "License"). See the NOTICE file
5 * distributed with this work for additional information regarding copyright
6 * ownership. You may not use this file except in compliance with the License.
7 *
8 * You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing,
13 * software distributed under the License is distributed on an
14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 * KIND, either express or implied. See the License for the
16 * specific language governing permissions and limitations
17 * under the License.
18 */
19 /*
20 * Copyright (C) 2018 Red Hat
21 */
22
23 #include <future>
24 #include <numeric>
25 #include <iostream>
26 #include <seastar/core/alien.hh>
27 #include <seastar/core/smp.hh>
28 #include <seastar/core/app-template.hh>
29 #include <seastar/core/posix.hh>
30 #include <seastar/core/reactor.hh>
31 #include <seastar/util/later.hh>
32
33 using namespace seastar;
34
35 enum {
36 ENGINE_READY = 24,
37 ALIEN_DONE = 42,
38 };
39
40 int main(int argc, char** argv)
41 {
42 // we need a protocol that both seastar and alien understand.
43 // and on which, a seastar future can wait.
44 int engine_ready_fd = eventfd(0, 0);
45 auto alien_done = file_desc::eventfd(0, 0);
46 seastar::app_template app;
47
48 // use the raw fd, because seastar engine want to take over the fds, if it
49 // polls on them.
50 auto zim = std::async([&app, engine_ready_fd,
51 alien_done=alien_done.get()] {
52 eventfd_t result = 0;
53 // wait until the seastar engine is ready
54 int r = ::eventfd_read(engine_ready_fd, &result);
55 if (r < 0) {
56 return -EINVAL;
57 }
58 if (result != ENGINE_READY) {
59 return -EINVAL;
60 }
61 std::vector<std::future<int>> counts;
62 for (auto i : boost::irange(0u, smp::count)) {
63 // send messages from alien.
64 counts.push_back(alien::submit_to(app.alien(), i, [i] {
65 return seastar::make_ready_future<int>(i);
66 }));
67 }
68 // std::future<void>
69 alien::submit_to(app.alien(), 0, [] {
70 return seastar::make_ready_future<>();
71 }).wait();
72 int total = 0;
73 for (auto& count : counts) {
74 total += count.get();
75 }
76 // i am done. dismiss the engine
77 ::eventfd_write(alien_done, ALIEN_DONE);
78 return total;
79 });
80
81 eventfd_t result = 0;
82 app.run(argc, argv, [&] {
83 return seastar::now().then([engine_ready_fd] {
84 // engine ready!
85 ::eventfd_write(engine_ready_fd, ENGINE_READY);
86 return seastar::now();
87 }).then([alien_done = std::move(alien_done), &result]() mutable {
88 return do_with(seastar::pollable_fd(std::move(alien_done)), [&result] (pollable_fd& alien_done_fds) {
89 // check if alien has dismissed me.
90 return alien_done_fds.readable().then([&result, &alien_done_fds] {
91 auto ret = alien_done_fds.get_file_desc().read(&result, sizeof(result));
92 return make_ready_future<size_t>(*ret);
93 });
94 });
95 }).then([&result](size_t n) {
96 if (n != sizeof(result)) {
97 throw std::runtime_error("read from eventfd failed");
98 }
99 if (result != ALIEN_DONE) {
100 throw std::logic_error("alien failed to dismiss me");
101 }
102 return seastar::now();
103 }).handle_exception([](auto ep) {
104 std::cerr << "Error: " << ep << std::endl;
105 }).finally([] {
106 seastar::engine().exit(0);
107 });
108 });
109 int total = zim.get();
110 const auto shards = boost::irange(0u, smp::count);
111 auto expected = std::accumulate(std::begin(shards), std::end(shards), 0);
112 if (total != expected) {
113 std::cerr << "Bad total: " << total << " != " << expected << std::endl;
114 return 1;
115 }
116 }