Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2024-11-15 09:04:18

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