1616#ifndef VIX_ASYNC_IO_CONTEXT_HPP
1717#define VIX_ASYNC_IO_CONTEXT_HPP
1818
19+ #include < atomic>
1920#include < coroutine>
2021#include < memory>
22+ #include < mutex>
2123#include < utility>
2224
2325#include < vix/async/core/scheduler.hpp>
2426
2527namespace vix ::async::net::detail
2628{
27- /* *
28- * @brief Internal networking service (Asio-backed).
29- *
30- * This type is forward-declared to keep io_context lightweight and
31- * avoid pulling networking implementation details into the public API.
32- */
3329 class asio_net_service ;
3430}
3531
@@ -40,69 +36,65 @@ namespace vix::async::core
4036 class signal_set ;
4137
4238 /* *
43- * @brief Core runtime context for async operations.
39+ * @brief Central asynchronous execution context.
40+ *
41+ * io_context is the core coordination object of the async runtime.
4442 *
45- * io_context owns a scheduler that drives coroutine continuations and
46- * posted tasks. It also exposes lazily-created services used by higher
47- * level facilities:
48- * - CPU thread pool for compute-bound work
49- * - timers for scheduling time-based events
50- * - signals for signal handling
51- * - net for networking (implementation detail service)
43+ * It provides:
44+ * - a scheduler for coroutine and task execution
45+ * - a CPU thread pool for blocking or heavy work
46+ * - a timer service for delayed execution
47+ * - a signal handling service
48+ * - a networking backend (asio-based)
5249 *
53- * The context is non-copyable and typically lives for the duration of
54- * the program or subsystem using it.
50+ * Services are lazily initialized and owned by the context.
51+ *
52+ * Lifecycle:
53+ * - Services are created on first use
54+ * - shutdown() stops the scheduler and destroys all services
55+ * - destruction is safe and idempotent
56+ *
57+ * Thread-safety:
58+ * - posting tasks is thread-safe
59+ * - shutdown is serialized and idempotent
5560 */
5661 class io_context
5762 {
5863 public:
5964 /* *
60- * @brief Construct a new io_context.
61- *
62- * Initializes the underlying scheduler. Optional services are created
63- * lazily on first access through their corresponding accessors.
65+ * @brief Construct an empty io_context.
6466 */
6567 io_context ();
6668
6769 /* *
68- * @brief Destroy the io_context.
70+ * @brief Destroy the io_context and release all resources .
6971 *
70- * Destroys any lazily-initialized services and the scheduler .
72+ * Automatically calls shutdown() if not already done .
7173 */
72- ~io_context ();
74+ ~io_context () noexcept ;
7375
74- /* *
75- * @brief io_context is non-copyable.
76- */
7776 io_context (const io_context &) = delete ;
78-
79- /* *
80- * @brief io_context is non-copyable.
81- */
8277 io_context &operator =(const io_context &) = delete ;
8378
8479 /* *
85- * @brief Access the underlying scheduler.
80+ * @brief Access the internal scheduler.
8681 *
87- * @return Reference to the scheduler.
82+ * @return Reference to scheduler.
8883 */
89- scheduler &get_scheduler () noexcept { return sched_; }
84+ [[nodiscard]] scheduler &get_scheduler () noexcept { return sched_; }
9085
9186 /* *
92- * @brief Access the underlying scheduler.
87+ * @brief Access the internal scheduler (const) .
9388 *
94- * @return Const reference to the scheduler.
89+ * @return Const reference to scheduler.
9590 */
96- const scheduler &get_scheduler () const noexcept { return sched_; }
91+ [[nodiscard]] const scheduler &get_scheduler () const noexcept { return sched_; }
9792
9893 /* *
99- * @brief Post a callable to be executed by the scheduler.
100- *
101- * The callable is forwarded into the scheduler queue and will be
102- * executed when run() drives the scheduler.
94+ * @brief Post a callable task to the scheduler.
10395 *
10496 * @tparam Fn Callable type.
105- * @param fn Callable to enqueue .
97+ * @param fn Task to execute .
10698 */
10799 template <typename Fn>
108100 void post (Fn &&fn)
@@ -111,7 +103,7 @@ namespace vix::async::core
111103 }
112104
113105 /* *
114- * @brief Post a coroutine continuation to be resumed by the scheduler.
106+ * @brief Post a coroutine handle to the scheduler.
115107 *
116108 * @param h Coroutine handle to resume.
117109 */
@@ -121,10 +113,9 @@ namespace vix::async::core
121113 }
122114
123115 /* *
124- * @brief Run the scheduler event loop.
116+ * @brief Run the scheduler loop.
125117 *
126- * This call typically blocks and processes queued tasks until stop()
127- * is called or the scheduler decides to return.
118+ * Blocks until stop() is called.
128119 */
129120 void run ()
130121 {
@@ -134,96 +125,91 @@ namespace vix::async::core
134125 /* *
135126 * @brief Stop the scheduler.
136127 *
137- * Signals the scheduler to stop processing and return from run().
128+ * Causes run() to exit .
138129 */
139130 void stop () noexcept
140131 {
141132 sched_.stop ();
142133 }
143134
144135 /* *
145- * @brief Check whether the scheduler is currently running.
136+ * @brief Check whether the scheduler is running.
146137 *
147138 * @return true if running, false otherwise.
148139 */
149- bool is_running () const noexcept
140+ [[nodiscard]] bool is_running () const noexcept
150141 {
151142 return sched_.is_running ();
152143 }
153144
154145 /* *
155- * @name Lazy services
146+ * @brief Access the CPU thread pool.
156147 *
157- * Services below are initialized on first access and are owned by
158- * this io_context instance.
148+ * Lazily initialized.
159149 *
160- * @{
150+ * @return Reference to thread_pool.
161151 */
152+ [[nodiscard]] thread_pool &cpu_pool ();
162153
163154 /* *
164- * @brief Access the CPU thread pool service.
155+ * @brief Access the timer service.
165156 *
166- * Lazily constructs the pool on first call .
157+ * Lazily initialized .
167158 *
168- * @return Reference to the thread_pool service .
159+ * @return Reference to timer .
169160 */
170- thread_pool & cpu_pool ();
161+ [[nodiscard]] timer & timers ();
171162
172163 /* *
173- * @brief Access the timers service.
164+ * @brief Access the signal handling service.
174165 *
175- * Lazily constructs the timer service on first call .
166+ * Lazily initialized .
176167 *
177- * @return Reference to the timer service .
168+ * @return Reference to signal_set .
178169 */
179- timer & timers ();
170+ [[nodiscard]] signal_set & signals ();
180171
181172 /* *
182- * @brief Access the signal handling service.
173+ * @brief Access the networking backend service.
183174 *
184- * Lazily constructs the signal_set service on first call .
175+ * Lazily initialized .
185176 *
186- * @return Reference to the signal_set service .
177+ * @return Reference to asio_net_service .
187178 */
188- signal_set & signals ();
179+ [[nodiscard]] vix::async::net::detail::asio_net_service & net ();
189180
190181 /* *
191- * @brief Access the networking service .
182+ * @brief Stop scheduler and destroy all services .
192183 *
193- * Lazily constructs the internal Asio-backed networking service on
194- * first call. The type is intentionally kept in a detail namespace.
184+ * This function:
185+ * - stops the scheduler
186+ * - destroys all lazily created services
195187 *
196- * @return Reference to the asio_net_service .
188+ * It is safe to call multiple times .
197189 */
198- vix::async::net::detail::asio_net_service &net ();
199-
200- /* * @} */
190+ void shutdown () noexcept ;
201191
202192 private:
203- /* *
204- * @brief Primary scheduler driving task execution and coroutine resumption.
205- */
193+ /* * @brief Core scheduler. */
206194 scheduler sched_;
207195
208- /* *
209- * @brief Lazily-created CPU pool.
210- */
196+ /* * @brief CPU thread pool (lazy). */
211197 std::unique_ptr<thread_pool> cpu_pool_;
212198
213- /* *
214- * @brief Lazily-created timers service.
215- */
199+ /* * @brief Timer service (lazy). */
216200 std::unique_ptr<timer> timer_;
217201
218- /* *
219- * @brief Lazily-created signals service.
220- */
202+ /* * @brief Signal handling service (lazy). */
221203 std::unique_ptr<signal_set> signals_;
222204
223- /* *
224- * @brief Lazily-created networking service.
225- */
205+ /* * @brief Networking backend (lazy). */
226206 std::unique_ptr<vix::async::net::detail::asio_net_service> net_;
207+
208+ /* * @brief Ensures shutdown runs once. */
209+ std::atomic<bool > shutdown_done_{false };
210+
211+ /* * @brief Protects shutdown sequence. */
212+ std::mutex shutdown_mutex_;
227213 };
228214
229215} // namespace vix::async::core
0 commit comments