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/app-template.hh>
28 #include <seastar/core/posix.hh>
29 #include <seastar/core/reactor.hh>
31 using namespace seastar
;
38 int main(int argc
, char** argv
)
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);
45 // use the raw fd, because seastar engine want to take over the fds, if it
47 auto zim
= std::async([engine_ready_fd
,
48 alien_done
=alien_done
.get()] {
50 // wait until the seastar engine is ready
51 int r
= ::eventfd_read(engine_ready_fd
, &result
);
55 if (result
!= ENGINE_READY
) {
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
);
66 for (auto& count
: counts
) {
69 // i am done. dismiss the engine
70 ::eventfd_write(alien_done
, ALIEN_DONE
);
74 seastar::app_template app
;
75 seastar::pollable_fd_state alien_done_fds
{std::move(alien_done
)};
77 app
.run(argc
, argv
, [&] {
78 return seastar::now().then([engine_ready_fd
] {
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");
89 if (result
!= ALIEN_DONE
) {
90 throw std::logic_error("alien failed to dismiss me");
92 return seastar::now();
93 }).handle_exception([](auto ep
) {
94 std::cerr
<< "Error: " << ep
<< std::endl
;
96 seastar::engine().exit(0);
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
;