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 <boost/capy/ex/frame_allocator.hpp>
13   #include <condition_variable> 13   #include <condition_variable>
14   #include <mutex> 14   #include <mutex>
15   #include <queue> 15   #include <queue>
16   16  
17   namespace boost { 17   namespace boost {
18   namespace capy { 18   namespace capy {
19   namespace test { 19   namespace test {
20   20  
21   struct blocking_context::impl 21   struct blocking_context::impl
22   { 22   {
23   std::mutex mtx; 23   std::mutex mtx;
24   std::condition_variable cv; 24   std::condition_variable cv;
25   std::queue<std::coroutine_handle<>> queue; 25   std::queue<std::coroutine_handle<>> queue;
26   std::exception_ptr ep; 26   std::exception_ptr ep;
27   bool done = false; 27   bool done = false;
28   }; 28   };
29   29  
HITCBC 30   986 blocking_context::blocking_context() 30   1124 blocking_context::blocking_context()
HITCBC 31   986 : impl_(new impl) 31   1124 : impl_(new impl)
32   { 32   {
HITCBC 33   986 } 33   1124 }
34   34  
HITCBC 35   986 blocking_context::~blocking_context() 35   1124 blocking_context::~blocking_context()
36   { 36   {
HITCBC 37   986 delete impl_; 37   1124 delete impl_;
HITCBC 38   986 } 38   1124 }
39   39  
40   blocking_executor 40   blocking_executor
HITCBC 41   986 blocking_context::get_executor() noexcept 41   1124 blocking_context::get_executor() noexcept
42   { 42   {
HITCBC 43   986 return blocking_executor{this}; 43   1124 return blocking_executor{this};
44   } 44   }
45   45  
46   void 46   void
HITCBC 47   668 blocking_context::signal_done() noexcept 47   782 blocking_context::signal_done() noexcept
48   { 48   {
HITCBC 49   668 std::lock_guard<std::mutex> lock(impl_->mtx); 49   782 std::lock_guard<std::mutex> lock(impl_->mtx);
HITCBC 50   668 impl_->done = true; 50   782 impl_->done = true;
HITCBC 51   668 impl_->cv.notify_one(); 51   782 impl_->cv.notify_one();
HITCBC 52   668 } 52   782 }
53   53  
54   void 54   void
HITCBC 55   314 blocking_context::signal_done( 55   336 blocking_context::signal_done(
56   std::exception_ptr ep) noexcept 56   std::exception_ptr ep) noexcept
57   { 57   {
HITCBC 58   314 std::lock_guard<std::mutex> lock(impl_->mtx); 58   336 std::lock_guard<std::mutex> lock(impl_->mtx);
HITCBC 59   314 impl_->ep = ep; 59   336 impl_->ep = ep;
HITCBC 60   314 impl_->done = true; 60   336 impl_->done = true;
HITCBC 61   314 impl_->cv.notify_one(); 61   336 impl_->cv.notify_one();
HITCBC 62   314 } 62   336 }
63   63  
64   void 64   void
HITCBC 65   982 blocking_context::run() 65   1118 blocking_context::run()
66   { 66   {
67   for(;;) 67   for(;;)
68   { 68   {
HITCBC 69   1061 std::coroutine_handle<> h; 69   1240 std::coroutine_handle<> h;
70   { 70   {
HITCBC 71   1061 std::unique_lock<std::mutex> lock(impl_->mtx); 71   1240 std::unique_lock<std::mutex> lock(impl_->mtx);
HITCBC 72   1061 impl_->cv.wait(lock, [&] { 72   1240 impl_->cv.wait(lock, [&] {
HITCBC 73   1062 return impl_->done || !impl_->queue.empty(); 73   1241 return impl_->done || !impl_->queue.empty();
74   }); 74   });
HITCBC 75   1061 if(impl_->done && impl_->queue.empty()) 75   1240 if(impl_->done && impl_->queue.empty())
HITCBC 76   982 break; 76   1118 break;
HITCBC 77   79 h = impl_->queue.front(); 77   122 h = impl_->queue.front();
HITCBC 78   79 impl_->queue.pop(); 78   122 impl_->queue.pop();
HITCBC 79   1061 } 79   1240 }
HITCBC 80   79 safe_resume(h); 80   122 safe_resume(h);
HITCBC 81   79 } 81   122 }
HITCBC 82   982 if(impl_->ep) 82   1118 if(impl_->ep)
HITCBC 83   314 std::rethrow_exception(impl_->ep); 83   336 std::rethrow_exception(impl_->ep);
HITCBC 84   668 } 84   782 }
85   85  
86   void 86   void
HITCBC 87   79 blocking_context::enqueue( 87   122 blocking_context::enqueue(
88   std::coroutine_handle<> h) 88   std::coroutine_handle<> h)
89   { 89   {
HITCBC 90   79 std::lock_guard<std::mutex> lock(impl_->mtx); 90   122 std::lock_guard<std::mutex> lock(impl_->mtx);
HITCBC 91   79 impl_->queue.push(h); 91   122 impl_->queue.push(h);
HITCBC 92   79 impl_->cv.notify_one(); 92   122 impl_->cv.notify_one();
HITCBC 93   79 } 93   122 }
94   94  
95   //---------------------------------------------------------- 95   //----------------------------------------------------------
96   96  
97   bool 97   bool
MISUBC 98   blocking_executor::operator==( 98   blocking_executor::operator==(
99   blocking_executor const& other) const noexcept 99   blocking_executor const& other) const noexcept
100   { 100   {
MISUBC 101   return ctx_ == other.ctx_; 101   return ctx_ == other.ctx_;
102   } 102   }
103   103  
104   blocking_context& 104   blocking_context&
HITCBC 105   983 blocking_executor::context() const noexcept 105   1120 blocking_executor::context() const noexcept
106   { 106   {
HITCBC 107   983 return *ctx_; 107   1120 return *ctx_;
108   } 108   }
109   109  
110   void 110   void
HITCBC 111   982 blocking_executor::on_work_started() const noexcept 111   1122 blocking_executor::on_work_started() const noexcept
112   { 112   {
HITCBC 113   982 } 113   1122 }
114   114  
115   void 115   void
HITCBC 116   982 blocking_executor::on_work_finished() const noexcept 116   1122 blocking_executor::on_work_finished() const noexcept
117   { 117   {
HITCBC 118   982 } 118   1122 }
119   119  
120   std::coroutine_handle<> 120   std::coroutine_handle<>
HITCBC 121   1007 blocking_executor::dispatch( 121   1166 blocking_executor::dispatch(
122   continuation& c) const 122   continuation& c) const
123   { 123   {
HITCBC 124   1007 return c.h; 124   1166 return c.h;
125   } 125   }
126   126  
127   void 127   void
HITCBC 128   79 blocking_executor::post( 128   122 blocking_executor::post(
129   continuation& c) const 129   continuation& c) const
130   { 130   {
HITCBC 131   79 ctx_->enqueue(c.h); 131   122 ctx_->enqueue(c.h);
HITCBC 132   79 } 132   122 }
133   133  
134   } // namespace test 134   } // namespace test
135   } // namespace capy 135   } // namespace capy
136   } // namespace boost 136   } // namespace boost