96.15% Lines (50/52) 92.86% Functions (13/14)
TLA Baseline Branch
Line Hits Code Line Hits Code
1   // 1   //
2   // Copyright (c) 2025 Vinnie Falco (vinnie.falco@gmail.com) 2   // Copyright (c) 2025 Vinnie Falco (vinnie.falco@gmail.com)
3   // 3   //
4   // Distributed under the Boost Software License, Version 1.0. (See accompanying 4   // Distributed under the Boost Software License, Version 1.0. (See accompanying
5   // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 5   // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6   // 6   //
7   // Official repository: https://github.com/cppalliance/capy 7   // Official repository: https://github.com/cppalliance/capy
8   // 8   //
9   9  
10   #include <boost/capy/test/run_blocking.hpp> 10   #include <boost/capy/test/run_blocking.hpp>
11   11  
  12 + #include <boost/capy/ex/frame_allocator.hpp>
12   #include <condition_variable> 13   #include <condition_variable>
13   #include <mutex> 14   #include <mutex>
14   #include <queue> 15   #include <queue>
15   16  
16   namespace boost { 17   namespace boost {
17   namespace capy { 18   namespace capy {
18   namespace test { 19   namespace test {
19   20  
20   struct blocking_context::impl 21   struct blocking_context::impl
21   { 22   {
22   std::mutex mtx; 23   std::mutex mtx;
23   std::condition_variable cv; 24   std::condition_variable cv;
24   std::queue<std::coroutine_handle<>> queue; 25   std::queue<std::coroutine_handle<>> queue;
25   std::exception_ptr ep; 26   std::exception_ptr ep;
26   bool done = false; 27   bool done = false;
27   }; 28   };
28   29  
HITCBC 29   2766 blocking_context::blocking_context() 30   2818 blocking_context::blocking_context()
HITCBC 30   2766 : impl_(new impl) 31   2818 : impl_(new impl)
31   { 32   {
HITCBC 32   2766 } 33   2818 }
33   34  
HITCBC 34   2766 blocking_context::~blocking_context() 35   2818 blocking_context::~blocking_context()
35   { 36   {
HITCBC 36   2766 delete impl_; 37   2818 delete impl_;
HITCBC 37   2766 } 38   2818 }
38   39  
39   blocking_executor 40   blocking_executor
HITCBC 40   2766 blocking_context::get_executor() noexcept 41   2818 blocking_context::get_executor() noexcept
41   { 42   {
HITCBC 42   2766 return blocking_executor{this}; 43   2818 return blocking_executor{this};
43   } 44   }
44   45  
45   void 46   void
HITCBC 46   1758 blocking_context::signal_done() noexcept 47   1789 blocking_context::signal_done() noexcept
47   { 48   {
HITCBC 48   1758 std::lock_guard<std::mutex> lock(impl_->mtx); 49   1789 std::lock_guard<std::mutex> lock(impl_->mtx);
HITCBC 49   1758 impl_->done = true; 50   1789 impl_->done = true;
HITCBC 50   1758 impl_->cv.notify_one(); 51   1789 impl_->cv.notify_one();
HITCBC 51   1758 } 52   1789 }
52   53  
53   void 54   void
HITCBC 54   1000 blocking_context::signal_done( 55   1021 blocking_context::signal_done(
55   std::exception_ptr ep) noexcept 56   std::exception_ptr ep) noexcept
56   { 57   {
HITCBC 57   1000 std::lock_guard<std::mutex> lock(impl_->mtx); 58   1021 std::lock_guard<std::mutex> lock(impl_->mtx);
HITCBC 58   1000 impl_->ep = ep; 59   1021 impl_->ep = ep;
HITCBC 59   1000 impl_->done = true; 60   1021 impl_->done = true;
HITCBC 60   1000 impl_->cv.notify_one(); 61   1021 impl_->cv.notify_one();
HITCBC 61   1000 } 62   1021 }
62   63  
63   void 64   void
HITCBC 64   2758 blocking_context::run() 65   2810 blocking_context::run()
65   { 66   {
66   for(;;) 67   for(;;)
67   { 68   {
HITCBC 68   2833 std::coroutine_handle<> h; 69   2888 std::coroutine_handle<> h;
69   { 70   {
HITCBC 70   2833 std::unique_lock<std::mutex> lock(impl_->mtx); 71   2888 std::unique_lock<std::mutex> lock(impl_->mtx);
HITCBC 71   2833 impl_->cv.wait(lock, [&] { 72   2888 impl_->cv.wait(lock, [&] {
HITCBC 72   2833 return impl_->done || !impl_->queue.empty(); 73   2889 return impl_->done || !impl_->queue.empty();
73   }); 74   });
HITCBC 74   2833 if(impl_->done && impl_->queue.empty()) 75   2888 if(impl_->done && impl_->queue.empty())
HITCBC 75   2758 break; 76   2810 break;
HITCBC 76   75 h = impl_->queue.front(); 77   78 h = impl_->queue.front();
HITCBC 77   75 impl_->queue.pop(); 78   78 impl_->queue.pop();
HITCBC 78   2833 } 79   2888 }
HITCBC 79 - 75 h.resume(); 80 + 78 safe_resume(h);
HITCBC 80   75 } 81   78 }
HITCBC 81   2758 if(impl_->ep) 82   2810 if(impl_->ep)
HITCBC 82   1000 std::rethrow_exception(impl_->ep); 83   1021 std::rethrow_exception(impl_->ep);
HITCBC 83   1758 } 84   1789 }
84   85  
85   void 86   void
HITCBC 86   75 blocking_context::enqueue( 87   78 blocking_context::enqueue(
87   std::coroutine_handle<> h) 88   std::coroutine_handle<> h)
88   { 89   {
HITGIC 89 - { 90 + 78 std::lock_guard<std::mutex> lock(impl_->mtx);
HITCBC 90 - 75 std::lock_guard<std::mutex> lock(impl_->mtx); 91 + 78 impl_->queue.push(h);
DCB 91 - 75 impl_->queue.push(h);  
DCB 92 - 75 }  
HITCBC 93   75 impl_->cv.notify_one(); 92   78 impl_->cv.notify_one();
HITCBC 94   75 } 93   78 }
95   94  
96   //---------------------------------------------------------- 95   //----------------------------------------------------------
97   96  
98   bool 97   bool
MISUBC 99   blocking_executor::operator==( 98   blocking_executor::operator==(
100   blocking_executor const& other) const noexcept 99   blocking_executor const& other) const noexcept
101   { 100   {
MISUBC 102   return ctx_ == other.ctx_; 101   return ctx_ == other.ctx_;
103   } 102   }
104   103  
105   blocking_context& 104   blocking_context&
HITCBC 106   2758 blocking_executor::context() const noexcept 105   2811 blocking_executor::context() const noexcept
107   { 106   {
HITCBC 108   2758 return *ctx_; 107   2811 return *ctx_;
109   } 108   }
110   109  
111   void 110   void
HITCBC 112   2758 blocking_executor::on_work_started() const noexcept 111   2810 blocking_executor::on_work_started() const noexcept
113   { 112   {
HITCBC 114   2758 } 113   2810 }
115   114  
116   void 115   void
HITCBC 117   2758 blocking_executor::on_work_finished() const noexcept 116   2810 blocking_executor::on_work_finished() const noexcept
118   { 117   {
HITCBC 119   2758 } 118   2810 }
120   119  
121   std::coroutine_handle<> 120   std::coroutine_handle<>
HITCBC 122   2783 blocking_executor::dispatch( 121   2835 blocking_executor::dispatch(
123 - std::coroutine_handle<> h) const 122 + continuation& c) const
124   { 123   {
HITCBC 125 - 2783 return h; 124 + 2835 return c.h;
126   } 125   }
127   126  
128   void 127   void
HITCBC 129   75 blocking_executor::post( 128   78 blocking_executor::post(
130 - std::coroutine_handle<> h) const 129 + continuation& c) const
131   { 130   {
HITCBC 132 - 75 ctx_->enqueue(h); 131 + 78 ctx_->enqueue(c.h);
HITCBC 133   75 } 132   78 }
134   133  
135   } // namespace test 134   } // namespace test
136   } // namespace capy 135   } // namespace capy
137   } // namespace boost 136   } // namespace boost