Line data Source code
1 : //
2 : // Copyright (c) 2026 Steve Gerbino
3 : //
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)
6 : //
7 : // Official repository: https://github.com/cppalliance/corosio
8 : //
9 :
10 : #ifndef BOOST_COROSIO_DETAIL_POSIX_RESOLVER_SERVICE_HPP
11 : #define BOOST_COROSIO_DETAIL_POSIX_RESOLVER_SERVICE_HPP
12 :
13 : #include <boost/corosio/detail/platform.hpp>
14 :
15 : #if BOOST_COROSIO_POSIX
16 :
17 : #include <boost/corosio/detail/config.hpp>
18 : #include <boost/corosio/resolver.hpp>
19 : #include <boost/capy/ex/execution_context.hpp>
20 :
21 : /*
22 : POSIX Resolver Service
23 : ======================
24 :
25 : POSIX getaddrinfo() is a blocking call that cannot be monitored with
26 : epoll/kqueue/io_uring. We use a worker thread approach: each resolution
27 : spawns a dedicated thread that runs the blocking call and posts completion
28 : back to the scheduler.
29 :
30 : This follows the timer_service pattern:
31 : - posix_resolver_service is an abstract base class (no scheduler dependency)
32 : - posix_resolver_service_impl is the concrete implementation
33 : - get_resolver_service(ctx, sched) creates the service with scheduler ref
34 :
35 : Thread-per-resolution Design
36 : ----------------------------
37 : Simple, no thread pool complexity. DNS lookups are infrequent enough that
38 : thread creation overhead is acceptable. Detached threads self-manage;
39 : shared_ptr capture keeps impl alive until completion.
40 :
41 : Cancellation
42 : ------------
43 : getaddrinfo() cannot be interrupted mid-call. We use an atomic flag to
44 : indicate cancellation was requested. The worker thread checks this flag
45 : after getaddrinfo() returns and reports the appropriate error.
46 : */
47 :
48 : namespace boost::corosio::detail {
49 :
50 : struct scheduler;
51 :
52 : //------------------------------------------------------------------------------
53 :
54 : /** Abstract resolver service for POSIX backends.
55 :
56 : This is the base class that defines the interface. The concrete
57 : implementation (posix_resolver_service_impl) is created via
58 : get_resolver_service() which passes the scheduler reference.
59 : */
60 : class posix_resolver_service : public capy::execution_context::service
61 : {
62 : public:
63 : /** Create a new resolver implementation. */
64 : virtual resolver::resolver_impl& create_impl() = 0;
65 :
66 : protected:
67 309 : posix_resolver_service() = default;
68 : };
69 :
70 : //------------------------------------------------------------------------------
71 :
72 : /** Get or create the resolver service for the given context.
73 :
74 : This function is called by the concrete scheduler during initialization
75 : to create the resolver service with a reference to itself.
76 :
77 : @param ctx Reference to the owning execution_context.
78 : @param sched Reference to the scheduler for posting completions.
79 : @return Reference to the resolver service.
80 : */
81 : posix_resolver_service&
82 : get_resolver_service(capy::execution_context& ctx, scheduler& sched);
83 :
84 : } // namespace boost::corosio::detail
85 :
86 : #endif // BOOST_COROSIO_POSIX
87 :
88 : #endif // BOOST_COROSIO_DETAIL_POSIX_RESOLVER_SERVICE_HPP
|