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   2804 blocking_context::blocking_context() 30   2806 blocking_context::blocking_context()
HITCBC 31   2804 : impl_(new impl) 31   2806 : impl_(new impl)
32   { 32   {
HITCBC 33   2804 } 33   2806 }
34   34  
HITCBC 35   2804 blocking_context::~blocking_context() 35   2806 blocking_context::~blocking_context()
36   { 36   {
HITCBC 37   2804 delete impl_; 37   2806 delete impl_;
HITCBC 38   2804 } 38   2806 }
39   39  
40   blocking_executor 40   blocking_executor
HITCBC 41   2804 blocking_context::get_executor() noexcept 41   2806 blocking_context::get_executor() noexcept
42   { 42   {
HITCBC 43   2804 return blocking_executor{this}; 43   2806 return blocking_executor{this};
44   } 44   }
45   45  
46   void 46   void
HITCBC 47   1779 blocking_context::signal_done() noexcept 47   1781 blocking_context::signal_done() noexcept
48   { 48   {
HITCBC 49   1779 std::lock_guard<std::mutex> lock(impl_->mtx); 49   1781 std::lock_guard<std::mutex> lock(impl_->mtx);
HITCBC 50   1779 impl_->done = true; 50   1781 impl_->done = true;
HITCBC 51   1779 impl_->cv.notify_one(); 51   1781 impl_->cv.notify_one();
HITCBC 52   1779 } 52   1781 }
53   53  
54   void 54   void
HITCBC 55   1017 blocking_context::signal_done( 55   1017 blocking_context::signal_done(
56   std::exception_ptr ep) noexcept 56   std::exception_ptr ep) noexcept
57   { 57   {
HITCBC 58   1017 std::lock_guard<std::mutex> lock(impl_->mtx); 58   1017 std::lock_guard<std::mutex> lock(impl_->mtx);
HITCBC 59   1017 impl_->ep = ep; 59   1017 impl_->ep = ep;
HITCBC 60   1017 impl_->done = true; 60   1017 impl_->done = true;
HITCBC 61   1017 impl_->cv.notify_one(); 61   1017 impl_->cv.notify_one();
HITCBC 62   1017 } 62   1017 }
63   63  
64   void 64   void
HITCBC 65   2796 blocking_context::run() 65   2798 blocking_context::run()
66   { 66   {
67   for(;;) 67   for(;;)
68   { 68   {
HITCBC 69   2871 std::coroutine_handle<> h; 69   2876 std::coroutine_handle<> h;
70   { 70   {
HITCBC 71   2871 std::unique_lock<std::mutex> lock(impl_->mtx); 71   2876 std::unique_lock<std::mutex> lock(impl_->mtx);
HITCBC 72   2871 impl_->cv.wait(lock, [&] { 72   2876 impl_->cv.wait(lock, [&] {
HITCBC 73   2871 return impl_->done || !impl_->queue.empty(); 73   2877 return impl_->done || !impl_->queue.empty();
74   }); 74   });
HITCBC 75   2871 if(impl_->done && impl_->queue.empty()) 75   2876 if(impl_->done && impl_->queue.empty())
HITCBC 76   2796 break; 76   2798 break;
HITCBC 77   75 h = impl_->queue.front(); 77   78 h = impl_->queue.front();
HITCBC 78   75 impl_->queue.pop(); 78   78 impl_->queue.pop();
HITCBC 79   2871 } 79   2876 }
HITCBC 80   75 safe_resume(h); 80   78 safe_resume(h);
HITCBC 81   75 } 81   78 }
HITCBC 82   2796 if(impl_->ep) 82   2798 if(impl_->ep)
HITCBC 83   1017 std::rethrow_exception(impl_->ep); 83   1017 std::rethrow_exception(impl_->ep);
HITCBC 84   1779 } 84   1781 }
85   85  
86   void 86   void
HITCBC 87   75 blocking_context::enqueue( 87   78 blocking_context::enqueue(
88   std::coroutine_handle<> h) 88   std::coroutine_handle<> h)
89   { 89   {
HITGIC 90 - { 90 + 78 std::lock_guard<std::mutex> lock(impl_->mtx);
HITCBC 91 - 75 std::lock_guard<std::mutex> lock(impl_->mtx); 91 + 78 impl_->queue.push(h);
DCB 92 - 75 impl_->queue.push(h);  
DCB 93 - 75 }  
HITCBC 94   75 impl_->cv.notify_one(); 92   78 impl_->cv.notify_one();
HITCBC 95   75 } 93   78 }
96   94  
97   //---------------------------------------------------------- 95   //----------------------------------------------------------
98   96  
99   bool 97   bool
MISUBC 100   blocking_executor::operator==( 98   blocking_executor::operator==(
101   blocking_executor const& other) const noexcept 99   blocking_executor const& other) const noexcept
102   { 100   {
MISUBC 103   return ctx_ == other.ctx_; 101   return ctx_ == other.ctx_;
104   } 102   }
105   103  
106   blocking_context& 104   blocking_context&
HITCBC 107   2796 blocking_executor::context() const noexcept 105   2799 blocking_executor::context() const noexcept
108   { 106   {
HITCBC 109   2796 return *ctx_; 107   2799 return *ctx_;
110   } 108   }
111   109  
112   void 110   void
HITCBC 113   2796 blocking_executor::on_work_started() const noexcept 111   2798 blocking_executor::on_work_started() const noexcept
114   { 112   {
HITCBC 115   2796 } 113   2798 }
116   114  
117   void 115   void
HITCBC 118   2796 blocking_executor::on_work_finished() const noexcept 116   2798 blocking_executor::on_work_finished() const noexcept
119   { 117   {
HITCBC 120   2796 } 118   2798 }
121   119  
122   std::coroutine_handle<> 120   std::coroutine_handle<>
HITCBC 123   2821 blocking_executor::dispatch( 121   2823 blocking_executor::dispatch(
124   continuation& c) const 122   continuation& c) const
125   { 123   {
HITCBC 126   2821 return c.h; 124   2823 return c.h;
127   } 125   }
128   126  
129   void 127   void
HITCBC 130   75 blocking_executor::post( 128   78 blocking_executor::post(
131   continuation& c) const 129   continuation& c) const
132   { 130   {
HITCBC 133   75 ctx_->enqueue(c.h); 131   78 ctx_->enqueue(c.h);
HITCBC 134   75 } 132   78 }
135   133  
136   } // namespace test 134   } // namespace test
137   } // namespace capy 135   } // namespace capy
138   } // namespace boost 136   } // namespace boost