Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-09-18 08:36:35

0001 //
0002 // Copyright (c) 2022 Klemens Morgenstern (klemens.morgenstern@gmx.net)
0003 //
0004 // Distributed under the Boost Software License, Version 1.0. (See accompanying
0005 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
0006 //
0007 
0008 #ifndef BOOST_COBALT_THREAD_HPP
0009 #define BOOST_COBALT_THREAD_HPP
0010 
0011 #include <boost/cobalt/detail/thread.hpp>
0012 #include <boost/cobalt/detail/exception.hpp>
0013 #include <boost/cobalt/detail/await_result_helper.hpp>
0014 
0015 
0016 
0017 namespace boost::cobalt
0018 {
0019 
0020 // tag::outline[]
0021 struct thread
0022 {
0023   // Send a cancellation signal
0024   void cancel(asio::cancellation_type type = asio::cancellation_type::all);
0025 
0026 
0027   // Allow the thread to be awaited. NOOP if the thread is invalid.
0028   auto operator co_await() &-> detail::thread_awaitable; //<1>
0029   auto operator co_await() && -> detail::thread_awaitable; //<2>
0030 
0031   // Stops the io_context & joins the executor
0032   ~thread();
0033   /// Move constructible
0034   thread(thread &&) noexcept = default;
0035 
0036   using executor_type = executor;
0037 
0038   using id = std::thread::id;
0039   id get_id() const noexcept;
0040 
0041   // end::outline[]
0042   /* tag::outline[]
0043   // Add the functions similar to `std::thread`
0044   void join();
0045   bool joinable() const;
0046   void detach();
0047 
0048   executor_type get_executor() const;
0049   end::outline[] */
0050 
0051 
0052   BOOST_COBALT_DECL void join();
0053   BOOST_COBALT_DECL bool joinable() const;
0054   BOOST_COBALT_DECL void detach();
0055 
0056   executor_type get_executor(const boost::source_location & loc = BOOST_CURRENT_LOCATION) const
0057   {
0058     auto st = state_;
0059     if (!st || st->done)
0060       cobalt::detail::throw_bad_executor(loc);
0061 
0062     return st ->ctx.get_executor();
0063   }
0064 
0065 
0066   using promise_type = detail::thread_promise;
0067 
0068  private:
0069   thread(std::thread thr, std::shared_ptr<detail::thread_state> state)
0070       : thread_(std::move(thr)), state_(std::move(state))
0071   {
0072   }
0073 
0074   std::thread thread_;
0075   std::shared_ptr<detail::thread_state> state_;
0076   friend struct detail::thread_promise;
0077   // tag::outline[]
0078 };
0079 // end::outline[]
0080 
0081 
0082 inline
0083 void thread::cancel(asio::cancellation_type type)
0084 {
0085   if (auto st = state_)
0086     asio::post(state_->ctx,
0087                [s= state_, type]
0088                {
0089                  BOOST_ASIO_HANDLER_LOCATION((__FILE__, __LINE__, __func__));
0090                  s->signal.emit(type);
0091                });
0092 }
0093 
0094 
0095 inline
0096 auto thread::operator co_await() &-> detail::thread_awaitable
0097 {
0098   return detail::thread_awaitable{std::move(state_)};
0099 }
0100 inline
0101 auto thread::operator co_await() && -> detail::thread_awaitable
0102 {
0103   return detail::thread_awaitable{std::move(thread_), std::move(state_)};
0104 }
0105 inline
0106 thread::~thread()
0107 {
0108   if (state_)
0109   {
0110     state_->ctx.stop();
0111     state_.reset();
0112   }
0113 
0114   if (thread_.joinable())
0115     thread_.join();
0116 }
0117 
0118 
0119 inline
0120 thread::id thread::get_id() const noexcept {return thread_.get_id();}
0121 
0122 }
0123 
0124 #endif //BOOST_COBALT_THREAD_HPP