]>
git.proxmox.com Git - ceph.git/blob - ceph/src/seastar/tests/unit/alien_test.cc
1 // -*- mode:C++; tab-width:4; c-basic-offset:4; indent-tabs-mode:nil -*-
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.
8 * You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
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
20 * Copyright (C) 2018 Red Hat
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>
33 using namespace seastar
;
40 int main(int argc
, char** argv
)
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
;
48 // use the raw fd, because seastar engine want to take over the fds, if it
50 auto zim
= std::async([&app
, engine_ready_fd
,
51 alien_done
=alien_done
.get()] {
53 // wait until the seastar engine is ready
54 int r
= ::eventfd_read(engine_ready_fd
, &result
);
58 if (result
!= ENGINE_READY
) {
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
);
69 alien::submit_to(app
.alien(), 0, [] {
70 return seastar::make_ready_future
<>();
73 for (auto& count
: counts
) {
76 // i am done. dismiss the engine
77 ::eventfd_write(alien_done
, ALIEN_DONE
);
82 app
.run(argc
, argv
, [&] {
83 return seastar::now().then([engine_ready_fd
] {
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
);
95 }).then([&result
](size_t n
) {
96 if (n
!= sizeof(result
)) {
97 throw std::runtime_error("read from eventfd failed");
99 if (result
!= ALIEN_DONE
) {
100 throw std::logic_error("alien failed to dismiss me");
102 return seastar::now();
103 }).handle_exception([](auto ep
) {
104 std::cerr
<< "Error: " << ep
<< std::endl
;
106 seastar::engine().exit(0);
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
;