1
다음 코드는 활성화 된 동시 루틴을 지원하는 clang-5.0에서 SEGFAULT를 발생시킵니다.() 나는 GDB 아래를 실행하면coroutines에 래핑 된 부스트 타이머가 clang-5.0에서 SEGFAULT를 일으 킵니다.
-stdlib=libc++ -fcoroutines-ts
그것이 coro.resume 후 async_await에서 세그먼테이션 폴트 (segfault); 내가 컴파일러 옵션을 사용하고 wandbox compiled code
: 온라인으로 여기에 코드를 실행할 수 있습니다 호출됩니다. await_resume 함수에 도달하지 못했습니다. 이 개체 수명 문제가 될 것으로 기대합니다. 아주 많은 코드가 MSVC 2017에서 컴파일되고 실행됩니다.
이 프로그램의 출력은 다음과 같습니다
i=0
Segmentation fault
Finish
소스 코드 :
#define BOOST_THREAD_PROVIDES_FUTURE
#define BOOST_THREAD_PROVIDES_FUTURE_CONTINUATION // Enables future::then
#include <boost/thread.hpp>
#include <boost/asio.hpp>
#include <boost/asio/system_timer.hpp>
#include <experimental/coroutine>
#include <chrono>
#include <iostream>
namespace std
{
namespace experimental
{
template <typename... Args>
struct coroutine_traits<boost::future<void>, Args...> {
struct promise_type {
boost::promise<void> p;
auto get_return_object() { return p.get_future(); }
std::experimental::suspend_never initial_suspend() { return {}; }
std::experimental::suspend_never final_suspend() { return {}; }
void unhandled_exception(){}
void return_void() { p.set_value(); }
};
};
}
}
namespace asioadapt
{
using namespace std::experimental;
template <typename R> auto operator co_await(boost::future<R> &&f) {
struct Awaiter {
boost::future<R> &&input;
boost::future<R> output;
bool await_ready() { return false; }
auto await_resume() { return output.get(); }
void await_suspend(std::experimental::coroutine_handle<> coro) {
input.then([this, coro](auto result_future) mutable{
this->output = std::move(result_future);
coro.resume();
});
}
};
return Awaiter{ static_cast<boost::future<R>&&>(f) };
}
template <typename R, typename P>
auto async_await(boost::asio::system_timer &t, std::chrono::duration<R, P> d) {
struct Awaiter
{
boost::asio::system_timer &t;
std::chrono::duration<R, P> d;
boost::system::error_code ec;
bool await_ready() { return false; }
void await_suspend(std::experimental::coroutine_handle<> coro) {
t.expires_from_now(d);
t.async_wait([this, &coro](auto ec) mutable {
this->ec = ec;
coro.resume();
});
}
void await_resume() {
if (ec)
throw boost::system::system_error(ec);
}
};
return Awaiter{ t, d };
}
}
using namespace boost;
using namespace boost::asio;
using namespace std::chrono_literals;
using namespace asioadapt;
boost::future<void> sleepy(io_service &io, int &i) {
system_timer timer(io);
std::cout << "i=" << i << std::endl;
co_await async_await(timer, 100ms);
++i;
std::cout << "i=" << i << std::endl;
co_await async_await(timer, 100ms);
++i;
std::cout << "i=" << i << std::endl;
co_await async_await(timer, 100ms);
++i;
std::cout << "i=" << i << std::endl;
}
void test(){
int i = 0;
io_service io;
auto future = sleepy(io, i);
io.run();
std::cout << "i=" << i << std::endl;
}
int main()
{
test();
}