]> git.proxmox.com Git - ceph.git/blob - ceph/src/seastar/tests/unit/alien_test.cc
update sources to ceph Nautilus 14.2.1
[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/app-template.hh>
28 #include <seastar/core/posix.hh>
29 #include <seastar/core/reactor.hh>
30
31 using namespace seastar;
32
33 enum {
34 ENGINE_READY = 24,
35 ALIEN_DONE = 42,
36 };
37
38 int main(int argc, char** argv)
39 {
40 // we need a protocol that both seastar and alien understand.
41 // and on which, a seastar future can wait.
42 int engine_ready_fd = eventfd(0, 0);
43 auto alien_done = file_desc::eventfd(0, 0);
44
45 // use the raw fd, because seastar engine want to take over the fds, if it
46 // polls on them.
47 auto zim = std::async([engine_ready_fd,
48 alien_done=alien_done.get()] {
49 eventfd_t result = 0;
50 // wait until the seastar engine is ready
51 int r = ::eventfd_read(engine_ready_fd, &result);
52 if (r < 0) {
53 return -EINVAL;
54 }
55 if (result != ENGINE_READY) {
56 return -EINVAL;
57 }
58 std::vector<std::future<int>> counts;
59 for (auto i : boost::irange(0u, smp::count)) {
60 // send messages from alien.
61 counts.push_back(alien::submit_to(i, [i] {
62 return seastar::make_ready_future<int>(i);
63 }));
64 }
65 int total = 0;
66 for (auto& count : counts) {
67 total += count.get();
68 }
69 // i am done. dismiss the engine
70 ::eventfd_write(alien_done, ALIEN_DONE);
71 return total;
72 });
73
74 seastar::app_template app;
75 seastar::pollable_fd_state alien_done_fds{std::move(alien_done)};
76 eventfd_t result = 0;
77 app.run(argc, argv, [&] {
78 return seastar::now().then([engine_ready_fd] {
79 // engine ready!
80 ::eventfd_write(engine_ready_fd, ENGINE_READY);
81 return seastar::now();
82 }).then([&alien_done_fds, &result]() {
83 // check if alien has dismissed me.
84 return seastar::engine().read_some(alien_done_fds, &result, sizeof(result));
85 }).then([&result](size_t n) {
86 if (n != sizeof(result)) {
87 throw std::runtime_error("read from eventfd failed");
88 }
89 if (result != ALIEN_DONE) {
90 throw std::logic_error("alien failed to dismiss me");
91 }
92 return seastar::now();
93 }).handle_exception([](auto ep) {
94 std::cerr << "Error: " << ep << std::endl;
95 }).finally([] {
96 seastar::engine().exit(0);
97 });
98 });
99 int total = zim.get();
100 const auto shards = boost::irange(0u, smp::count);
101 auto expected = std::accumulate(std::begin(shards), std::end(shards), 0);
102 if (total != expected) {
103 std::cerr << "Bad total: " << total << " != " << expected << std::endl;
104 return 1;
105 }
106 }