123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123 |
- //
- // Copyright (c) 2022 Klemens Morgenstern (klemens.morgenstern@gmx.net)
- //
- // Distributed under the Boost Software License, Version 1.0. (See accompanying
- // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
- //
- #ifndef BOOST_COBALT_THREAD_HPP
- #define BOOST_COBALT_THREAD_HPP
- #include <boost/cobalt/detail/thread.hpp>
- #include <boost/cobalt/detail/await_result_helper.hpp>
- namespace boost::cobalt
- {
- // tag::outline[]
- struct thread
- {
- // Send a cancellation signal
- void cancel(asio::cancellation_type type = asio::cancellation_type::all);
- // Allow the thread to be awaited. NOOP if the thread is invalid.
- auto operator co_await() &-> detail::thread_awaitable; //<1>
- auto operator co_await() && -> detail::thread_awaitable; //<2>
- // Stops the io_context & joins the executor
- ~thread();
- /// Move constructible
- thread(thread &&) noexcept = default;
- using executor_type = executor;
- using id = std::thread::id;
- id get_id() const noexcept;
- // end::outline[]
- /* tag::outline[]
- // Add the functions similar to `std::thread`
- void join();
- bool joinable() const;
- void detach();
- executor_type get_executor() const;
- end::outline[] */
- BOOST_COBALT_DECL void join();
- BOOST_COBALT_DECL bool joinable() const;
- BOOST_COBALT_DECL void detach();
- executor_type get_executor(const boost::source_location & loc = BOOST_CURRENT_LOCATION) const
- {
- auto st = state_;
- if (!st || st->done)
- boost::throw_exception(asio::execution::bad_executor(), loc);
- return st ->ctx.get_executor();
- }
- using promise_type = detail::thread_promise;
- private:
- thread(std::thread thr, std::shared_ptr<detail::thread_state> state)
- : thread_(std::move(thr)), state_(std::move(state))
- {
- }
- std::thread thread_;
- std::shared_ptr<detail::thread_state> state_;
- friend struct detail::thread_promise;
- // tag::outline[]
- };
- // end::outline[]
- inline
- void thread::cancel(asio::cancellation_type type)
- {
- if (auto st = state_)
- asio::post(state_->ctx,
- [s= state_, type]
- {
- BOOST_ASIO_HANDLER_LOCATION((__FILE__, __LINE__, __func__));
- s->signal.emit(type);
- });
- }
- inline
- auto thread::operator co_await() &-> detail::thread_awaitable
- {
- return detail::thread_awaitable{std::move(state_)};
- }
- inline
- auto thread::operator co_await() && -> detail::thread_awaitable
- {
- return detail::thread_awaitable{std::move(thread_), std::move(state_)};
- }
- inline
- thread::~thread()
- {
- if (state_)
- {
- state_->ctx.stop();
- state_.reset();
- }
- if (thread_.joinable())
- thread_.join();
- }
- inline
- thread::id thread::get_id() const noexcept {return thread_.get_id();}
- }
- #endif //BOOST_COBALT_THREAD_HPP
|